Update cmd flags to support static mpd with live profile

- Deprecated command line flags --profile and --single_segment.
  'segment_template' in stream descriptors implies live profile
  and non-single segment.
- Added flag --generate_static_mpd_for_live_profile to generate
  static mpd for live profile; if not set, dynamic mpd will be
  generated.

Close #142

Change-Id: I78879297ed118f0f246c4753a16ad125bd6b5e4f
This commit is contained in:
Kongqun Yang 2017-01-06 18:40:37 -08:00 committed by KongQun Yang
parent 5aaae303e8
commit 80c54a533a
24 changed files with 137 additions and 134 deletions

View File

@ -145,7 +145,7 @@ host operating systems.
# VOD: mp4 --> dash
packager input=/media/example.mp4,stream=audio,output=audio.mp4 \
input=/media/example.mp4,stream=video,output=video.mp4 \
--profile on-demand --mpd_output example.mpd
--mpd_output example.mpd
# Leave the container.
exit
@ -231,13 +231,11 @@ Demux audio from the input and generate a fragmented mp4:
packager input=sintel.mp4,stream=audio,output=fragmented_sintel.mp4
```
Demux streams from the input and generates a mpd with on-demand profile along
with fragmented mp4:
Demux streams from the input and generates a mpd with fragmented mp4:
```Shell
packager \
input=sintel.mp4,stream=audio,output=sintel_audio.mp4 \
input=sintel.mp4,stream=video,output=sintel_video.mp4 \
--profile on-demand \
--mpd_output sintel_vod.mpd
```
@ -247,19 +245,17 @@ packager \
input=sintel.mp4,stream=audio,output=sintel_audio.mp4 \
input=sintel.mp4,stream=video,output=sintel_video.mp4 \
input=sintel_english_input.vtt,stream=text,output=sintel_english.vtt \
--profile on-demand \
--mpd_output sintel_vod.mpd
```
You may also generate mpd with live profile. Here is an example with IPTV input
streams:
You may also generate mpd with live profile by specifying segment_template in
stream descriptors. Here is an example with IPTV input streams:
```Shell
packager \
'input=udp://224.1.1.5:5003,stream=audio,init_segment=live-audio.mp4,segment_template=live-audio-$Number$.mp4,bandwidth=130000' \
'input=udp://224.1.1.5:5003,stream=video,init_segment=live-video-sd.mp4,segment_template=live-video-sd-$Number$.mp4,bandwidth=2000000' \
'input=udp://224.1.1.5:5002,stream=video,init_segment=live-video-hd.mp4,segment_template=live-video-hd-$Number$.mp4,bandwidth=5000000' \
--profile live \
--mpd_output live.mpd
```
@ -274,6 +270,16 @@ Three options are supported right now:
- timeout=microseconds
Timeout in microseconds. Default to unlimited.
To generate static mpd with live profile. An additional flag needs to be
specified:
```Shell
packager \
'input=sintel.mp4,stream=audio,init_segment=audio.mp4,segment_template=audio-$Number$.mp4' \
'input=sintel.mp4,stream=video,init_segment=video.mp4,segment_template=video-$Number$.mp4' \
--mpd_output live_static.mpd \
--generate_static_mpd
```
Demux video from the input and generate an encrypted fragmented mp4 using
Widevine encryption with RSA signing key file *widevine_test_private.der*:
```Shell
@ -292,7 +298,6 @@ packager \
'input=udp://224.1.1.5:5003,stream=audio,init_segment=live-audio.mp4,segment_template=live-audio-$Number$.mp4,bandwidth=130000' \
'input=udp://224.1.1.5:5003,stream=video,init_segment=live-video-sd.mp4,segment_template=live-video-sd-$Number$.mp4,bandwidth=2000000' \
'input=udp://224.1.1.5:5002,stream=video,init_segment=live-video-hd.mp4,segment_template=live-video-hd-$Number$.mp4,bandwidth=5000000' \
--profile live \
--mpd_output live.mpd \
--enable_widevine_encryption \
--key_server_url "https://license.uat.widevine.com/cenc/getcontentkey/widevine_test" \
@ -343,7 +348,6 @@ generated TS segments.
```Shell
packager \
'input=bear-1280x720.mp4,stream=video,segment_template=bear$Number$.ts,playlist_name=playlist.m3u8' \
--single_segment=false \
--hls_master_playlist_output="master.m3u8" \
--hls_base_url="http://localhost:10000/"
```
@ -354,7 +358,6 @@ specified.
packager \
'input=input.mp4,stream=video,segment_template=output$Number$.ts,playlist_name=video_playlist.m3u8' \
'input=input.mp4,stream=audio,segment_template=output_audio$Number$.ts,playlist_name=audio_playlist.m3u8,hls_group_id=audio,hls_name=ENGLISH' \
--single_segment=false \
--hls_master_playlist_output="master_playlist.m3u8" \
--hls_base_url="http://localhost:10000/"
```

