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
This commit is contained in:
parent
3a5fdd2d9c
commit
6a7b32641a
|
@ -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',
|
||||
|
|
|
@ -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<uint8_t>& new_key_id,
|
||||
const std::vector<uint8_t>& new_pssh));
|
||||
MOCK_METHOD2(
|
||||
AddContentProtectionElement,
|
||||
bool(uint32_t container_id,
|
||||
const ContentProtectionElement& content_protection_element));
|
||||
MOCK_METHOD0(Flush, bool());
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace media {
|
||||
|
|
|
@ -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
|
|
@ -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 <gmock/gmock.h>
|
||||
|
||||
#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<uint8_t>& new_key_id,
|
||||
const std::vector<uint8_t>& 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_
|
|
@ -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',
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -6,12 +6,24 @@
|
|||
|
||||
#include "packager/mpd/util/mpd_writer.h"
|
||||
|
||||
#include <gflags/gflags.h>
|
||||
#include <google/protobuf/text_format.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#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<MediaInfo>& 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<MediaInfo>::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;
|
||||
virtual scoped_ptr<MpdNotifier> Create(
|
||||
DashProfile dash_profile,
|
||||
const MpdOptions& mpd_options,
|
||||
const std::vector<std::string>& base_urls,
|
||||
const std::string& output_path) OVERRIDE {
|
||||
return scoped_ptr<MpdNotifier>(new DashIopMpdNotifier(
|
||||
dash_profile, mpd_options, base_urls, output_path));
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
// Factory that creates SimpleMpdNotifier instances.
|
||||
class SimpleMpdNotifierFactory : public MpdNotifierFactory {
|
||||
public:
|
||||
SimpleMpdNotifierFactory() {}
|
||||
virtual ~SimpleMpdNotifierFactory() OVERRIDE {}
|
||||
|
||||
virtual scoped_ptr<MpdNotifier> Create(
|
||||
DashProfile dash_profile,
|
||||
const MpdOptions& mpd_options,
|
||||
const std::vector<std::string>& base_urls,
|
||||
const std::string& output_path) OVERRIDE {
|
||||
return scoped_ptr<MpdNotifier>(new SimpleMpdNotifier(
|
||||
dash_profile, mpd_options, base_urls, output_path));
|
||||
}
|
||||
};
|
||||
|
||||
*has_video = *has_video || media_info_has_video;
|
||||
*has_audio = *has_audio || media_info_has_audio;
|
||||
*has_text = *has_text || media_info_has_text;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SetMediaInfosToMpdBuilder(const std::list<MediaInfo>& media_infos,
|
||||
MpdBuilder* mpd_builder) {
|
||||
if (media_infos.empty()) {
|
||||
LOG(ERROR) << "No MediaInfo to generate an MPD.";
|
||||
return false;
|
||||
}
|
||||
|
||||
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<std::string, std::map<std::string, AdaptationSet*> > 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<MediaInfo>::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<MpdNotifierFactory*>(
|
||||
new DashIopMpdNotifierFactory())
|
||||
: static_cast<MpdNotifierFactory*>(
|
||||
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<std::string>::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<MpdNotifier> 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.";
|
||||
for (std::list<MediaInfo>::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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
if (!notifier->Flush()) {
|
||||
LOG(ERROR) << "Failed to flush MPD notifier.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (static_cast<size_t>(length) > mpd_bytes_left) {
|
||||
LOG(ERROR) << "Wrote " << length << " bytes but there was only "
|
||||
<< mpd_bytes_left << " bytes to write.";
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
mpd_char_ptr += length;
|
||||
mpd_bytes_left -= length;
|
||||
}
|
||||
|
||||
if (!file->Flush()) {
|
||||
LOG(ERROR) << "Failed to flush file.";
|
||||
return false;
|
||||
}
|
||||
|
||||
return file->Close();
|
||||
void MpdWriter::SetMpdNotifierFactoryForTest(
|
||||
scoped_ptr<MpdNotifierFactory> factory) {
|
||||
notifier_factory_ = factory.Pass();
|
||||
}
|
||||
|
||||
} // namespace edash_packager
|
||||
|
|
|
@ -11,8 +11,12 @@
|
|||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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<MpdNotifier> Create(
|
||||
DashProfile dash_profile,
|
||||
const MpdOptions& mpd_options,
|
||||
const std::vector<std::string>& 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
|
||||
// <Period> element and at most three <AdaptationSet> elements, each for video,
|
||||
|
@ -48,13 +67,6 @@ class MpdWriter {
|
|||
// element will be a direct child element of the <MPD> 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<MpdNotifierFactory> factory);
|
||||
|
||||
std::list<MediaInfo> media_infos_;
|
||||
std::list<std::string> base_urls_;
|
||||
std::vector<std::string> base_urls_;
|
||||
|
||||
scoped_ptr<MpdNotifierFactory> notifier_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MpdWriter);
|
||||
};
|
||||
|
|
|
@ -4,121 +4,104 @@
|
|||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#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<MpdNotifier> Create(
|
||||
DashProfile dash_profile,
|
||||
const MpdOptions& mpd_options,
|
||||
const std::vector<std::string>& base_urls,
|
||||
const std::string& output_path) OVERRIDE {
|
||||
EXPECT_EQ(expected_base_urls_, base_urls);
|
||||
|
||||
scoped_ptr<MockMpdNotifier> 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<MpdNotifier>();
|
||||
}
|
||||
|
||||
TEST(MpdWriterTest, TwoVideoMediaInfo) {
|
||||
MpdWriter mpd_writer;
|
||||
void SetExpectedBaseUrls(const std::vector<std::string>& base_urls) {
|
||||
expected_base_urls_ = base_urls;
|
||||
}
|
||||
|
||||
std::vector<std::string> 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<MpdNotifierFactory>());
|
||||
}
|
||||
|
||||
scoped_ptr<TestMpdNotifierFactory> 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<std::string> base_urls_;
|
||||
base_urls_.push_back(kBaseUrl1);
|
||||
base_urls_.push_back(kBaseUrl2);
|
||||
|
||||
notifier_factory_->SetExpectedBaseUrls(base_urls_);
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue