From 6a7b32641a14b65d73ad8e382aa64f727fced1ff Mon Sep 17 00:00:00 2001 From: Rintaro Kuroiwa Date: Mon, 14 Sep 2015 12:53:32 -0700 Subject: [PATCH] Get MpdWriter working again - ContentProtection elements were missing when using MpdWriter, therefore mpd_generator also did not generate ContentProtection. - MpdWriter uses MpdNotifier now, instead of directly using MpdBuiler. - Add mock_mpd_notifier.{h,cc} to be shared by several tests. Change-Id: Id0f6213aa0c80e50294cd4193962054b0b5c2492 --- packager/media/event/media_event.gyp | 1 + .../mpd_notify_muxer_listener_unittest.cc | 27 +-- packager/mpd/base/mock_mpd_notifier.cc | 8 + packager/mpd/base/mock_mpd_notifier.h | 47 ++++ packager/mpd/mpd.gyp | 19 +- packager/mpd/util/mpd_writer.cc | 205 ++++++------------ packager/mpd/util/mpd_writer.h | 34 ++- packager/mpd/util/mpd_writer_unittest.cc | 177 +++++++-------- 8 files changed, 242 insertions(+), 276 deletions(-) create mode 100644 packager/mpd/base/mock_mpd_notifier.cc create mode 100644 packager/mpd/base/mock_mpd_notifier.h diff --git a/packager/media/event/media_event.gyp b/packager/media/event/media_event.gyp index fd08063a61..5f5334ed02 100644 --- a/packager/media/event/media_event.gyp +++ b/packager/media/event/media_event.gyp @@ -41,6 +41,7 @@ 'dependencies': [ '../../base/base.gyp:base', '../../mpd/mpd.gyp:media_info_proto', + '../../mpd/mpd.gyp:mpd_mocks', '../../testing/gmock.gyp:gmock', '../../testing/gtest.gyp:gtest', '../../testing/gtest.gyp:gtest_main', diff --git a/packager/media/event/mpd_notify_muxer_listener_unittest.cc b/packager/media/event/mpd_notify_muxer_listener_unittest.cc index fddf4b7e05..701af21002 100644 --- a/packager/media/event/mpd_notify_muxer_listener_unittest.cc +++ b/packager/media/event/mpd_notify_muxer_listener_unittest.cc @@ -17,6 +17,7 @@ #include "packager/media/event/muxer_listener_test_helper.h" #include "packager/mpd/base/content_protection_element.h" #include "packager/mpd/base/media_info.pb.h" +#include "packager/mpd/base/mock_mpd_notifier.h" #include "packager/mpd/base/mpd_notifier.h" using ::testing::_; @@ -36,32 +37,6 @@ MediaInfo ConvertToMediaInfo(const std::string& media_info_string) { return media_info; } -class MockMpdNotifier : public MpdNotifier { - public: - MockMpdNotifier(DashProfile profile) : MpdNotifier(profile) {} - virtual ~MockMpdNotifier() OVERRIDE {} - - MOCK_METHOD0(Init, bool()); - MOCK_METHOD2(NotifyNewContainer, - bool(const MediaInfo& media_info, uint32_t* container_id)); - MOCK_METHOD2(NotifySampleDuration, - bool(uint32_t container_id, uint32_t sample_duration)); - MOCK_METHOD4(NotifyNewSegment, - bool(uint32_t container_id, - uint64_t start_time, - uint64_t duration, - uint64_t size)); - MOCK_METHOD3(NotifyEncryptionUpdate, - bool(uint32_t container_id, - const std::vector& new_key_id, - const std::vector& new_pssh)); - MOCK_METHOD2( - AddContentProtectionElement, - bool(uint32_t container_id, - const ContentProtectionElement& content_protection_element)); - MOCK_METHOD0(Flush, bool()); -}; - } // namespace namespace media { diff --git a/packager/mpd/base/mock_mpd_notifier.cc b/packager/mpd/base/mock_mpd_notifier.cc new file mode 100644 index 0000000000..22c35daaa3 --- /dev/null +++ b/packager/mpd/base/mock_mpd_notifier.cc @@ -0,0 +1,8 @@ +#include "packager/mpd/base/mock_mpd_notifier.h" + +namespace edash_packager { + +MockMpdNotifier::MockMpdNotifier(DashProfile profile) : MpdNotifier(profile) {} +MockMpdNotifier::~MockMpdNotifier() {} + +} // namespace edash_packager diff --git a/packager/mpd/base/mock_mpd_notifier.h b/packager/mpd/base/mock_mpd_notifier.h new file mode 100644 index 0000000000..c0293e4986 --- /dev/null +++ b/packager/mpd/base/mock_mpd_notifier.h @@ -0,0 +1,47 @@ +// Copyright 2015 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 MPD_BASE_MOCK_MPD_NOTIFIER_H_ +#define MPD_BASE_MOCK_MPD_NOTIFIER_H_ + +#include "packager/mpd/base/mpd_notifier.h" + +#include + +#include "packager/mpd/base/content_protection_element.h" +#include "packager/mpd/base/media_info.pb.h" + +namespace edash_packager { + +class MockMpdNotifier : public MpdNotifier { + public: + MockMpdNotifier(DashProfile profile); + virtual ~MockMpdNotifier() OVERRIDE; + + MOCK_METHOD0(Init, bool()); + MOCK_METHOD2(NotifyNewContainer, + bool(const MediaInfo& media_info, uint32_t* container_id)); + MOCK_METHOD2(NotifySampleDuration, + bool(uint32_t container_id, uint32_t sample_duration)); + MOCK_METHOD4(NotifyNewSegment, + bool(uint32_t container_id, + uint64_t start_time, + uint64_t duration, + uint64_t size)); + MOCK_METHOD3(NotifyEncryptionUpdate, + bool(uint32_t container_id, + const std::vector& new_key_id, + const std::vector& new_pssh)); + MOCK_METHOD2( + AddContentProtectionElement, + bool(uint32_t container_id, + const ContentProtectionElement& content_protection_element)); + MOCK_METHOD0(Flush, bool()); +}; + +} // namespace edash_packager + +#endif // MPD_BASE_MOCK_MPD_NOTIFIER_H_ diff --git a/packager/mpd/mpd.gyp b/packager/mpd/mpd.gyp index faa61299f9..484c89a737 100644 --- a/packager/mpd/mpd.gyp +++ b/packager/mpd/mpd.gyp @@ -67,14 +67,26 @@ 'media_info_proto', ], }, + { + 'target_name': 'mpd_mocks', + 'type': '<(component)', + 'sources': [ + 'base/mock_mpd_builder.cc', + 'base/mock_mpd_builder.h', + 'base/mock_mpd_notifier.cc', + 'base/mock_mpd_notifier.h', + ], + 'dependencies': [ + '../testing/gmock.gyp:gmock', + 'mpd_builder', + ], + }, { 'target_name': 'mpd_unittest', 'type': '<(gtest_target_type)', 'sources': [ 'base/bandwidth_estimator_unittest.cc', 'base/dash_iop_mpd_notifier_unittest.cc', - 'base/mock_mpd_builder.cc', - 'base/mock_mpd_builder.h', 'base/mpd_builder_unittest.cc', 'base/simple_mpd_notifier_unittest.cc', 'base/xml/xml_node_unittest.cc', @@ -91,6 +103,7 @@ '../testing/gmock.gyp:gmock', '../testing/gtest.gyp:gtest', 'mpd_builder', + 'mpd_mocks', 'mpd_util', ], }, @@ -103,7 +116,9 @@ ], 'dependencies': [ '../media/file/file.gyp:file', + '../third_party/gflags/gflags.gyp:gflags', 'mpd_builder', + 'mpd_mocks', ], }, ], diff --git a/packager/mpd/util/mpd_writer.cc b/packager/mpd/util/mpd_writer.cc index bd6b2434e0..99b84c465c 100644 --- a/packager/mpd/util/mpd_writer.cc +++ b/packager/mpd/util/mpd_writer.cc @@ -6,12 +6,24 @@ #include "packager/mpd/util/mpd_writer.h" +#include #include #include +#include "packager/base/file_util.h" +#include "packager/base/files/file_path.h" #include "packager/media/file/file.h" +#include "packager/mpd/base/dash_iop_mpd_notifier.h" #include "packager/mpd/base/mpd_builder.h" +#include "packager/mpd/base/mpd_notifier.h" #include "packager/mpd/base/mpd_utils.h" +#include "packager/mpd/base/simple_mpd_notifier.h" + +DEFINE_bool(generate_dash_if_iop_compliant_mpd, + false, + "Try to generate DASH-IF IOPv3 compliant MPD. This is best effort " + "and does not guarantee compliance. Off by default until players " + "support IOP MPDs."); using edash_packager::media::File; @@ -19,109 +31,46 @@ namespace edash_packager { namespace { -// On entry set |has_video|, |has_audio|, and |has_text| to false. -// On success, return true and set appropriate |has_*| variables. Otherwise -// return false. -bool HasVideoAudioText(const std::list& media_infos, - bool* has_video, - bool* has_audio, - bool* has_text) { - DCHECK(has_video); - DCHECK(has_audio); - DCHECK(has_text); +// Factory that creates DashIopMpdNotifier instances. +class DashIopMpdNotifierFactory : public MpdNotifierFactory { + public: + DashIopMpdNotifierFactory() {} + virtual ~DashIopMpdNotifierFactory() OVERRIDE {} - *has_video = false; - *has_audio = false; - *has_text = false; - - for (std::list::const_iterator it = media_infos.begin(); - it != media_infos.end(); - ++it) { - const MediaInfo& media_info = *it; - const bool media_info_has_video = media_info.has_video_info(); - const bool media_info_has_audio = media_info.has_audio_info(); - const bool media_info_has_text = media_info.has_text_info(); - - if (MoreThanOneTrue( - media_info_has_video, media_info_has_audio, media_info_has_text)) { - LOG(ERROR) << "MpdWriter cannot handle MediaInfo with more than " - "one stream."; - return false; - } - - if (!AtLeastOneTrue( - media_info_has_video, media_info_has_audio, media_info_has_text)) { - LOG(ERROR) << "MpdWriter requires that MediaInfo contain one " - "audio, video, or text stream."; - return false; - } - - *has_video = *has_video || media_info_has_video; - *has_audio = *has_audio || media_info_has_audio; - *has_text = *has_text || media_info_has_text; + virtual scoped_ptr Create( + DashProfile dash_profile, + const MpdOptions& mpd_options, + const std::vector& base_urls, + const std::string& output_path) OVERRIDE { + return scoped_ptr(new DashIopMpdNotifier( + dash_profile, mpd_options, base_urls, output_path)); } +}; - return true; -} +// Factory that creates SimpleMpdNotifier instances. +class SimpleMpdNotifierFactory : public MpdNotifierFactory { + public: + SimpleMpdNotifierFactory() {} + virtual ~SimpleMpdNotifierFactory() OVERRIDE {} -bool SetMediaInfosToMpdBuilder(const std::list& media_infos, - MpdBuilder* mpd_builder) { - if (media_infos.empty()) { - LOG(ERROR) << "No MediaInfo to generate an MPD."; - return false; + virtual scoped_ptr Create( + DashProfile dash_profile, + const MpdOptions& mpd_options, + const std::vector& base_urls, + const std::string& output_path) OVERRIDE { + return scoped_ptr(new SimpleMpdNotifier( + dash_profile, mpd_options, base_urls, output_path)); } +}; - bool has_video = false; - bool has_audio = false; - bool has_text = false; - if (!HasVideoAudioText(media_infos, &has_video, &has_audio, &has_text)) - return false; - - DCHECK(mpd_builder); - - // [type][lang] = AdaptationSet - std::map > map; - // This puts video sets into the map first, which keeps some pre-existing - // test expectations from changing. - if (has_video) { - map["video"][""] = mpd_builder->AddAdaptationSet(""); - } - - for (std::list::const_iterator it = media_infos.begin(); - it != media_infos.end(); - ++it) { - const MediaInfo& media_info = *it; - DCHECK(OnlyOneTrue(media_info.has_video_info(), - media_info.has_audio_info(), - media_info.has_text_info())); - - std::string lang; - AdaptationSet** adaptation_set = NULL; - if (media_info.has_video_info()) { - adaptation_set = &map["video"][lang]; - } else if (media_info.has_audio_info()) { - lang = media_info.audio_info().language(); - adaptation_set = &map["audio"][lang]; - } else if (media_info.has_text_info()) { - adaptation_set = &map["text"][lang]; - } - if (!*adaptation_set) { - *adaptation_set = mpd_builder->AddAdaptationSet(lang); - } - - Representation* representation = - (*adaptation_set)->AddRepresentation(media_info); - if (!representation) { - LOG(ERROR) << "Failed to add representation."; - return false; - } - } - - return true; -} } // namespace -MpdWriter::MpdWriter() {} +MpdWriter::MpdWriter() + : notifier_factory_(FLAGS_generate_dash_if_iop_compliant_mpd + ? static_cast( + new DashIopMpdNotifierFactory()) + : static_cast( + new SimpleMpdNotifierFactory())) {} MpdWriter::~MpdWriter() {} bool MpdWriter::AddFile(const std::string& media_info_path, @@ -149,66 +98,36 @@ void MpdWriter::AddBaseUrl(const std::string& base_url) { base_urls_.push_back(base_url); } -// NOTE: The only use case we have for this is static profile, i.e. VOD. -bool MpdWriter::WriteMpdToString(std::string* output) { - CHECK(output); - - MpdBuilder mpd_builder(MpdBuilder::kStatic, MpdOptions()); - for (std::list::const_iterator it = base_urls_.begin(); - it != base_urls_.end(); - ++it) { - const std::string& base_url = *it; - mpd_builder.AddBaseUrl(base_url); - } - - if (!SetMediaInfosToMpdBuilder(media_infos_, &mpd_builder)) { - LOG(ERROR) << "Failed to set MediaInfos to MpdBuilder."; - return false; - } - - return mpd_builder.ToString(output); -} - bool MpdWriter::WriteMpdToFile(const char* file_name) { CHECK(file_name); - - std::string mpd; - if (!WriteMpdToString(&mpd)) { - LOG(ERROR) << "Failed to write MPD to string."; + scoped_ptr notifier = notifier_factory_->Create( + kOnDemandProfile, MpdOptions(), base_urls_, file_name); + if (!notifier->Init()) { + LOG(ERROR) << "failed to initialize MpdNotifier."; return false; } - File* file = File::Open(file_name, "w"); - if (!file) { - LOG(ERROR) << "Failed to write MPD to string."; - return false; - } - - const char* mpd_char_ptr = mpd.data(); - size_t mpd_bytes_left = mpd.size(); - while (mpd_bytes_left > 0) { - int64_t length = file->Write(mpd_char_ptr, mpd_bytes_left); - if (length < 0) { - LOG(ERROR) << "Write error " << length; + for (std::list::const_iterator it = media_infos_.begin(); + it != media_infos_.end(); + ++it) { + uint32_t unused_conatiner_id; + if (!notifier->NotifyNewContainer(*it, &unused_conatiner_id)) { + LOG(ERROR) << "Failed to add MediaInfo for media file: " + << it->media_file_name(); return false; } - - if (static_cast(length) > mpd_bytes_left) { - LOG(ERROR) << "Wrote " << length << " bytes but there was only " - << mpd_bytes_left << " bytes to write."; - return false; - } - - mpd_char_ptr += length; - mpd_bytes_left -= length; } - if (!file->Flush()) { - LOG(ERROR) << "Failed to flush file."; + if (!notifier->Flush()) { + LOG(ERROR) << "Failed to flush MPD notifier."; return false; } + return true; +} - return file->Close(); +void MpdWriter::SetMpdNotifierFactoryForTest( + scoped_ptr factory) { + notifier_factory_ = factory.Pass(); } } // namespace edash_packager diff --git a/packager/mpd/util/mpd_writer.h b/packager/mpd/util/mpd_writer.h index bdd523ed83..a4f14ffb40 100644 --- a/packager/mpd/util/mpd_writer.h +++ b/packager/mpd/util/mpd_writer.h @@ -11,8 +11,12 @@ #include #include +#include #include "packager/base/macros.h" +#include "packager/base/memory/scoped_ptr.h" +#include "packager/mpd/base/mpd_notifier.h" +#include "packager/mpd/base/mpd_options.h" namespace edash_packager { namespace media { @@ -24,6 +28,21 @@ namespace edash_packager { class MediaInfo; +/// This is mainly for testing, and is implementation detail. No need to worry +/// about this class if you are just using the API. +/// Inject a factory and mock MpdNotifier to test the MpdWriter implementation. +class MpdNotifierFactory { + public: + MpdNotifierFactory() {} + virtual ~MpdNotifierFactory() {} + + virtual scoped_ptr Create( + DashProfile dash_profile, + const MpdOptions& mpd_options, + const std::vector& base_urls, + const std::string& output_path) = 0; +}; + // An instance of this class takes a set of MediaInfo files and generates an // MPD when one of WriteMpd* methods are called. This generates an MPD with one // element and at most three elements, each for video, @@ -48,13 +67,6 @@ class MpdWriter { // element will be a direct child element of the element. void AddBaseUrl(const std::string& base_url); - // Write the MPD to |output|. |output| should not be NULL. - // AddFile() should be called before calling this function to generate an MPD. - // On success, MPD is set to |output| and returns true, otherwise returns - // false. - // This method can be called multiple times, if necessary. - bool WriteMpdToString(std::string* output); - // Write the MPD to |file_name|. |file_name| should not be NULL. // This opens the file in write mode, IOW if the // file exists this will over write whatever is in the file. @@ -65,8 +77,14 @@ class MpdWriter { bool WriteMpdToFile(const char* file_name); private: + friend class MpdWriterTest; + + void SetMpdNotifierFactoryForTest(scoped_ptr factory); + std::list media_infos_; - std::list base_urls_; + std::vector base_urls_; + + scoped_ptr notifier_factory_; DISALLOW_COPY_AND_ASSIGN(MpdWriter); }; diff --git a/packager/mpd/util/mpd_writer_unittest.cc b/packager/mpd/util/mpd_writer_unittest.cc index 4e77e8e80e..d9e32f5faf 100644 --- a/packager/mpd/util/mpd_writer_unittest.cc +++ b/packager/mpd/util/mpd_writer_unittest.cc @@ -4,121 +4,104 @@ // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd +#include #include #include "packager/base/file_util.h" #include "packager/base/path_service.h" +#include "packager/mpd/base/dash_iop_mpd_notifier.h" +#include "packager/mpd/base/mock_mpd_notifier.h" +#include "packager/mpd/base/mpd_options.h" #include "packager/mpd/test/mpd_builder_test_helper.h" #include "packager/mpd/util/mpd_writer.h" namespace edash_packager { -// Note that these tests look very similar to MpdBuilder tests but these can -// only handle MediaInfos with 1 stream in each file. -TEST(MpdWriterTest, VideoMediaInfo) { - MpdWriter mpd_writer; - base::FilePath media_info_file = GetTestDataFilePath(kFileNameVideoMediaInfo1); +using ::testing::_; +using ::testing::Invoke; +using ::testing::Return; - ASSERT_TRUE(mpd_writer.AddFile(media_info_file.value(), "")); - std::string generated_mpd; - ASSERT_TRUE(mpd_writer.WriteMpdToString(&generated_mpd)); - ASSERT_TRUE(ValidateMpdSchema(generated_mpd)); +namespace { - ASSERT_NO_FATAL_FAILURE(ExpectMpdToEqualExpectedOutputFile( - generated_mpd, - kFileNameExpectedMpdOutputVideo1)); -} +class TestMpdNotifierFactory : public MpdNotifierFactory { + public: + TestMpdNotifierFactory() {} + virtual ~TestMpdNotifierFactory() OVERRIDE {} + + // So sad that this method cannot be mocked (gmock errors at compile time). + // Also (probably) this version of gmock does not support returning + // scoped_ptr. + // For now we only need to return MockMpdNotifier() with these set of + // expectations for all the tests. + virtual scoped_ptr Create( + DashProfile dash_profile, + const MpdOptions& mpd_options, + const std::vector& base_urls, + const std::string& output_path) OVERRIDE { + EXPECT_EQ(expected_base_urls_, base_urls); + + scoped_ptr mock_notifier( + new MockMpdNotifier(kOnDemandProfile)); + + EXPECT_CALL(*mock_notifier, Init()).WillOnce(Return(true)); + EXPECT_CALL(*mock_notifier, NotifyNewContainer(_, _)) + .Times(2) + .WillRepeatedly(Return(true)); + EXPECT_CALL(*mock_notifier, Flush()).WillOnce(Return(true)); + return mock_notifier.PassAs(); + } + + void SetExpectedBaseUrls(const std::vector& base_urls) { + expected_base_urls_ = base_urls; + } + + std::vector expected_base_urls_; +}; + +} // namespace + +class MpdWriterTest : public ::testing::Test { + protected: + // Note that MpdWriter::SetMpdNotifierFactoryForTest() is not called in SetUp. + // Set expectations in the test and call it. + virtual void SetUp() OVERRIDE { + notifier_factory_.reset(new TestMpdNotifierFactory()); + } + + void SetMpdNotifierFactoryForTest() { + mpd_writer_.SetMpdNotifierFactoryForTest( + notifier_factory_.PassAs()); + } + + scoped_ptr notifier_factory_; + MpdWriter mpd_writer_; +}; + +// Verify that writing mpd to a file works. +// Also check that base URLs are passed correctly. +TEST_F(MpdWriterTest, WriteMpdToFile) { + const char kBaseUrl1[] = "http://cdn1.mydomain.com/"; + const char kBaseUrl2[] = "http://cdn2.mydomain.com/"; + std::vector base_urls_; + base_urls_.push_back(kBaseUrl1); + base_urls_.push_back(kBaseUrl2); + + notifier_factory_->SetExpectedBaseUrls(base_urls_); -TEST(MpdWriterTest, TwoVideoMediaInfo) { - MpdWriter mpd_writer; base::FilePath media_info_file1 = GetTestDataFilePath(kFileNameVideoMediaInfo1); base::FilePath media_info_file2 = GetTestDataFilePath(kFileNameVideoMediaInfo2); - ASSERT_TRUE(mpd_writer.AddFile(media_info_file1.value(), "")); - ASSERT_TRUE(mpd_writer.AddFile(media_info_file2.value(), "")); + SetMpdNotifierFactoryForTest(); + EXPECT_TRUE(mpd_writer_.AddFile(media_info_file1.value(), "")); + EXPECT_TRUE(mpd_writer_.AddFile(media_info_file2.value(), "")); + mpd_writer_.AddBaseUrl(kBaseUrl1); + mpd_writer_.AddBaseUrl(kBaseUrl2); - std::string generated_mpd; - ASSERT_TRUE(mpd_writer.WriteMpdToString(&generated_mpd)); - ASSERT_TRUE(ValidateMpdSchema(generated_mpd)); - - ASSERT_NO_FATAL_FAILURE(ExpectMpdToEqualExpectedOutputFile( - generated_mpd, - kFileNameExpectedMpdOutputVideo1And2)); -} - -TEST(MpdWriterTest, AudioMediaInfo) { - MpdWriter mpd_writer; - base::FilePath media_info_file = GetTestDataFilePath(kFileNameAudioMediaInfo1); - - ASSERT_TRUE(mpd_writer.AddFile(media_info_file.value(), "")); - std::string generated_mpd; - ASSERT_TRUE(mpd_writer.WriteMpdToString(&generated_mpd)); - ASSERT_TRUE(ValidateMpdSchema(generated_mpd)); - - ASSERT_NO_FATAL_FAILURE(ExpectMpdToEqualExpectedOutputFile( - generated_mpd, - kFileNameExpectedMpdOutputAudio1)); -} - -TEST(MpdWriterTest, VideoAudioMediaInfo) { - MpdWriter mpd_writer; - base::FilePath audio_media_info = - GetTestDataFilePath(kFileNameAudioMediaInfo1); - base::FilePath video_media_info = - GetTestDataFilePath(kFileNameVideoMediaInfo1); - - ASSERT_TRUE(mpd_writer.AddFile(audio_media_info.value(), "")); - ASSERT_TRUE(mpd_writer.AddFile(video_media_info.value(), "")); - - std::string generated_mpd; - ASSERT_TRUE(mpd_writer.WriteMpdToString(&generated_mpd)); - ASSERT_TRUE(ValidateMpdSchema(generated_mpd)); - - ASSERT_NO_FATAL_FAILURE(ExpectMpdToEqualExpectedOutputFile( - generated_mpd, - kFileNameExpectedMpdOutputAudio1AndVideo1)); -} - -TEST(MpdWriterTest, EncryptedAudioMediaInfo) { - MpdWriter mpd_writer; - base::FilePath encrypted_audio_media_info = - GetTestDataFilePath(kFileNameEncytpedAudioMediaInfo); - - ASSERT_TRUE(mpd_writer.AddFile(encrypted_audio_media_info.value(), "")); - - std::string generated_mpd; - ASSERT_TRUE(mpd_writer.WriteMpdToString(&generated_mpd)); - ASSERT_TRUE(ValidateMpdSchema(generated_mpd)); - - ASSERT_NO_FATAL_FAILURE(ExpectMpdToEqualExpectedOutputFile( - generated_mpd, kFileNameExpectedMpdOutputEncryptedAudio)); -} - -TEST(MpdWriterTest, LanguageMediaInfo) { - MpdWriter mpd_writer; - base::FilePath audio_media_info1 = - GetTestDataFilePath(kFileNameLanguageAudioMediaInfo1); - base::FilePath audio_media_info2 = - GetTestDataFilePath(kFileNameLanguageAudioMediaInfo2); - base::FilePath audio_media_info3 = - GetTestDataFilePath(kFileNameLanguageAudioMediaInfo3); - base::FilePath video_media_info1 = - GetTestDataFilePath(kFileNameLanguageVideoMediaInfo1); - - ASSERT_TRUE(mpd_writer.AddFile(audio_media_info1.value(), "")); - ASSERT_TRUE(mpd_writer.AddFile(audio_media_info2.value(), "")); - ASSERT_TRUE(mpd_writer.AddFile(audio_media_info3.value(), "")); - ASSERT_TRUE(mpd_writer.AddFile(video_media_info1.value(), "")); - - std::string generated_mpd; - ASSERT_TRUE(mpd_writer.WriteMpdToString(&generated_mpd)); - ASSERT_TRUE(ValidateMpdSchema(generated_mpd)); - - ASSERT_NO_FATAL_FAILURE(ExpectMpdToEqualExpectedOutputFile( - generated_mpd, - kFileNameExpectedMpdOutputLanguageAudio)); + base::FilePath mpd_file_path; + ASSERT_TRUE(base::CreateTemporaryFile(&mpd_file_path)); + EXPECT_TRUE(mpd_writer_.WriteMpdToFile(mpd_file_path.value().c_str())); } } // namespace edash_packager