View File

@ -8,6 +8,14 @@
#include "packager/app/mpd_flags.h"
DEFINE_bool(generate_static_mpd,
false,
"Set to true to generate static mpd. If segment_template is "
"specified in stream descriptors, shaka-packager generates dynamic "
"mpd by default; if this flag is enabled, shaka-packager generates "
"static mpd instead. Note that if segment_template is not "
"specified, shaka-packager always generates static mpd regardless "
"of the value of this flag.");
// TODO(rkuroiwa, kqyang): Remove the 'Exclusive' statements once
// --output_media_info can work together with --mpd_output.
DEFINE_bool(output_media_info,

View File

@ -11,6 +11,7 @@
#include <gflags/gflags.h>
DECLARE_bool(generate_static_mpd);
DECLARE_bool(output_media_info);
DECLARE_string(mpd_output);
DECLARE_string(base_urls);

View File

@ -8,18 +8,9 @@
#include "packager/app/muxer_flags.h"
DEFINE_string(profile,
"",
"Specify the target DASH profile: on-demand or live. This will "
"set proper option values to ensure conformance to the desired "
"profile.");
DEFINE_double(clear_lead,
10.0f,
"Clear lead in seconds if encryption is enabled.");
DEFINE_bool(single_segment,
true,
"Generate a single segment for the media presentation. This option "
"should be set for on demand profile.");
DEFINE_double(segment_duration,
10.0f,
"Segment duration in seconds. If single_segment is specified, "

View File

@ -11,9 +11,7 @@
#include <gflags/gflags.h>
DECLARE_string(profile);
DECLARE_double(clear_lead);
DECLARE_bool(single_segment);
DECLARE_double(segment_duration);
DECLARE_bool(segment_sap_aligned);
DECLARE_double(fragment_duration);

View File

@ -265,11 +265,6 @@ bool CreateRemuxJobs(const StreamDescriptorList& stream_descriptors,
return false;
}
stream_muxer_options.segment_template = stream_iter->segment_template;
if (stream_muxer_options.single_segment) {
LOG(WARNING) << "Segment template and single segment are incompatible, "
"setting single segment to false.";
stream_muxer_options.single_segment = false;
}
}
stream_muxer_options.bandwidth = stream_iter->bandwidth;
@ -419,20 +414,11 @@ bool RunPackager(const StreamDescriptorList& stream_descriptors) {
if (protection_scheme == FOURCC_NULL)
return false;
if (!AssignFlagsFromProfile())
return false;
if (FLAGS_output_media_info && !FLAGS_mpd_output.empty()) {
NOTIMPLEMENTED() << "ERROR: --output_media_info and --mpd_output do not "
"work together.";
return false;
}
if (FLAGS_output_media_info && !FLAGS_single_segment) {
// TODO(rkuroiwa, kqyang): Support partial media info dump for live.
NOTIMPLEMENTED() << "ERROR: --output_media_info is only supported if "
"--single_segment is true.";
return false;
}
// Since there isn't a muxer listener that can output both MPD and HLS,
// disallow specifying both MPD and HLS flags.
@ -446,8 +432,28 @@ bool RunPackager(const StreamDescriptorList& stream_descriptors) {
if (!GetMuxerOptions(&muxer_options))
return false;
DCHECK(!stream_descriptors.empty());
// On demand profile generates single file segment while live profile
// generates multiple segments specified using segment template.
const bool on_demand_dash_profile =
stream_descriptors.begin()->segment_template.empty();
for (const auto& stream_descriptor : stream_descriptors) {
if (on_demand_dash_profile != stream_descriptor.segment_template.empty()) {
LOG(ERROR) << "Inconsistent stream descriptor specification: "
"segment_template should be specified for none or all "
"stream descriptors.";
return false;
}
}
if (FLAGS_output_media_info && !on_demand_dash_profile) {
// TODO(rkuroiwa, kqyang): Support partial media info dump for live.
NOTIMPLEMENTED() << "ERROR: --output_media_info is only supported for "
"on-demand profile (not using segment_template).";
return false;
}
MpdOptions mpd_options;
if (!GetMpdOptions(&mpd_options))
if (!GetMpdOptions(on_demand_dash_profile, &mpd_options))
return false;
// Create encryption key source if needed.

View File

@ -125,30 +125,9 @@ std::unique_ptr<KeySource> CreateDecryptionKeySource() {
return decryption_key_source;
}
bool AssignFlagsFromProfile() {
bool single_segment = FLAGS_single_segment;
if (FLAGS_profile == "on-demand") {
single_segment = true;
} else if (FLAGS_profile == "live") {
single_segment = false;
} else if (FLAGS_profile != "") {
fprintf(stderr, "ERROR: --profile '%s' is not supported.\n",
FLAGS_profile.c_str());
return false;
}
if (FLAGS_single_segment != single_segment) {
FLAGS_single_segment = single_segment;
fprintf(stdout, "Profile %s: set --single_segment to %s.\n",
FLAGS_profile.c_str(), single_segment ? "true" : "false");
}
return true;
}
bool GetMuxerOptions(MuxerOptions* muxer_options) {
DCHECK(muxer_options);
muxer_options->single_segment = FLAGS_single_segment;
muxer_options->segment_duration = FLAGS_segment_duration;
muxer_options->fragment_duration = FLAGS_fragment_duration;
muxer_options->segment_sap_aligned = FLAGS_segment_sap_aligned;
@ -168,15 +147,15 @@ bool GetMuxerOptions(MuxerOptions* muxer_options) {
return true;
}
bool GetMpdOptions(MpdOptions* mpd_options) {
bool GetMpdOptions(bool on_demand_profile, MpdOptions* mpd_options) {
DCHECK(mpd_options);
mpd_options->dash_profile =
FLAGS_single_segment ? DashProfile::kOnDemand : DashProfile::kLive;
// Single segment does not always mean static mpd.
// TODO(kqyang): Add a new flag for mpd type and update the code.
on_demand_profile ? DashProfile::kOnDemand : DashProfile::kLive;
mpd_options->mpd_type =
FLAGS_single_segment ? MpdType::kStatic : MpdType::kDynamic;
(on_demand_profile || FLAGS_generate_static_mpd)
? MpdType::kStatic
: MpdType::kDynamic;
mpd_options->availability_time_offset = FLAGS_availability_time_offset;
mpd_options->minimum_update_period = FLAGS_minimum_update_period;
mpd_options->min_buffer_time = FLAGS_min_buffer_time;

View File

@ -42,14 +42,11 @@ std::unique_ptr<KeySource> CreateEncryptionKeySource();
/// decryption is not required.
std::unique_ptr<KeySource> CreateDecryptionKeySource();
/// Set flags according to profile.
bool AssignFlagsFromProfile();
/// Fill MuxerOptions members using provided command line options.
bool GetMuxerOptions(MuxerOptions* muxer_options);
/// Fill MpdOptions members using provided command line options.
bool GetMpdOptions(MpdOptions* mpd_options);
bool GetMpdOptions(bool on_demand_profile, MpdOptions* mpd_options);
/// Select and add a stream from a provided set to a muxer.
/// @param streams contains the set of MediaStreams from which to select.

View File

@ -0,0 +1,34 @@
// Copyright 2017 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
//
// Defines retired / deprecated flags. These flags will be removed in later
// versions.
#include "packager/app/retired_flags.h"
#include <stdio.h>
DEFINE_string(profile, "", "This flag is deprecated. Do not use.");
DEFINE_bool(single_segment, true, "This flag is deprecated. Do not use.");
// The current gflags library does not provide a way to check whether a flag is
// set in command line. If a flag has a different value to its default value,
// the flag must have been set. It is possible that the flag is set to the same
// value as its default value though.
bool InformRetiredStringFlag(const char* flagname, const std::string& value) {
if (!value.empty())
fprintf(stderr, "WARNING: %s is deprecated and ignored.\n", flagname);
return true;
}
bool InformRetiredDefaultTrueFlag(const char* flagname, bool value) {
if (!value)
fprintf(stderr, "WARNING: %s is deprecated and ignored.\n", flagname);
return true;
}
DEFINE_validator(profile, &InformRetiredStringFlag);
DEFINE_validator(single_segment, &InformRetiredDefaultTrueFlag);

View File

@ -0,0 +1,10 @@
// Copyright 2017 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
#include <gflags/gflags.h>
DECLARE_string(profile);
DECLARE_bool(single_segment);

View File

@ -110,7 +110,7 @@ class PackagerAppTest(unittest.TestCase):
output_format='ts',
live=True,
test_files=['bear-640x360.ts']),
self._GetFlags(live=True, output_hls=True))
self._GetFlags(output_hls=True))
self._DiffLiveGold(self.output[0],
'bear-640x360-a-golden',
output_format='ts')
@ -220,8 +220,7 @@ class PackagerAppTest(unittest.TestCase):
output_format='ts',
live=True,
test_files=['bear-640x360.ts']),
self._GetFlags(encryption=True,
live=True, output_hls=True))
self._GetFlags(encryption=True, output_hls=True))
self._DiffLiveGold(self.output[0],
'bear-640x360-a-enc-golden',
output_format='ts')
@ -329,8 +328,7 @@ class PackagerAppTest(unittest.TestCase):
def testPackageWithLiveProfile(self):
self.packager.Package(
self._GetStreams(['audio', 'video'], live=True),
self._GetFlags(live=True))
self._GetStreams(['audio', 'video'], live=True), self._GetFlags())
self._DiffLiveGold(self.output[0], 'bear-640x360-a-live-golden')
self._DiffLiveGold(self.output[1], 'bear-640x360-v-live-golden')
self._DiffLiveMpdGold(self.mpd_output, 'bear-640x360-av-live-golden.mpd')
@ -338,7 +336,7 @@ class PackagerAppTest(unittest.TestCase):
def testPackageWithLiveProfileAndEncryption(self):
self.packager.Package(
self._GetStreams(['audio', 'video'], live=True),
self._GetFlags(encryption=True, live=True))
self._GetFlags(encryption=True))
self._DiffLiveGold(self.output[0], 'bear-640x360-a-live-cenc-golden')
self._DiffLiveGold(self.output[1], 'bear-640x360-v-live-cenc-golden')
self._DiffLiveMpdGold(self.mpd_output,
@ -347,8 +345,7 @@ class PackagerAppTest(unittest.TestCase):
def testPackageWithLiveProfileAndEncryptionAndDashIfIop(self):
self.packager.Package(
self._GetStreams(['audio', 'video'], live=True),
self._GetFlags(encryption=True,
live=True, dash_if_iop=True))
self._GetFlags(encryption=True, dash_if_iop=True))
self._DiffLiveGold(self.output[0], 'bear-640x360-a-live-cenc-golden')
self._DiffLiveGold(self.output[1], 'bear-640x360-v-live-cenc-golden')
self._DiffLiveMpdGold(self.mpd_output,
@ -360,8 +357,7 @@ class PackagerAppTest(unittest.TestCase):
live=True,
test_files=['bear-1280x720.mp4', 'bear-640x360.mp4',
'bear-320x180.mp4']),
self._GetFlags(encryption=True,
live=True, dash_if_iop=True))
self._GetFlags(encryption=True, dash_if_iop=True))
self._DiffLiveGold(self.output[2], 'bear-640x360-a-live-cenc-golden')
self._DiffLiveGold(self.output[3], 'bear-640x360-v-live-cenc-golden')
# Mpd cannot be validated right now since we don't generate determinstic
@ -371,9 +367,7 @@ class PackagerAppTest(unittest.TestCase):
def testPackageWithLiveProfileAndKeyRotation(self):
self.packager.Package(
self._GetStreams(['audio', 'video'], live=True),
self._GetFlags(encryption=True,
key_rotation=True,
live=True))
self._GetFlags(encryption=True, key_rotation=True))
self._DiffLiveGold(self.output[0],
'bear-640x360-a-live-cenc-rotation-golden')
self._DiffLiveGold(self.output[1],
@ -386,7 +380,6 @@ class PackagerAppTest(unittest.TestCase):
self._GetStreams(['audio', 'video'], live=True),
self._GetFlags(encryption=True,
key_rotation=True,
live=True,
dash_if_iop=True))
self._DiffLiveGold(self.output[0],
'bear-640x360-a-live-cenc-rotation-golden')
@ -496,7 +489,6 @@ class PackagerAppTest(unittest.TestCase):
random_iv=False,
widevine_encryption=False,
key_rotation=False,
live=False,
dash_if_iop=False,
output_media_info=False,
output_hls=False,
@ -526,8 +518,6 @@ class PackagerAppTest(unittest.TestCase):
if key_rotation:
flags.append('--crypto_period_duration=1')
if live:
flags.append('--profile=live')
if dash_if_iop:
flags.append('--generate_dash_if_iop_compliant_mpd')
if output_media_info:

View File

@ -9,17 +9,8 @@
namespace shaka {
namespace media {
MuxerOptions::MuxerOptions()
: single_segment(false),
segment_duration(0),
fragment_duration(0),
segment_sap_aligned(false),
fragment_sap_aligned(false),
num_subsegments_per_sidx(0),
mp4_use_decoding_timestamp_in_timeline(false),
bandwidth(0),
webm_subsample_encryption(true) {}
MuxerOptions::~MuxerOptions() {}
MuxerOptions::MuxerOptions() = default;
MuxerOptions::~MuxerOptions() = default;
} // namespace media
} // namespace shaka

View File

@ -19,42 +19,38 @@ struct MuxerOptions {
MuxerOptions();
~MuxerOptions();
/// Generate a single segment for each media presentation. This option
/// should be set for on demand profile.
bool single_segment;
/// Segment duration in seconds. If single_segment is specified, this
/// parameter sets the duration of a subsegment; otherwise, this parameter
/// sets the duration of a segment. A segment can contain one or many
/// fragments.
double segment_duration;
double segment_duration = 0;
/// Fragment duration in seconds. Should not be larger than the segment
/// duration.
double fragment_duration;
double fragment_duration = 0;
/// Force segments to begin with stream access points. Segment duration may
/// not be exactly what specified by segment_duration.
bool segment_sap_aligned;
bool segment_sap_aligned = false;
/// Force fragments to begin with stream access points. Fragment duration
/// may not be exactly what specified by segment_duration. Setting to true
/// implies that segment_sap_aligned is true as well.
bool fragment_sap_aligned;
bool fragment_sap_aligned = false;
/// For ISO BMFF only.
/// Set the number of subsegments in each SIDX box. If 0, a single SIDX box
/// is used per segment. If -1, no SIDX box is used. Otherwise, the Muxer
/// will pack N subsegments in the root SIDX of the segment, with
/// segment_duration/N/fragment_duration fragments per subsegment.
int num_subsegments_per_sidx;
int num_subsegments_per_sidx = 0;
/// For ISO BMFF only.
/// Set the flag use_decoding_timestamp_in_timeline, which if set to true, use
/// decoding timestamp instead of presentation timestamp in media timeline,
/// which is needed to workaround a Chromium bug that decoding timestamp is
/// used in buffered range, https://crbug.com/398130.
bool mp4_use_decoding_timestamp_in_timeline;
bool mp4_use_decoding_timestamp_in_timeline = false;
/// Output file name. If segment_template is not specified, the Muxer
/// generates this single output file with all segments concatenated;
@ -72,10 +68,10 @@ struct MuxerOptions {
/// User-specified bit rate for the media stream. If zero, the muxer will
/// attempt to estimate.
uint32_t bandwidth;
uint32_t bandwidth = 0;
// Enable/disable subsample encryption for WebM containers.
bool webm_subsample_encryption;
bool webm_subsample_encryption = true;
};
} // namespace media

View File

@ -44,7 +44,6 @@ MediaInfo ConvertToMediaInfo(const std::string& media_info_string) {
}
void SetDefaultLiveMuxerOptionsValues(media::MuxerOptions* muxer_options) {
muxer_options->single_segment = false;
muxer_options->segment_duration = 10.0;
muxer_options->fragment_duration = 10.0;
muxer_options->segment_sap_aligned = true;

View File

@ -149,9 +149,8 @@ void SetMediaInfoStreamInfo(const StreamInfo& stream_info,
void SetMediaInfoMuxerOptions(const MuxerOptions& muxer_options,
MediaInfo* media_info) {
DCHECK(media_info);
if (muxer_options.single_segment) {
if (muxer_options.segment_template.empty()) {
media_info->set_media_file_name(muxer_options.output_file_name);
DCHECK(muxer_options.segment_template.empty());
} else {
media_info->set_init_segment_name(muxer_options.output_file_name);
media_info->set_segment_template(muxer_options.segment_template);

View File

@ -73,7 +73,6 @@ OnMediaEndParameters GetDefaultOnMediaEndParams() {
}
void SetDefaultMuxerOptionsValues(MuxerOptions* muxer_options) {
muxer_options->single_segment = true;
muxer_options->segment_duration = 10.0;
muxer_options->fragment_duration = 10.0;
muxer_options->segment_sap_aligned = true;

View File

@ -45,7 +45,7 @@ void VodMediaInfoDumpMuxerListener::OnMediaStart(
const StreamInfo& stream_info,
uint32_t time_scale,
ContainerType container_type) {
DCHECK(muxer_options.single_segment);
DCHECK(muxer_options.segment_template.empty());
media_info_.reset(new MediaInfo());
if (!internal::GenerateMediaInfo(muxer_options,
stream_info,

View File

@ -134,7 +134,7 @@ Status MP4Muxer::Initialize() {
}
}
if (options().single_segment) {
if (options().segment_template.empty()) {
segmenter_.reset(new SingleSegmentSegmenter(options(), std::move(ftyp),
std::move(moov)));
} else {

View File

@ -6,6 +6,7 @@
#include <gtest/gtest.h>
#include <memory>
#include "packager/media/base/muxer_util.h"
#include "packager/media/formats/webm/segmenter_test_base.h"
namespace shaka {
@ -27,12 +28,10 @@ const uint8_t kBasicSupportDataInit[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
// ID: Info, Payload Size: 88
0x15, 0x49, 0xa9, 0x66, 0xd8,
// ID: Info, Payload Size: 81
0x15, 0x49, 0xa9, 0x66, 0xd1,
// TimecodeScale: 1000000
0x2a, 0xd7, 0xb1, 0x83, 0x0f, 0x42, 0x40,
// Duration: float(0)
0x44, 0x89, 0x84, 0x3f, 0x80, 0x00, 0x00,
// MuxingApp: 'libwebm-0.2.1.0'
0x4d, 0x80, 0x8f, 0x6c, 0x69, 0x62, 0x77, 0x65, 0x62, 0x6d, 0x2d, 0x30,
0x2e, 0x32, 0x2e, 0x31, 0x2e, 0x30,
@ -93,7 +92,10 @@ const uint8_t kBasicSupportDataSegment[] = {
class MultiSegmentSegmenterTest : public SegmentTestBase {
public:
MultiSegmentSegmenterTest() : info_(CreateVideoStreamInfo()) {}
MultiSegmentSegmenterTest()
: info_(CreateVideoStreamInfo()),
segment_template_(std::string(kMemoryFilePrefix) +
"output-template-$Number$.webm") {}
protected:
void InitializeSegmenter(const MuxerOptions& options) {
@ -102,12 +104,18 @@ class MultiSegmentSegmenterTest : public SegmentTestBase {
options, info_.get(), NULL, &segmenter_));
}
std::string TemplateFileName(int number) const {
return GetSegmentName(segment_template_, 0, number, 0);
}
scoped_refptr<StreamInfo> info_;
std::string segment_template_;
std::unique_ptr<webm::Segmenter> segmenter_;
};
TEST_F(MultiSegmentSegmenterTest, BasicSupport) {
MuxerOptions options = CreateMuxerOptions();
options.segment_template = segment_template_;
ASSERT_NO_FATAL_FAILURE(InitializeSegmenter(options));
// Write the samples to the Segmenter.
@ -128,6 +136,7 @@ TEST_F(MultiSegmentSegmenterTest, BasicSupport) {
TEST_F(MultiSegmentSegmenterTest, SplitsFilesOnSegmentDuration) {
MuxerOptions options = CreateMuxerOptions();
options.segment_template = segment_template_;
options.segment_duration = 5; // seconds
ASSERT_NO_FATAL_FAILURE(InitializeSegmenter(options));
@ -154,6 +163,7 @@ TEST_F(MultiSegmentSegmenterTest, SplitsFilesOnSegmentDuration) {
TEST_F(MultiSegmentSegmenterTest, RespectsSegmentSAPAlign) {
MuxerOptions options = CreateMuxerOptions();
options.segment_template = segment_template_;
options.segment_duration = 3; // seconds
options.segment_sap_aligned = true;
ASSERT_NO_FATAL_FAILURE(InitializeSegmenter(options));
@ -182,6 +192,7 @@ TEST_F(MultiSegmentSegmenterTest, RespectsSegmentSAPAlign) {
TEST_F(MultiSegmentSegmenterTest, SplitsClustersOnFragmentDuration) {
MuxerOptions options = CreateMuxerOptions();
options.segment_template = segment_template_;
options.fragment_duration = 5; // seconds
ASSERT_NO_FATAL_FAILURE(InitializeSegmenter(options));
@ -205,6 +216,7 @@ TEST_F(MultiSegmentSegmenterTest, SplitsClustersOnFragmentDuration) {
TEST_F(MultiSegmentSegmenterTest, RespectsFragmentSAPAlign) {
MuxerOptions options = CreateMuxerOptions();
options.segment_template = segment_template_;
options.fragment_duration = 3; // seconds
options.fragment_sap_aligned = true;
ASSERT_NO_FATAL_FAILURE(InitializeSegmenter(options));
@ -230,4 +242,3 @@ TEST_F(MultiSegmentSegmenterTest, RespectsFragmentSAPAlign) {
} // namespace media
} // namespace shaka

View File

@ -74,7 +74,7 @@ Status Segmenter::Initialize(std::unique_ptr<MkvWriter> writer,
(GetPackagerProjectUrl() + " version " + version).c_str());
}
if (options().single_segment) {
if (options().segment_template.empty()) {
// Set an initial duration so the duration element is written; will be
// overwritten at the end. This works because this is a float and floats
// are always the same size.

View File

@ -6,7 +6,6 @@
#include "packager/media/formats/webm/segmenter_test_base.h"
#include "packager/media/base/muxer_util.h"
#include "packager/media/file/memory_file.h"
#include "packager/media/formats/webm/webm_constants.h"
#include "packager/version/version.h"
@ -43,10 +42,7 @@ void SegmentTestBase::SetUp() {
SetPackagerVersionForTesting("test");
output_file_name_ = std::string(kMemoryFilePrefix) + "output-file.webm";
segment_template_ =
std::string(kMemoryFilePrefix) + "output-template-$Number$.webm";
cur_time_timescale_ = 0;
single_segment_ = true;
}
void SegmentTestBase::TearDown() {
@ -78,9 +74,7 @@ scoped_refptr<MediaSample> SegmentTestBase::CreateSample(
MuxerOptions SegmentTestBase::CreateMuxerOptions() const {
MuxerOptions ret;
ret.single_segment = single_segment_;
ret.output_file_name = output_file_name_;
ret.segment_template = segment_template_;
ret.segment_duration = 30; // seconds
ret.fragment_duration = 30; // seconds
ret.segment_sap_aligned = false;
@ -102,10 +96,6 @@ std::string SegmentTestBase::OutputFileName() const {
return output_file_name_;
}
std::string SegmentTestBase::TemplateFileName(int number) const {
return GetSegmentName(segment_template_, 0, number, 0);
}
SegmentTestBase::ClusterParser::ClusterParser() : in_cluster_(false) {}
SegmentTestBase::ClusterParser::~ClusterParser() {}

View File

@ -43,7 +43,7 @@ Status WebMMuxer::Initialize() {
if (!status.ok())
return status;
if (!options().single_segment) {
if (!options().segment_template.empty()) {
segmenter_.reset(new MultiSegmentSegmenter(options()));
} else {
segmenter_.reset(new TwoPassSingleSegmentSegmenter(options()));

View File

@ -140,8 +140,6 @@ bool PackagerTestBasic::ContentsEqual(const std::string& file1,
MuxerOptions PackagerTestBasic::SetupOptions(const std::string& output,
bool single_segment) {
MuxerOptions options;
options.single_segment = single_segment;
options.segment_duration = kSegmentDurationInSeconds;
options.fragment_duration = kFragmentDurationInSecodns;
options.segment_sap_aligned = kSegmentSapAligned;
@ -149,7 +147,8 @@ MuxerOptions PackagerTestBasic::SetupOptions(const std::string& output,
options.num_subsegments_per_sidx = kNumSubsegmentsPerSidx;
options.output_file_name = GetFullPath(output);
options.segment_template = GetFullPath(kSegmentTemplate);
if (!single_segment)
options.segment_template = GetFullPath(kSegmentTemplate);
options.temp_dir = test_directory_.AsUTF8Unsafe();
return options;
}

View File

@ -26,6 +26,8 @@
'app/packager_main.cc',
'app/packager_util.cc',
'app/packager_util.h',
'app/retired_flags.cc',
'app/retired_flags.h',
'app/stream_descriptor.cc',
'app/stream_descriptor.h',
'app/validate_flag.cc',