Consolidate Mp4OutputParams into MuxerOptions

Change-Id: I533e40ef9eb84453c15cbdb7ef42fc85bef5125d
This commit is contained in:
KongQun Yang 2017-08-18 11:57:34 -07:00
parent 9eaf1dcae0
commit 4e82ab13bd
13 changed files with 67 additions and 84 deletions

View File

@ -171,17 +171,6 @@ std::unique_ptr<KeySource> CreateDecryptionKeySource(
return decryption_key_source; return decryption_key_source;
} }
MuxerOptions GetMuxerOptions(const std::string& temp_dir,
const Mp4OutputParams& mp4_params) {
MuxerOptions muxer_options;
muxer_options.num_subsegments_per_sidx = mp4_params.num_subsegments_per_sidx;
muxer_options.mp4_include_pssh_in_stream = mp4_params.include_pssh_in_stream;
muxer_options.mp4_use_decoding_timestamp_in_timeline =
mp4_params.use_decoding_timestamp_in_timeline;
muxer_options.temp_dir = temp_dir;
return muxer_options;
}
MpdOptions GetMpdOptions(bool on_demand_profile, const MpdParams& mpd_params) { MpdOptions GetMpdOptions(bool on_demand_profile, const MpdParams& mpd_params) {
MpdOptions mpd_options; MpdOptions mpd_options;
mpd_options.dash_profile = mpd_options.dash_profile =

View File

@ -50,10 +50,6 @@ std::unique_ptr<KeySource> CreateEncryptionKeySource(
std::unique_ptr<KeySource> CreateDecryptionKeySource( std::unique_ptr<KeySource> CreateDecryptionKeySource(
const DecryptionParams& decryption_params); const DecryptionParams& decryption_params);
/// @return MuxerOptions from provided command line options.
MuxerOptions GetMuxerOptions(const std::string& temp_dir,
const Mp4OutputParams& mp4_params);
/// @return MpdOptions from provided command line options. /// @return MpdOptions from provided command line options.
MpdOptions GetMpdOptions(bool on_demand_profile, const MpdParams& mpd_params); MpdOptions GetMpdOptions(bool on_demand_profile, const MpdParams& mpd_params);

View File

@ -11,6 +11,8 @@
#include <string> #include <string>
#include "packager/media/public/mp4_output_params.h"
namespace shaka { namespace shaka {
namespace media { namespace media {
@ -19,19 +21,8 @@ struct MuxerOptions {
MuxerOptions(); MuxerOptions();
~MuxerOptions(); ~MuxerOptions();
/// For ISO BMFF only. /// MP4 (ISO-BMFF) specific parameters.
/// Set the number of subsegments in each SIDX box. If 0, a single SIDX box Mp4OutputParams mp4_params;
/// 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 = 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 = false;
/// Output file name. If segment_template is not specified, the Muxer /// Output file name. If segment_template is not specified, the Muxer
/// generates this single output file with all segments concatenated; /// generates this single output file with all segments concatenated;
@ -50,12 +41,6 @@ struct MuxerOptions {
/// User-specified bit rate for the media stream. If zero, the muxer will /// User-specified bit rate for the media stream. If zero, the muxer will
/// attempt to estimate. /// attempt to estimate.
uint32_t bandwidth = 0; uint32_t bandwidth = 0;
// MP4 only: include pssh in the encrypted stream. CMAF recommends carrying
// license acquisition information in the manifest and not duplicate the
// information in the stream. (This is not a hard requirement so we are still
// CMAF compatible even if pssh is included in the stream.)
bool mp4_include_pssh_in_stream = true;
}; };
} // namespace media } // namespace media

View File

@ -43,8 +43,8 @@ MediaInfo ConvertToMediaInfo(const std::string& media_info_string) {
return media_info; return media_info;
} }
void SetDefaultLiveMuxerOptionsValues(media::MuxerOptions* muxer_options) { void SetDefaultLiveMuxerOptions(media::MuxerOptions* muxer_options) {
muxer_options->num_subsegments_per_sidx = 0; muxer_options->mp4_params.num_subsegments_per_sidx = 0;
muxer_options->output_file_name = "liveinit.mp4"; muxer_options->output_file_name = "liveinit.mp4";
muxer_options->segment_template = "live-$NUMBER$.mp4"; muxer_options->segment_template = "live-$NUMBER$.mp4";
muxer_options->temp_dir.clear(); muxer_options->temp_dir.clear();
@ -98,7 +98,7 @@ MATCHER_P(ExpectMediaInfoEq, expected_text_format, "") {
TEST_F(MpdNotifyMuxerListenerTest, VodClearContent) { TEST_F(MpdNotifyMuxerListenerTest, VodClearContent) {
SetupForVod(); SetupForVod();
MuxerOptions muxer_options; MuxerOptions muxer_options;
SetDefaultMuxerOptionsValues(&muxer_options); SetDefaultMuxerOptions(&muxer_options);
VideoStreamInfoParameters video_params = GetDefaultVideoStreamInfoParams(); VideoStreamInfoParameters video_params = GetDefaultVideoStreamInfoParams();
std::shared_ptr<StreamInfo> video_stream_info = std::shared_ptr<StreamInfo> video_stream_info =
CreateVideoStreamInfo(video_params); CreateVideoStreamInfo(video_params);
@ -143,7 +143,7 @@ MATCHER_P4(ProtectedContentEq, uuid, name, default_key_id, pssh, "") {
TEST_F(MpdNotifyMuxerListenerTest, VodEncryptedContent) { TEST_F(MpdNotifyMuxerListenerTest, VodEncryptedContent) {
SetupForVod(); SetupForVod();
MuxerOptions muxer_options; MuxerOptions muxer_options;
SetDefaultMuxerOptionsValues(&muxer_options); SetDefaultMuxerOptions(&muxer_options);
VideoStreamInfoParameters video_params = GetDefaultVideoStreamInfoParams(); VideoStreamInfoParameters video_params = GetDefaultVideoStreamInfoParams();
std::shared_ptr<StreamInfo> video_stream_info = std::shared_ptr<StreamInfo> video_stream_info =
CreateVideoStreamInfo(video_params); CreateVideoStreamInfo(video_params);
@ -186,7 +186,7 @@ TEST_F(MpdNotifyMuxerListenerTest, VodEncryptedContent) {
TEST_F(MpdNotifyMuxerListenerTest, VodOnSampleDurationReady) { TEST_F(MpdNotifyMuxerListenerTest, VodOnSampleDurationReady) {
SetupForVod(); SetupForVod();
MuxerOptions muxer_options; MuxerOptions muxer_options;
SetDefaultMuxerOptionsValues(&muxer_options); SetDefaultMuxerOptions(&muxer_options);
VideoStreamInfoParameters video_params = GetDefaultVideoStreamInfoParams(); VideoStreamInfoParameters video_params = GetDefaultVideoStreamInfoParams();
std::shared_ptr<StreamInfo> video_stream_info = std::shared_ptr<StreamInfo> video_stream_info =
CreateVideoStreamInfo(video_params); CreateVideoStreamInfo(video_params);
@ -233,7 +233,7 @@ TEST_F(MpdNotifyMuxerListenerTest, VodOnSampleDurationReady) {
TEST_F(MpdNotifyMuxerListenerTest, VodOnNewSegment) { TEST_F(MpdNotifyMuxerListenerTest, VodOnNewSegment) {
SetupForVod(); SetupForVod();
MuxerOptions muxer_options; MuxerOptions muxer_options;
SetDefaultMuxerOptionsValues(&muxer_options); SetDefaultMuxerOptions(&muxer_options);
VideoStreamInfoParameters video_params = GetDefaultVideoStreamInfoParams(); VideoStreamInfoParameters video_params = GetDefaultVideoStreamInfoParams();
std::shared_ptr<StreamInfo> video_stream_info = std::shared_ptr<StreamInfo> video_stream_info =
CreateVideoStreamInfo(video_params); CreateVideoStreamInfo(video_params);
@ -270,7 +270,7 @@ TEST_F(MpdNotifyMuxerListenerTest, VodOnNewSegment) {
TEST_P(MpdNotifyMuxerListenerTest, LiveNoKeyRotation) { TEST_P(MpdNotifyMuxerListenerTest, LiveNoKeyRotation) {
SetupForLive(); SetupForLive();
MuxerOptions muxer_options; MuxerOptions muxer_options;
SetDefaultLiveMuxerOptionsValues(&muxer_options); SetDefaultLiveMuxerOptions(&muxer_options);
VideoStreamInfoParameters video_params = GetDefaultVideoStreamInfoParams(); VideoStreamInfoParameters video_params = GetDefaultVideoStreamInfoParams();
std::shared_ptr<StreamInfo> video_stream_info = std::shared_ptr<StreamInfo> video_stream_info =
CreateVideoStreamInfo(video_params); CreateVideoStreamInfo(video_params);
@ -343,7 +343,7 @@ TEST_P(MpdNotifyMuxerListenerTest, LiveNoKeyRotation) {
TEST_P(MpdNotifyMuxerListenerTest, LiveWithKeyRotation) { TEST_P(MpdNotifyMuxerListenerTest, LiveWithKeyRotation) {
SetupForLive(); SetupForLive();
MuxerOptions muxer_options; MuxerOptions muxer_options;
SetDefaultLiveMuxerOptionsValues(&muxer_options); SetDefaultLiveMuxerOptions(&muxer_options);
VideoStreamInfoParameters video_params = GetDefaultVideoStreamInfoParams(); VideoStreamInfoParameters video_params = GetDefaultVideoStreamInfoParams();
std::shared_ptr<StreamInfo> video_stream_info = std::shared_ptr<StreamInfo> video_stream_info =
CreateVideoStreamInfo(video_params); CreateVideoStreamInfo(video_params);

View File

@ -86,8 +86,8 @@ OnMediaEndParameters GetDefaultOnMediaEndParams() {
return param; return param;
} }
void SetDefaultMuxerOptionsValues(MuxerOptions* muxer_options) { void SetDefaultMuxerOptions(MuxerOptions* muxer_options) {
muxer_options->num_subsegments_per_sidx = 0; muxer_options->mp4_params.num_subsegments_per_sidx = 0;
muxer_options->output_file_name = "test_output_file_name.mp4"; muxer_options->output_file_name = "test_output_file_name.mp4";
muxer_options->segment_template.clear(); muxer_options->segment_template.clear();
muxer_options->temp_dir.clear(); muxer_options->temp_dir.clear();

View File

@ -92,7 +92,7 @@ OnMediaEndParameters GetDefaultOnMediaEndParams();
std::vector<ProtectionSystemSpecificInfo> GetDefaultKeySystemInfo(); std::vector<ProtectionSystemSpecificInfo> GetDefaultKeySystemInfo();
// Sets "default" values for muxer_options for testing. // Sets "default" values for muxer_options for testing.
void SetDefaultMuxerOptionsValues(MuxerOptions* muxer_options); void SetDefaultMuxerOptions(MuxerOptions* muxer_options);
// Expect that expect and actual are equal. // Expect that expect and actual are equal.
void ExpectMediaInfoEqual(const MediaInfo& expect, const MediaInfo& actual); void ExpectMediaInfoEqual(const MediaInfo& expect, const MediaInfo& actual);

View File

@ -77,7 +77,7 @@ class VodMediaInfoDumpMuxerListenerTest : public ::testing::Test {
const StreamInfo& stream_info, const StreamInfo& stream_info,
bool enable_encryption) { bool enable_encryption) {
MuxerOptions muxer_options; MuxerOptions muxer_options;
SetDefaultMuxerOptionsValues(&muxer_options); SetDefaultMuxerOptions(&muxer_options);
const uint32_t kReferenceTimeScale = 1000; const uint32_t kReferenceTimeScale = 1000;
if (enable_encryption) { if (enable_encryption) {
std::vector<uint8_t> bogus_default_key_id( std::vector<uint8_t> bogus_default_key_id(

View File

@ -171,7 +171,8 @@ Status MP4Muxer::InitializeMuxer() {
<< streams()[i]->stream_type(); << streams()[i]->stream_type();
} }
if (streams()[i]->is_encrypted() && options().mp4_include_pssh_in_stream) { if (streams()[i]->is_encrypted() &&
options().mp4_params.include_pssh_in_stream) {
const auto& key_system_info = const auto& key_system_info =
streams()[i]->encryption_config().key_system_info; streams()[i]->encryption_config().key_system_info;
moov->pssh.resize(key_system_info.size()); moov->pssh.resize(key_system_info.size());

View File

@ -86,7 +86,7 @@ Status MultiSegmentSegmenter::DoFinalizeSegment() {
sidx()->earliest_presentation_time = sidx()->earliest_presentation_time =
sidx()->references[0].earliest_presentation_time; sidx()->references[0].earliest_presentation_time;
if (options().num_subsegments_per_sidx <= 0) if (options().mp4_params.num_subsegments_per_sidx <= 0)
return WriteSegment(); return WriteSegment();
// sidx() contains pre-generated segment references with one reference per // sidx() contains pre-generated segment references with one reference per
@ -94,7 +94,7 @@ Status MultiSegmentSegmenter::DoFinalizeSegment() {
// pre-generated references into final subsegment references. // pre-generated references into final subsegment references.
size_t num_fragments = sidx()->references.size(); size_t num_fragments = sidx()->references.size();
size_t num_fragments_per_subsegment = size_t num_fragments_per_subsegment =
(num_fragments - 1) / options().num_subsegments_per_sidx + 1; (num_fragments - 1) / options().mp4_params.num_subsegments_per_sidx + 1;
if (num_fragments_per_subsegment <= 1) if (num_fragments_per_subsegment <= 1)
return WriteSegment(); return WriteSegment();
@ -130,7 +130,7 @@ Status MultiSegmentSegmenter::DoFinalizeSegment() {
} }
} }
refs.resize(options().num_subsegments_per_sidx); refs.resize(options().mp4_params.num_subsegments_per_sidx);
// earliest_presentation_time is the earliest presentation time of any // earliest_presentation_time is the earliest presentation time of any
// access unit in the reference stream in the first subsegment. // access unit in the reference stream in the first subsegment.
@ -169,7 +169,7 @@ Status MultiSegmentSegmenter::WriteSegment() {
} }
// If num_subsegments_per_sidx is negative, no SIDX box is generated. // If num_subsegments_per_sidx is negative, no SIDX box is generated.
if (options().num_subsegments_per_sidx >= 0) if (options().mp4_params.num_subsegments_per_sidx >= 0)
sidx()->Write(buffer.get()); sidx()->Write(buffer.get());
const size_t segment_size = buffer->Size() + fragment_buffer()->Size(); const size_t segment_size = buffer->Size() + fragment_buffer()->Size();

View File

@ -69,7 +69,7 @@ Status Segmenter::Initialize(
fragmenters_[i].reset(new Fragmenter(streams[i], &moof_->tracks[i])); fragmenters_[i].reset(new Fragmenter(streams[i], &moof_->tracks[i]));
} }
if (options_.mp4_use_decoding_timestamp_in_timeline) { if (options_.mp4_params.use_decoding_timestamp_in_timeline) {
for (uint32_t i = 0; i < streams.size(); ++i) for (uint32_t i = 0; i < streams.size(); ++i)
fragmenters_[i]->set_use_decoding_timestamp_in_timeline(true); fragmenters_[i]->set_use_decoding_timestamp_in_timeline(true);
} }
@ -252,7 +252,7 @@ void Segmenter::FinalizeFragmentForKeyRotation(
size_t stream_id, size_t stream_id,
bool fragment_encrypted, bool fragment_encrypted,
const EncryptionConfig& encryption_config) { const EncryptionConfig& encryption_config) {
if (options_.mp4_include_pssh_in_stream) { if (options_.mp4_params.include_pssh_in_stream) {
const std::vector<ProtectionSystemSpecificInfo>& system_info = const std::vector<ProtectionSystemSpecificInfo>& system_info =
encryption_config.key_system_info; encryption_config.key_system_info;
moof_->pssh.resize(system_info.size()); moof_->pssh.resize(system_info.size());

View File

@ -0,0 +1,36 @@
// 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
#ifndef PACKAGER_MEDIA_PUBLIC_MP4_OUTPUT_PARAMS_H_
#define PACKAGER_MEDIA_PUBLIC_MP4_OUTPUT_PARAMS_H_
namespace shaka {
/// MP4 (ISO-BMFF) output related parameters.
struct Mp4OutputParams {
// Include pssh in the encrypted stream. CMAF and DASH-IF recommends carrying
// license acquisition information in the manifest and not duplicate the
// information in the stream. (This is not a hard requirement so we are still
// CMAF compatible even if pssh is included in the stream.)
bool include_pssh_in_stream = true;
/// 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/subsegment_duration fragments per subsegment.
/// This flag is ingored for DASH MPD with on-demand profile.
static constexpr int kNoSidxBoxInSegment = -1;
static constexpr int kSingleSidxPerSegment = 0;
int num_subsegments_per_sidx = kSingleSidxPerSegment;
/// 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 use_decoding_timestamp_in_timeline = false;
};
} // namespace shaka
#endif // PACKAGER_MEDIA_PUBLIC_MP4_OUTPUT_PARAMS_H_

View File

@ -315,7 +315,6 @@ std::shared_ptr<Muxer> CreateOutputMuxer(const MuxerOptions& options,
bool CreateRemuxJobs(const StreamDescriptorList& stream_descriptors, bool CreateRemuxJobs(const StreamDescriptorList& stream_descriptors,
const PackagingParams& packaging_params, const PackagingParams& packaging_params,
const MuxerOptions& muxer_options,
FakeClock* fake_clock, FakeClock* fake_clock,
KeySource* encryption_key_source, KeySource* encryption_key_source,
MpdNotifier* mpd_notifier, MpdNotifier* mpd_notifier,
@ -338,7 +337,9 @@ bool CreateRemuxJobs(const StreamDescriptorList& stream_descriptors,
MediaContainerName output_format = GetOutputFormat(*stream_iter); MediaContainerName output_format = GetOutputFormat(*stream_iter);
// Process stream descriptor. // Process stream descriptor.
MuxerOptions stream_muxer_options(muxer_options); MuxerOptions stream_muxer_options;
stream_muxer_options.mp4_params = packaging_params.mp4_output_params;
stream_muxer_options.temp_dir = packaging_params.temp_dir;
stream_muxer_options.output_file_name = stream_iter->output; stream_muxer_options.output_file_name = stream_iter->output;
if (!stream_iter->segment_template.empty()) { if (!stream_iter->segment_template.empty()) {
if (!ValidateSegmentTemplate(stream_iter->segment_template)) { if (!ValidateSegmentTemplate(stream_iter->segment_template)) {
@ -583,9 +584,6 @@ Status Packager::Initialize(
std::unique_ptr<PackagerInternal> internal(new PackagerInternal); std::unique_ptr<PackagerInternal> internal(new PackagerInternal);
MuxerOptions muxer_options = media::GetMuxerOptions(
packaging_params.temp_dir, packaging_params.mp4_output_params);
const bool on_demand_dash_profile = const bool on_demand_dash_profile =
stream_descriptors.begin()->segment_template.empty(); stream_descriptors.begin()->segment_template.empty();
MpdOptions mpd_options = MpdOptions mpd_options =
@ -634,10 +632,9 @@ Status Packager::Initialize(
for (const StreamDescriptor& descriptor : stream_descriptors) for (const StreamDescriptor& descriptor : stream_descriptors)
stream_descriptor_list.insert(descriptor); stream_descriptor_list.insert(descriptor);
if (!media::CreateRemuxJobs( if (!media::CreateRemuxJobs(
stream_descriptor_list, packaging_params, muxer_options, stream_descriptor_list, packaging_params, &internal->fake_clock,
&internal->fake_clock, internal->encryption_key_source.get(), internal->encryption_key_source.get(), internal->mpd_notifier.get(),
internal->mpd_notifier.get(), internal->hls_notifier.get(), internal->hls_notifier.get(), &internal->jobs)) {
&internal->jobs)) {
return Status(error::INVALID_ARGUMENT, "Failed to create remux jobs."); return Status(error::INVALID_ARGUMENT, "Failed to create remux jobs.");
} }
internal_ = std::move(internal); internal_ = std::move(internal);

View File

@ -14,32 +14,11 @@
#include "packager/hls/public/hls_playlist_type.h" #include "packager/hls/public/hls_playlist_type.h"
#include "packager/media/public/chunking_params.h" #include "packager/media/public/chunking_params.h"
#include "packager/media/public/crypto_params.h" #include "packager/media/public/crypto_params.h"
#include "packager/media/public/mp4_output_params.h"
#include "packager/status.h" #include "packager/status.h"
namespace shaka { namespace shaka {
/// MP4 (ISO-BMFF) output related parameters.
struct Mp4OutputParams {
// Include pssh in the encrypted stream. CMAF recommends carrying
// license acquisition information in the manifest and not duplicate the
// information in the stream. (This is not a hard requirement so we are still
// CMAF compatible even if pssh is included in the stream.)
bool include_pssh_in_stream = true;
/// 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/subsegment_duration fragments per subsegment.
/// This flag is ingored for DASH MPD with on-demand profile.
const int kNoSidxBoxInSegment = -1;
const int kSingleSidxPerSegment = 0;
int num_subsegments_per_sidx = kSingleSidxPerSegment;
/// 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 use_decoding_timestamp_in_timeline = false;
};
/// DASH MPD related parameters. /// DASH MPD related parameters.
struct MpdParams { struct MpdParams {
/// MPD output file path. /// MPD output file path.