Consolidate MpdParams into MpdOptions

Change-Id: I7f37277ef87597548c2fbf219963cd8725ae4c05
This commit is contained in:
KongQun Yang 2017-07-27 11:49:50 -07:00
parent 4e82ab13bd
commit 556ff56559
18 changed files with 143 additions and 163 deletions

View File

@ -26,8 +26,6 @@ namespace shaka {
namespace media {
namespace {
} // namespace
std::unique_ptr<RequestSigner> CreateSigner(const WidevineSigner& signer) {
std::unique_ptr<RequestSigner> request_signer;
switch (signer.signing_key_type) {
@ -47,6 +45,8 @@ std::unique_ptr<RequestSigner> CreateSigner(const WidevineSigner& signer) {
return request_signer;
}
} // namespace
std::unique_ptr<KeySource> CreateEncryptionKeySource(
FourCC protection_scheme,
const EncryptionParams& encryption_params) {
@ -179,12 +179,7 @@ MpdOptions GetMpdOptions(bool on_demand_profile, const MpdParams& mpd_params) {
(on_demand_profile || mpd_params.generate_static_live_mpd)
? MpdType::kStatic
: MpdType::kDynamic;
mpd_options.minimum_update_period = mpd_params.minimum_update_period;
mpd_options.min_buffer_time = mpd_params.min_buffer_time;
mpd_options.time_shift_buffer_depth = mpd_params.time_shift_buffer_depth;
mpd_options.suggested_presentation_delay =
mpd_params.suggested_presentation_delay;
mpd_options.default_language = mpd_params.default_language;
mpd_options.mpd_params = mpd_params;
return mpd_options;
}

View File

@ -10,18 +10,15 @@
#define PACKAGER_APP_PACKAGER_UTIL_H_
#include <memory>
#include <vector>
#include "packager/base/optional.h"
#include "packager/media/base/fourccs.h"
#include "packager/packager.h"
namespace shaka {
// TODO(kqyang): Should we consolidate XxxParams and XxxOptions?
struct ChunkingParams;
class Status;
struct DecryptionParams;
struct EncryptionParams;
struct Mp4OutputParams;
struct MpdOptions;
struct MpdParams;
@ -29,12 +26,9 @@ namespace media {
class MediaHandler;
class KeySource;
struct ChunkingOptions;
struct EncryptionOptions;
struct MuxerOptions;
/// Create KeySource based on provided command line options for content
/// encryption. Also fetches keys.
/// Create KeySource based on provided params for content encryption. Also
/// fetches keys.
/// @param protection_scheme specifies the protection scheme to be used for
/// encryption.
/// @return A std::unique_ptr containing a new KeySource, or nullptr if
@ -43,14 +37,14 @@ std::unique_ptr<KeySource> CreateEncryptionKeySource(
FourCC protection_scheme,
const EncryptionParams& encryption_params);
/// Create KeySource based on provided command line options for content
/// decryption. Does not fetch keys.
/// Create KeySource based on provided params for content decryption. Does not
/// fetch keys.
/// @return A std::unique_ptr containing a new KeySource, or nullptr if
/// decryption is not required.
std::unique_ptr<KeySource> CreateDecryptionKeySource(
const DecryptionParams& decryption_params);
/// @return MpdOptions from provided command line options.
/// @return MpdOptions from provided inputs.
MpdOptions GetMpdOptions(bool on_demand_profile, const MpdParams& mpd_params);
/// Connect handlers in the vector.

View File

@ -38,15 +38,12 @@ std::set<std::string> GetUUIDs(
} // namespace
DashIopMpdNotifier::DashIopMpdNotifier(
const MpdOptions& mpd_options,
const std::vector<std::string>& base_urls,
const std::string& output_path)
DashIopMpdNotifier::DashIopMpdNotifier(const MpdOptions& mpd_options)
: MpdNotifier(mpd_options),
output_path_(output_path),
output_path_(mpd_options.mpd_params.mpd_output),
mpd_builder_(new MpdBuilder(mpd_options)) {
for (size_t i = 0; i < base_urls.size(); ++i)
mpd_builder_->AddBaseUrl(base_urls[i]);
for (const std::string& base_url : mpd_options.mpd_params.base_urls)
mpd_builder_->AddBaseUrl(base_url);
}
DashIopMpdNotifier::~DashIopMpdNotifier() {}

View File

@ -29,9 +29,7 @@ namespace shaka {
/// All video Adaptation Sets have Role set to "main".
class DashIopMpdNotifier : public MpdNotifier {
public:
DashIopMpdNotifier(const MpdOptions& mpd_options,
const std::vector<std::string>& base_urls,
const std::string& output_path);
explicit DashIopMpdNotifier(const MpdOptions& mpd_options);
~DashIopMpdNotifier() override;
/// None of the methods write out the MPD file until Flush() is called.

View File

@ -101,7 +101,7 @@ class DashIopMpdNotifierTest : public ::testing::Test {
void SetUp() override {
ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path_));
output_path_ = temp_file_path_.AsUTF8Unsafe();
empty_mpd_option_.mpd_params.mpd_output = temp_file_path_.AsUTF8Unsafe();
}
void TearDown() override {
@ -113,11 +113,9 @@ class DashIopMpdNotifierTest : public ::testing::Test {
notifier->SetMpdBuilderForTesting(std::move(mpd_builder));
}
// Use output_path_ for specifying the MPD output path so that
// Empty mpd options except with output path specified, so that
// WriteMpdToFile() doesn't crash.
std::string output_path_;
const MpdOptions empty_mpd_option_;
const std::vector<std::string> empty_base_urls_;
MpdOptions empty_mpd_option_;
// Default mocks that can be used for the tests.
// IOW, if a test only requires one instance of
@ -132,8 +130,7 @@ class DashIopMpdNotifierTest : public ::testing::Test {
// Verify that basic VOD NotifyNewContainer() operation works.
// No encrypted contents.
TEST_F(DashIopMpdNotifierTest, NotifyNewContainer) {
DashIopMpdNotifier notifier(empty_mpd_option_, empty_base_urls_,
output_path_);
DashIopMpdNotifier notifier(empty_mpd_option_);
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
@ -170,8 +167,7 @@ TEST_F(DashIopMpdNotifierTest, NotifyNewContainerForTrickPlay) {
" playback_rate: 10\n"
"}\n"
"container_type: 1\n";
DashIopMpdNotifier notifier(empty_mpd_option_, empty_base_urls_,
output_path_);
DashIopMpdNotifier notifier(empty_mpd_option_);
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
@ -228,8 +224,7 @@ TEST_F(DashIopMpdNotifierTest, NotifyNewTextContainer) {
" language: 'en'\n"
"}\n"
"container_type: CONTAINER_TEXT\n";
DashIopMpdNotifier notifier(empty_mpd_option_, empty_base_urls_,
output_path_);
DashIopMpdNotifier notifier(empty_mpd_option_);
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
@ -257,8 +252,7 @@ TEST_F(DashIopMpdNotifierTest, NotifyNewTextContainer) {
// AdaptationSets with different DRM won't be switchable.
TEST_F(DashIopMpdNotifierTest,
NotifyNewContainersWithDifferentProtectedContent) {
DashIopMpdNotifier notifier(empty_mpd_option_, empty_base_urls_,
output_path_);
DashIopMpdNotifier notifier(empty_mpd_option_);
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
// Note they both have different (bogus) pssh, like real use case.
@ -375,8 +369,7 @@ TEST_F(DashIopMpdNotifierTest,
// MediaInfo::ProtectedContent. Only one AdaptationSet should be
// created.
TEST_F(DashIopMpdNotifierTest, NotifyNewContainersWithSameProtectedContent) {
DashIopMpdNotifier notifier(empty_mpd_option_, empty_base_urls_,
output_path_);
DashIopMpdNotifier notifier(empty_mpd_option_);
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
// These have the same default key ID and PSSH.
@ -477,8 +470,7 @@ TEST_F(DashIopMpdNotifierTest, NotifyNewContainersWithSameProtectedContent) {
// AddContentProtection() should not work and should always return false.
TEST_F(DashIopMpdNotifierTest, AddContentProtection) {
DashIopMpdNotifier notifier(empty_mpd_option_, empty_base_urls_,
output_path_);
DashIopMpdNotifier notifier(empty_mpd_option_);
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
@ -508,8 +500,7 @@ TEST_F(DashIopMpdNotifierTest, AddContentProtection) {
// 3. Add a 4k protected content. This should also make a new AdaptationSet.
// It should be switchable with SD/HD AdaptationSet.
TEST_F(DashIopMpdNotifierTest, SetAdaptationSetSwitching) {
DashIopMpdNotifier notifier(empty_mpd_option_, empty_base_urls_,
output_path_);
DashIopMpdNotifier notifier(empty_mpd_option_);
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
// These have the same default key ID and PSSH.
@ -645,8 +636,7 @@ TEST_F(DashIopMpdNotifierTest, SetAdaptationSetSwitching) {
// switchable.
TEST_F(DashIopMpdNotifierTest,
DoNotSetAdaptationSetSwitchingIfContentTypesDifferent) {
DashIopMpdNotifier notifier(empty_mpd_option_, empty_base_urls_,
output_path_);
DashIopMpdNotifier notifier(empty_mpd_option_);
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
// These have the same default key ID and PSSH.
@ -752,8 +742,7 @@ TEST_F(DashIopMpdNotifierTest, UpdateEncryption) {
"}\n"
"container_type: 1\n";
DashIopMpdNotifier notifier(empty_mpd_option_, empty_base_urls_,
output_path_);
DashIopMpdNotifier notifier(empty_mpd_option_);
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
@ -792,8 +781,7 @@ TEST_F(DashIopMpdNotifierTest, UpdateEncryption) {
// This issue identified a bug where using SimpleMpdNotifier with multiple
// threads causes a deadlock. This tests with DashIopMpdNotifier.
TEST_F(DashIopMpdNotifierTest, NotifyNewContainerAndSampleDurationNoMock) {
DashIopMpdNotifier notifier(empty_mpd_option_, empty_base_urls_,
output_path_);
DashIopMpdNotifier notifier(empty_mpd_option_);
uint32_t container_id;
EXPECT_TRUE(notifier.NotifyNewContainer(ConvertToMediaInfo(kValidMediaInfo),
&container_id));
@ -856,8 +844,7 @@ TEST_F(DashIopMpdNotifierTest, SplitAdaptationSetsByLanguageAndCodec) {
"container_type: CONTAINER_WEBM\n"
"media_duration_seconds: 10.5\n";
DashIopMpdNotifier notifier(empty_mpd_option_, empty_base_urls_,
output_path_);
DashIopMpdNotifier notifier(empty_mpd_option_);
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
std::unique_ptr<MockAdaptationSet> adaptation_set1(new MockAdaptationSet(1));

View File

@ -385,7 +385,7 @@ AdaptationSet* MpdBuilder::AddAdaptationSet(const std::string& lang) {
&representation_counter_));
DCHECK(adaptation_set);
if (!lang.empty() && lang == mpd_options_.default_language) {
if (!lang.empty() && lang == mpd_options_.mpd_params.default_language) {
adaptation_set->AddRole(AdaptationSet::kRoleMain);
}
@ -503,9 +503,10 @@ xmlDocPtr MpdBuilder::GenerateMpd() {
}
void MpdBuilder::AddCommonMpdInfo(XmlNode* mpd_node) {
if (Positive(mpd_options_.min_buffer_time)) {
if (Positive(mpd_options_.mpd_params.min_buffer_time)) {
mpd_node->SetStringAttribute(
"minBufferTime", SecondsToXmlDuration(mpd_options_.min_buffer_time));
"minBufferTime",
SecondsToXmlDuration(mpd_options_.mpd_params.min_buffer_time));
} else {
LOG(ERROR) << "minBufferTime value not specified.";
// TODO(tinskip): Propagate error.
@ -551,19 +552,19 @@ void MpdBuilder::AddDynamicMpdInfo(XmlNode* mpd_node) {
mpd_node->SetStringAttribute("availabilityStartTime",
availability_start_time_);
if (Positive(mpd_options_.minimum_update_period)) {
if (Positive(mpd_options_.mpd_params.minimum_update_period)) {
mpd_node->SetStringAttribute(
"minimumUpdatePeriod",
SecondsToXmlDuration(mpd_options_.minimum_update_period));
SecondsToXmlDuration(mpd_options_.mpd_params.minimum_update_period));
} else {
LOG(WARNING) << "The profile is dynamic but no minimumUpdatePeriod "
"specified.";
}
SetIfPositive("timeShiftBufferDepth", mpd_options_.time_shift_buffer_depth,
mpd_node);
SetIfPositive("timeShiftBufferDepth",
mpd_options_.mpd_params.time_shift_buffer_depth, mpd_node);
SetIfPositive("suggestedPresentationDelay",
mpd_options_.suggested_presentation_delay, mpd_node);
mpd_options_.mpd_params.suggested_presentation_delay, mpd_node);
}
float MpdBuilder::GetStaticMpdDuration(XmlNode* mpd_node) {
@ -1287,15 +1288,15 @@ bool Representation::IsContiguous(uint64_t start_time,
void Representation::SlideWindow() {
DCHECK(!segment_infos_.empty());
if (mpd_options_.time_shift_buffer_depth <= 0.0 ||
if (mpd_options_.mpd_params.time_shift_buffer_depth <= 0.0 ||
mpd_options_.mpd_type == MpdType::kStatic)
return;
const uint32_t time_scale = GetTimeScale(media_info_);
DCHECK_GT(time_scale, 0u);
uint64_t time_shift_buffer_depth =
static_cast<uint64_t>(mpd_options_.time_shift_buffer_depth * time_scale);
uint64_t time_shift_buffer_depth = static_cast<uint64_t>(
mpd_options_.mpd_params.time_shift_buffer_depth * time_scale);
// The start time of the latest segment is considered the current_play_time,
// and this should guarantee that the latest segment will stay in the list.

View File

@ -2196,7 +2196,8 @@ TEST_F(SegmentTemplateTest, OverlappingSegmentsWithinErrorRange) {
// All segments have the same duration and size.
TEST_F(TimeShiftBufferDepthTest, Normal) {
const int kTimeShiftBufferDepth = 10; // 10 sec.
mutable_mpd_options()->time_shift_buffer_depth = kTimeShiftBufferDepth;
mutable_mpd_options()->mpd_params.time_shift_buffer_depth =
kTimeShiftBufferDepth;
const uint64_t kInitialStartTime = 0;
// Trick to make every segment 1 second long.
@ -2233,7 +2234,8 @@ TEST_F(TimeShiftBufferDepthTest, Normal) {
// removed from the MPD.
TEST_F(TimeShiftBufferDepthTest, TimeShiftBufferDepthShorterThanSegmentLength) {
const int kTimeShiftBufferDepth = 10; // 10 sec.
mutable_mpd_options()->time_shift_buffer_depth = kTimeShiftBufferDepth;
mutable_mpd_options()->mpd_params.time_shift_buffer_depth =
kTimeShiftBufferDepth;
const uint64_t kInitialStartTime = 0;
// Each duration is a second longer than timeShiftBufferDepth.
@ -2254,7 +2256,8 @@ TEST_F(TimeShiftBufferDepthTest, TimeShiftBufferDepthShorterThanSegmentLength) {
// More generic version the normal test.
TEST_F(TimeShiftBufferDepthTest, Generic) {
const int kTimeShiftBufferDepth = 30;
mutable_mpd_options()->time_shift_buffer_depth = kTimeShiftBufferDepth;
mutable_mpd_options()->mpd_params.time_shift_buffer_depth =
kTimeShiftBufferDepth;
const uint64_t kInitialStartTime = 123;
const uint64_t kDuration = DefaultTimeScale();
@ -2296,7 +2299,8 @@ TEST_F(TimeShiftBufferDepthTest, Generic) {
// the most recent segment added does not count
TEST_F(TimeShiftBufferDepthTest, MoreThanOneS) {
const int kTimeShiftBufferDepth = 100;
mutable_mpd_options()->time_shift_buffer_depth = kTimeShiftBufferDepth;
mutable_mpd_options()->mpd_params.time_shift_buffer_depth =
kTimeShiftBufferDepth;
const uint64_t kInitialStartTime = 0;
const uint64_t kSize = 20000;
@ -2346,7 +2350,8 @@ TEST_F(TimeShiftBufferDepthTest, MoreThanOneS) {
// Then the first S element's last segment should still be in the MPD.
TEST_F(TimeShiftBufferDepthTest, UseLastSegmentInS) {
const int kTimeShiftBufferDepth = 9;
mutable_mpd_options()->time_shift_buffer_depth = kTimeShiftBufferDepth;
mutable_mpd_options()->mpd_params.time_shift_buffer_depth =
kTimeShiftBufferDepth;
const uint64_t kInitialStartTime = 1;
const uint64_t kDuration1 = static_cast<uint64_t>(DefaultTimeScale() * 1.5);
@ -2382,7 +2387,8 @@ TEST_F(TimeShiftBufferDepthTest, UseLastSegmentInS) {
// Gap between S elements but both should be included.
TEST_F(TimeShiftBufferDepthTest, NormalGap) {
const int kTimeShiftBufferDepth = 10;
mutable_mpd_options()->time_shift_buffer_depth = kTimeShiftBufferDepth;
mutable_mpd_options()->mpd_params.time_shift_buffer_depth =
kTimeShiftBufferDepth;
const uint64_t kInitialStartTime = 0;
const uint64_t kDuration = DefaultTimeScale();
@ -2413,7 +2419,8 @@ TEST_F(TimeShiftBufferDepthTest, NormalGap) {
// Case where there is a huge gap so the first S element is removed.
TEST_F(TimeShiftBufferDepthTest, HugeGap) {
const int kTimeShiftBufferDepth = 10;
mutable_mpd_options()->time_shift_buffer_depth = kTimeShiftBufferDepth;
mutable_mpd_options()->mpd_params.time_shift_buffer_depth =
kTimeShiftBufferDepth;
const uint64_t kInitialStartTime = 0;
const uint64_t kDuration = DefaultTimeScale();
@ -2448,7 +2455,8 @@ TEST_F(TimeShiftBufferDepthTest, HugeGap) {
// Check if startNumber is working correctly.
TEST_F(TimeShiftBufferDepthTest, ManySegments) {
const int kTimeShiftBufferDepth = 1;
mutable_mpd_options()->time_shift_buffer_depth = kTimeShiftBufferDepth;
mutable_mpd_options()->mpd_params.time_shift_buffer_depth =
kTimeShiftBufferDepth;
const uint64_t kInitialStartTime = 0;
const uint64_t kDuration = DefaultTimeScale();

View File

@ -9,6 +9,8 @@
#include <string>
#include "packager/mpd/public/mpd_params.h"
namespace shaka {
enum class DashProfile {
@ -23,12 +25,7 @@ enum class MpdType { kStatic, kDynamic };
struct MpdOptions {
DashProfile dash_profile = DashProfile::kOnDemand;
MpdType mpd_type = MpdType::kStatic;
double minimum_update_period = 0;
// TODO(tinskip): Set min_buffer_time in unit tests rather than here.
double min_buffer_time = 2.0;
double time_shift_buffer_depth = 0;
double suggested_presentation_delay = 0;
std::string default_language;
MpdParams mpd_params;
};
} // namespace shaka

View File

@ -14,14 +14,12 @@
namespace shaka {
SimpleMpdNotifier::SimpleMpdNotifier(const MpdOptions& mpd_options,
const std::vector<std::string>& base_urls,
const std::string& output_path)
SimpleMpdNotifier::SimpleMpdNotifier(const MpdOptions& mpd_options)
: MpdNotifier(mpd_options),
output_path_(output_path),
output_path_(mpd_options.mpd_params.mpd_output),
mpd_builder_(new MpdBuilder(mpd_options)) {
for (size_t i = 0; i < base_urls.size(); ++i)
mpd_builder_->AddBaseUrl(base_urls[i]);
for (const std::string& base_url : mpd_options.mpd_params.base_urls)
mpd_builder_->AddBaseUrl(base_url);
}
SimpleMpdNotifier::~SimpleMpdNotifier() {

View File

@ -30,9 +30,7 @@ struct MpdOptions;
/// generates an Mpd file.
class SimpleMpdNotifier : public MpdNotifier {
public:
SimpleMpdNotifier(const MpdOptions& mpd_options,
const std::vector<std::string>& base_urls,
const std::string& output_path);
explicit SimpleMpdNotifier(const MpdOptions& mpd_options);
~SimpleMpdNotifier() override;
/// @name MpdNotifier implemetation overrides.

View File

@ -43,7 +43,7 @@ class SimpleMpdNotifierTest : public ::testing::Test {
void SetUp() override {
ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path_));
output_path_ = temp_file_path_.AsUTF8Unsafe();
empty_mpd_option_.mpd_params.mpd_output = temp_file_path_.AsUTF8Unsafe();
}
void TearDown() override {
@ -55,10 +55,9 @@ class SimpleMpdNotifierTest : public ::testing::Test {
notifier->SetMpdBuilderForTesting(std::move(mpd_builder));
}
// Use output_path_ for specifying the MPD output path so that
// Empty mpd options except with output path specified, so that
// WriteMpdToFile() doesn't crash.
std::string output_path_;
const MpdOptions empty_mpd_option_;
MpdOptions empty_mpd_option_;
const std::vector<std::string> empty_base_urls_;
// Default AdaptationSet mock.
@ -70,7 +69,7 @@ class SimpleMpdNotifierTest : public ::testing::Test {
// Verify NotifyNewContainer() works as expected for VOD.
TEST_F(SimpleMpdNotifierTest, NotifyNewContainer) {
SimpleMpdNotifier notifier(empty_mpd_option_, empty_base_urls_, output_path_);
SimpleMpdNotifier notifier(empty_mpd_option_);
const uint32_t kRepresentationId = 1u;
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
@ -94,7 +93,7 @@ TEST_F(SimpleMpdNotifierTest, NotifyNewContainer) {
}
TEST_F(SimpleMpdNotifierTest, NotifySampleDuration) {
SimpleMpdNotifier notifier(empty_mpd_option_, empty_base_urls_, output_path_);
SimpleMpdNotifier notifier(empty_mpd_option_);
const uint32_t kRepresentationId = 8u;
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
@ -124,7 +123,7 @@ TEST_F(SimpleMpdNotifierTest, NotifySampleDuration) {
// This issue identified a bug where using SimpleMpdNotifier with multiple
// threads causes a deadlock.
TEST_F(SimpleMpdNotifierTest, NotifyNewContainerAndSampleDurationNoMock) {
SimpleMpdNotifier notifier(empty_mpd_option_, empty_base_urls_, output_path_);
SimpleMpdNotifier notifier(empty_mpd_option_);
uint32_t container_id;
EXPECT_TRUE(notifier.NotifyNewContainer(ConvertToMediaInfo(kValidMediaInfo),
&container_id));
@ -134,7 +133,7 @@ TEST_F(SimpleMpdNotifierTest, NotifyNewContainerAndSampleDurationNoMock) {
}
TEST_F(SimpleMpdNotifierTest, NotifyNewSegment) {
SimpleMpdNotifier notifier(empty_mpd_option_, empty_base_urls_, output_path_);
SimpleMpdNotifier notifier(empty_mpd_option_);
const uint32_t kRepresentationId = 447834u;
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
@ -163,7 +162,7 @@ TEST_F(SimpleMpdNotifierTest, NotifyNewSegment) {
}
TEST_F(SimpleMpdNotifierTest, AddContentProtectionElement) {
SimpleMpdNotifier notifier(empty_mpd_option_, empty_base_urls_, output_path_);
SimpleMpdNotifier notifier(empty_mpd_option_);
const uint32_t kRepresentationId = 0u;
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
@ -206,7 +205,7 @@ TEST_F(SimpleMpdNotifierTest, UpdateEncryption) {
" default_key_id: '_default_key_id_'\n"
"}\n"
"container_type: 1\n";
SimpleMpdNotifier notifier(empty_mpd_option_, empty_base_urls_, output_path_);
SimpleMpdNotifier notifier(empty_mpd_option_);
const uint32_t kRepresentationId = 447834u;
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
std::unique_ptr<MockRepresentation> mock_representation(
@ -294,7 +293,7 @@ TEST_F(SimpleMpdNotifierTest, SplitAdaptationSetsByLanguageAndCodec) {
"container_type: CONTAINER_WEBM\n"
"media_duration_seconds: 10.5\n";
SimpleMpdNotifier notifier(empty_mpd_option_, empty_base_urls_, output_path_);
SimpleMpdNotifier notifier(empty_mpd_option_);
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
std::unique_ptr<MockAdaptationSet> adaptation_set1(new MockAdaptationSet(1));

View File

@ -47,6 +47,7 @@
'base/xml/scoped_xml_ptr.h',
'base/xml/xml_node.cc',
'base/xml/xml_node.h',
'public/mpd_params.h',
],
'dependencies': [
'../base/base.gyp:base',

View File

@ -0,0 +1,53 @@
// 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_MPD_PUBLIC_MPD_PARAMS_H_
#define PACKAGER_MPD_PUBLIC_MPD_PARAMS_H_
#include <string>
#include <vector>
namespace shaka {
/// DASH MPD related parameters.
struct MpdParams {
/// MPD output file path.
std::string mpd_output;
/// BaseURLs for the MPD. The values will be added as <BaseURL> element(s)
/// under the <MPD> element.
std::vector<std::string> base_urls;
/// Set MPD@minBufferTime attribute, which specifies, in seconds, a common
/// duration used in the definition of the MPD representation data rate. A
/// client can be assured of having enough data for continous playout
/// providing playout begins at min_buffer_time after the first bit is
/// received.
double min_buffer_time = 2.0;
/// Generate static MPD for live profile. Note that this flag has no effect
/// for on-demand profile, in which case static MPD is always used.
bool generate_static_live_mpd = false;
/// Set MPD@timeShiftBufferDepth attribute, which is the guaranteed duration
/// of the time shifting buffer for 'dynamic' media presentations, in seconds.
double time_shift_buffer_depth = 0;
/// Set MPD@suggestedPresentationDelay attribute. For 'dynamic' media
/// presentations, it specifies a delay, in seconds, to be added to the media
/// presentation time. The attribute is not set if the value is 0; the client
/// is expected to choose a suitable value in this case.
static constexpr double kSuggestedPresentationDelayNotSet = 0;
double suggested_presentation_delay = kSuggestedPresentationDelayNotSet;
/// Set MPD@minimumUpdatePeriod attribute, which indicates to the player how
/// often to refresh the MPD in seconds. For dynamic MPD only.
double minimum_update_period = 0;
/// The tracks tagged with this language will have <Role ... value=\"main\" />
/// in the manifest. This allows the player to choose the correct default
/// language for the content.
std::string default_language;
/// Try to generate DASH-IF IOP compliant MPD.
bool generate_dash_if_iop_compliant_mpd = true;
};
} // namespace shaka
#endif // PACKAGER_MPD_PUBLIC_MPD_PARAMS_H_

View File

@ -35,11 +35,8 @@ class DashIopMpdNotifierFactory : public MpdNotifierFactory {
DashIopMpdNotifierFactory() {}
~DashIopMpdNotifierFactory() override {}
std::unique_ptr<MpdNotifier> Create(const MpdOptions& mpd_options,
const std::vector<std::string>& base_urls,
const std::string& output_path) override {
return std::unique_ptr<MpdNotifier>(
new DashIopMpdNotifier(mpd_options, base_urls, output_path));
std::unique_ptr<MpdNotifier> Create(const MpdOptions& mpd_options) override {
return std::unique_ptr<MpdNotifier>(new DashIopMpdNotifier(mpd_options));
}
};
@ -49,11 +46,8 @@ class SimpleMpdNotifierFactory : public MpdNotifierFactory {
SimpleMpdNotifierFactory() {}
~SimpleMpdNotifierFactory() override {}
std::unique_ptr<MpdNotifier> Create(const MpdOptions& mpd_options,
const std::vector<std::string>& base_urls,
const std::string& output_path) override {
return std::unique_ptr<MpdNotifier>(
new SimpleMpdNotifier(mpd_options, base_urls, output_path));
std::unique_ptr<MpdNotifier> Create(const MpdOptions& mpd_options) override {
return std::unique_ptr<MpdNotifier>(new SimpleMpdNotifier(mpd_options));
}
};
@ -93,8 +87,11 @@ void MpdWriter::AddBaseUrl(const std::string& base_url) {
bool MpdWriter::WriteMpdToFile(const char* file_name) {
CHECK(file_name);
MpdOptions mpd_options;
mpd_options.mpd_params.base_urls = base_urls_;
mpd_options.mpd_params.mpd_output = file_name;
std::unique_ptr<MpdNotifier> notifier =
notifier_factory_->Create(MpdOptions(), base_urls_, file_name);
notifier_factory_->Create(mpd_options);
if (!notifier->Init()) {
LOG(ERROR) << "failed to initialize MpdNotifier.";
return false;

View File

@ -35,9 +35,7 @@ class MpdNotifierFactory {
virtual ~MpdNotifierFactory() {}
virtual std::unique_ptr<MpdNotifier> Create(
const MpdOptions& mpd_options,
const std::vector<std::string>& base_urls,
const std::string& output_path) = 0;
const MpdOptions& mpd_options) = 0;
};
// An instance of this class takes a set of MediaInfo files and generates an

View File

@ -33,10 +33,8 @@ class TestMpdNotifierFactory : public MpdNotifierFactory {
// std::unique_ptr.
// For now we only need to return MockMpdNotifier() with these set of
// expectations for all the tests.
std::unique_ptr<MpdNotifier> Create(const MpdOptions& mpd_options,
const std::vector<std::string>& base_urls,
const std::string& output_path) override {
EXPECT_EQ(expected_base_urls_, base_urls);
std::unique_ptr<MpdNotifier> Create(const MpdOptions& mpd_options) override {
EXPECT_EQ(expected_base_urls_, mpd_options.mpd_params.base_urls);
std::unique_ptr<MockMpdNotifier> mock_notifier(
new MockMpdNotifier(mpd_options));

View File

@ -43,9 +43,7 @@
namespace shaka {
// TODO(kqyang): Clean up namespaces.
using media::ChunkingOptions;
using media::Demuxer;
using media::EncryptionOptions;
using media::KeySource;
using media::MuxerOptions;
@ -602,11 +600,9 @@ Status Packager::Initialize(
const MpdParams& mpd_params = packaging_params.mpd_params;
if (!mpd_params.mpd_output.empty()) {
if (mpd_params.generate_dash_if_iop_compliant_mpd) {
internal->mpd_notifier.reset(new DashIopMpdNotifier(
mpd_options, mpd_params.base_urls, mpd_params.mpd_output));
internal->mpd_notifier.reset(new DashIopMpdNotifier(mpd_options));
} else {
internal->mpd_notifier.reset(new SimpleMpdNotifier(
mpd_options, mpd_params.base_urls, mpd_params.mpd_output));
internal->mpd_notifier.reset(new SimpleMpdNotifier(mpd_options));
}
if (!internal->mpd_notifier->Init()) {
LOG(ERROR) << "MpdNotifier failed to initialize.";

View File

@ -15,46 +15,11 @@
#include "packager/media/public/chunking_params.h"
#include "packager/media/public/crypto_params.h"
#include "packager/media/public/mp4_output_params.h"
#include "packager/mpd/public/mpd_params.h"
#include "packager/status.h"
namespace shaka {
/// DASH MPD related parameters.
struct MpdParams {
/// MPD output file path.
std::string mpd_output;
/// BaseURLs for the MPD. The values will be added as <BaseURL> element(s)
/// under the <MPD> element.
std::vector<std::string> base_urls;
/// Set MPD@minBufferTime attribute, which specifies, in seconds, a common
/// duration used in the definition of the MPD representation data rate. A
/// client can be assured of having enough data for continous playout
/// providing playout begins at min_buffer_time after the first bit is
/// received.
double min_buffer_time = 2.0;
/// Generate static MPD for live profile. Note that this flag has no effect
/// for on-demand profile, in which case static MPD is always used.
bool generate_static_live_mpd = false;
/// Set MPD@timeShiftBufferDepth attribute, which is the guaranteed duration
/// of the time shifting buffer for 'dynamic' media presentations, in seconds.
double time_shift_buffer_depth = 0;
/// Set MPD@suggestedPresentationDelay attribute. For 'dynamic' media
/// presentations, it specifies a delay, in seconds, to be added to the media
/// presentation time. The attribute is not set if the value is 0; the client
/// is expected to choose a suitable value in this case.
const double kSuggestedPresentationDelayNotSet = 0;
double suggested_presentation_delay = kSuggestedPresentationDelayNotSet;
/// Set MPD@minimumUpdatePeriod attribute, which indicates to the player how
/// often to refresh the MPD in seconds. For dynamic MPD only.
double minimum_update_period = 0;
/// The tracks tagged with this language will have <Role ... value=\"main\" />
/// in the manifest. This allows the player to choose the correct default
/// language for the content.
std::string default_language;
/// Try to generate DASH-IF IOP compliant MPD.
bool generate_dash_if_iop_compliant_mpd = true;
};
/// HLS related parameters.
struct HlsParams {
/// HLS playlist type. See HLS specification for details.