Make MediaPlaylist accept HlsParams as contructor param

And for HlsNotifier and SimpleHlsNotifier as well.

This will make it easier to add preserve_segments_outside_live_window
param in a later CL.

Change-Id: I86d464fe247e04574158a0a76e39d8a122960ae4
This commit is contained in:
KongQun Yang 2018-04-13 18:26:02 -07:00
parent adc9549e2d
commit 60d7a4b2d5
11 changed files with 318 additions and 331 deletions

View File

@ -19,8 +19,7 @@ namespace hls {
// TODO(rkuroiwa): Consider merging this with MpdNotifier. // TODO(rkuroiwa): Consider merging this with MpdNotifier.
class HlsNotifier { class HlsNotifier {
public: public:
explicit HlsNotifier(HlsPlaylistType playlist_type) explicit HlsNotifier(const HlsParams& hls_params) : hls_params_(hls_params) {}
: playlist_type_(playlist_type) {}
virtual ~HlsNotifier() {} virtual ~HlsNotifier() {}
/// Intialize the notifier. /// Intialize the notifier.
@ -92,11 +91,11 @@ class HlsNotifier {
/// @return true on success, false otherwise. /// @return true on success, false otherwise.
virtual bool Flush() = 0; virtual bool Flush() = 0;
/// @return the playlist type. /// @return The HLS parameters.
HlsPlaylistType playlist_type() const { return playlist_type_; } const HlsParams& hls_params() const { return hls_params_; }
private: private:
HlsPlaylistType playlist_type_; const HlsParams hls_params_;
}; };
} // namespace hls } // namespace hls

View File

@ -31,7 +31,6 @@ const char kDefaultMasterPlaylistName[] = "playlist.m3u8";
const char kDefaultLanguage[] = "en"; const char kDefaultLanguage[] = "en";
const uint32_t kWidth = 800; const uint32_t kWidth = 800;
const uint32_t kHeight = 600; const uint32_t kHeight = 600;
const HlsPlaylistType kVodPlaylist = HlsPlaylistType::kVod;
std::unique_ptr<MockMediaPlaylist> CreateVideoPlaylist( std::unique_ptr<MockMediaPlaylist> CreateVideoPlaylist(
const std::string& filename, const std::string& filename,
@ -41,7 +40,7 @@ std::unique_ptr<MockMediaPlaylist> CreateVideoPlaylist(
const char kNoGroup[] = ""; const char kNoGroup[] = "";
std::unique_ptr<MockMediaPlaylist> playlist( std::unique_ptr<MockMediaPlaylist> playlist(
new MockMediaPlaylist(kVodPlaylist, filename, kNoName, kNoGroup)); new MockMediaPlaylist(filename, kNoName, kNoGroup));
playlist->SetStreamTypeForTesting( playlist->SetStreamTypeForTesting(
MediaPlaylist::MediaPlaylistStreamType::kVideo); MediaPlaylist::MediaPlaylistStreamType::kVideo);
@ -76,7 +75,7 @@ std::unique_ptr<MockMediaPlaylist> CreateAudioPlaylist(
uint64_t channels, uint64_t channels,
uint64_t bitrate) { uint64_t bitrate) {
std::unique_ptr<MockMediaPlaylist> playlist( std::unique_ptr<MockMediaPlaylist> playlist(
new MockMediaPlaylist(kVodPlaylist, filename, name, group)); new MockMediaPlaylist(filename, name, group));
EXPECT_CALL(*playlist, GetNumChannels()).WillRepeatedly(Return(channels)); EXPECT_CALL(*playlist, GetNumChannels()).WillRepeatedly(Return(channels));
@ -100,7 +99,7 @@ std::unique_ptr<MockMediaPlaylist> CreateTextPlaylist(
const std::string& codec, const std::string& codec,
const std::string& language) { const std::string& language) {
std::unique_ptr<MockMediaPlaylist> playlist( std::unique_ptr<MockMediaPlaylist> playlist(
new MockMediaPlaylist(kVodPlaylist, filename, name, group)); new MockMediaPlaylist(filename, name, group));
playlist->SetStreamTypeForTesting( playlist->SetStreamTypeForTesting(
MediaPlaylist::MediaPlaylistStreamType::kSubtitle); MediaPlaylist::MediaPlaylistStreamType::kSubtitle);

View File

@ -321,13 +321,11 @@ double LatestSegmentStartTime(
HlsEntry::HlsEntry(HlsEntry::EntryType type) : type_(type) {} HlsEntry::HlsEntry(HlsEntry::EntryType type) : type_(type) {}
HlsEntry::~HlsEntry() {} HlsEntry::~HlsEntry() {}
MediaPlaylist::MediaPlaylist(HlsPlaylistType playlist_type, MediaPlaylist::MediaPlaylist(const HlsParams& hls_params,
double time_shift_buffer_depth,
const std::string& file_name, const std::string& file_name,
const std::string& name, const std::string& name,
const std::string& group_id) const std::string& group_id)
: playlist_type_(playlist_type), : hls_params_(hls_params),
time_shift_buffer_depth_(time_shift_buffer_depth),
file_name_(file_name), file_name_(file_name),
name_(name), name_(name),
group_id_(group_id) {} group_id_(group_id) {}
@ -440,7 +438,8 @@ void MediaPlaylist::AddPlacementOpportunity() {
} }
bool MediaPlaylist::WriteToFile(const std::string& file_path) { bool MediaPlaylist::WriteToFile(const std::string& file_path) {
if (!key_frames_.empty() && playlist_type_ == HlsPlaylistType::kVod) { if (!key_frames_.empty() &&
hls_params_.playlist_type == HlsPlaylistType::kVod) {
// Flush remaining key frames. This assumes |WriteToFile| is only called // Flush remaining key frames. This assumes |WriteToFile| is only called
// once at the end of the file in VOD. // once at the end of the file in VOD.
CHECK_EQ(key_frames_.size(), 1u); CHECK_EQ(key_frames_.size(), 1u);
@ -456,13 +455,13 @@ bool MediaPlaylist::WriteToFile(const std::string& file_path) {
} }
std::string content = CreatePlaylistHeader( std::string content = CreatePlaylistHeader(
media_info_, target_duration_, playlist_type_, stream_type_, media_info_, target_duration_, hls_params_.playlist_type, stream_type_,
media_sequence_number_, discontinuity_sequence_number_); media_sequence_number_, discontinuity_sequence_number_);
for (const auto& entry : entries_) for (const auto& entry : entries_)
base::StringAppendF(&content, "%s\n", entry->ToString().c_str()); base::StringAppendF(&content, "%s\n", entry->ToString().c_str());
if (playlist_type_ == HlsPlaylistType::kVod) { if (hls_params_.playlist_type == HlsPlaylistType::kVod) {
content += "#EXT-X-ENDLIST\n"; content += "#EXT-X-ENDLIST\n";
} }
@ -550,8 +549,8 @@ void MediaPlaylist::AddSegmentInfoEntry(const std::string& segment_file_name,
void MediaPlaylist::SlideWindow() { void MediaPlaylist::SlideWindow() {
DCHECK(!entries_.empty()); DCHECK(!entries_.empty());
if (time_shift_buffer_depth_ <= 0.0 || if (hls_params_.time_shift_buffer_depth <= 0.0 ||
playlist_type_ != HlsPlaylistType::kLive) { hls_params_.playlist_type != HlsPlaylistType::kLive) {
return; return;
} }
DCHECK_GT(time_scale_, 0u); DCHECK_GT(time_scale_, 0u);
@ -559,10 +558,11 @@ void MediaPlaylist::SlideWindow() {
// The start time of the latest segment is considered the current_play_time, // 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. // and this should guarantee that the latest segment will stay in the list.
const double current_play_time = LatestSegmentStartTime(entries_); const double current_play_time = LatestSegmentStartTime(entries_);
if (current_play_time <= time_shift_buffer_depth_) if (current_play_time <= hls_params_.time_shift_buffer_depth)
return; return;
const double timeshift_limit = current_play_time - time_shift_buffer_depth_; const double timeshift_limit =
current_play_time - hls_params_.time_shift_buffer_depth;
// Temporary list to hold the EXT-X-KEYs. For example, this allows us to // Temporary list to hold the EXT-X-KEYs. For example, this allows us to
// remove <3> without removing <1> and <2> below (<1> and <2> are moved to the // remove <3> without removing <1> and <2> below (<1> and <2> are moved to the

View File

@ -58,17 +58,14 @@ class MediaPlaylist {
kSampleAesCenc, // 'cenc' encrypted content. kSampleAesCenc, // 'cenc' encrypted content.
}; };
/// @param playlist_type is the type of this media playlist. /// @param hls_params contains HLS parameters.
/// @param time_shift_buffer_depth determines the duration of the time
/// shifting buffer, only for live HLS.
/// @param file_name is the file name of this media playlist. /// @param file_name is the file name of this media playlist.
/// @param name is the name of this playlist. In other words this is the /// @param name is the name of this playlist. In other words this is the
/// value of the NAME attribute for EXT-X-MEDIA. This is not /// value of the NAME attribute for EXT-X-MEDIA. This is not
/// necessarily the same as @a file_name. /// necessarily the same as @a file_name.
/// @param group_id is the group ID for this playlist. This is the value of /// @param group_id is the group ID for this playlist. This is the value of
/// GROUP-ID attribute for EXT-X-MEDIA. /// GROUP-ID attribute for EXT-X-MEDIA.
MediaPlaylist(HlsPlaylistType playlist_type, MediaPlaylist(const HlsParams& hls_params,
double time_shift_buffer_depth,
const std::string& file_name, const std::string& file_name,
const std::string& name, const std::string& name,
const std::string& group_id); const std::string& group_id);
@ -192,8 +189,7 @@ class MediaPlaylist {
// |sequence_number_| by the number of segments removed. // |sequence_number_| by the number of segments removed.
void SlideWindow(); void SlideWindow();
const HlsPlaylistType playlist_type_; const HlsParams hls_params_;
const double time_shift_buffer_depth_;
// Mainly for MasterPlaylist to use these values. // Mainly for MasterPlaylist to use these values.
const std::string file_name_; const std::string file_name_;
const std::string name_; const std::string name_;

View File

@ -41,12 +41,13 @@ class MediaPlaylistTest : public ::testing::Test {
MediaPlaylistTest(HlsPlaylistType type) MediaPlaylistTest(HlsPlaylistType type)
: default_file_name_(kDefaultPlaylistFileName), : default_file_name_(kDefaultPlaylistFileName),
default_name_("default_name"), default_name_("default_name"),
default_group_id_("default_group_id"), default_group_id_("default_group_id") {
media_playlist_(type, HlsParams hls_params;
kTimeShiftBufferDepth, hls_params.playlist_type = type;
default_file_name_, hls_params.time_shift_buffer_depth = kTimeShiftBufferDepth;
default_name_, media_playlist_.reset(new MediaPlaylist(hls_params, default_file_name_,
default_group_id_) {} default_name_, default_group_id_));
}
void SetUp() override { void SetUp() override {
SetPackagerVersionForTesting("test"); SetPackagerVersionForTesting("test");
@ -67,7 +68,7 @@ class MediaPlaylistTest : public ::testing::Test {
const std::string default_file_name_; const std::string default_file_name_;
const std::string default_name_; const std::string default_name_;
const std::string default_group_id_; const std::string default_group_id_;
MediaPlaylist media_playlist_; std::unique_ptr<MediaPlaylist> media_playlist_;
MediaInfo valid_video_media_info_; MediaInfo valid_video_media_info_;
}; };
@ -96,7 +97,7 @@ class MediaPlaylistSingleSegmentTest : public MediaPlaylistTest {
// Verify that SetMediaInfo() fails if timescale is not present. // Verify that SetMediaInfo() fails if timescale is not present.
TEST_F(MediaPlaylistMultiSegmentTest, NoTimeScale) { TEST_F(MediaPlaylistMultiSegmentTest, NoTimeScale) {
MediaInfo media_info; MediaInfo media_info;
EXPECT_FALSE(media_playlist_.SetMediaInfo(media_info)); EXPECT_FALSE(media_playlist_->SetMediaInfo(media_info));
} }
TEST_F(MediaPlaylistMultiSegmentTest, SetMediaInfoText) { TEST_F(MediaPlaylistMultiSegmentTest, SetMediaInfoText) {
@ -104,7 +105,7 @@ TEST_F(MediaPlaylistMultiSegmentTest, SetMediaInfoText) {
media_info.set_reference_time_scale(kTimeScale); media_info.set_reference_time_scale(kTimeScale);
MediaInfo::TextInfo* text_info = media_info.mutable_text_info(); MediaInfo::TextInfo* text_info = media_info.mutable_text_info();
text_info->set_codec("wvtt"); text_info->set_codec("wvtt");
EXPECT_TRUE(media_playlist_.SetMediaInfo(media_info)); EXPECT_TRUE(media_playlist_->SetMediaInfo(media_info));
} }
TEST_F(MediaPlaylistMultiSegmentTest, SetMediaInfo) { TEST_F(MediaPlaylistMultiSegmentTest, SetMediaInfo) {
@ -113,13 +114,13 @@ TEST_F(MediaPlaylistMultiSegmentTest, SetMediaInfo) {
MediaInfo::VideoInfo* video_info = media_info.mutable_video_info(); MediaInfo::VideoInfo* video_info = media_info.mutable_video_info();
video_info->set_width(1280); video_info->set_width(1280);
video_info->set_height(720); video_info->set_height(720);
EXPECT_TRUE(media_playlist_.SetMediaInfo(media_info)); EXPECT_TRUE(media_playlist_->SetMediaInfo(media_info));
} }
// Verify that AddSegment works (not crash). // Verify that AddSegment works (not crash).
TEST_F(MediaPlaylistMultiSegmentTest, AddSegment) { TEST_F(MediaPlaylistMultiSegmentTest, AddSegment) {
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
media_playlist_.AddSegment("file1.ts", 900000, 0, kZeroByteOffset, 1000000); media_playlist_->AddSegment("file1.ts", 900000, 0, kZeroByteOffset, 1000000);
} }
// Verify that it returns the display resolution. // Verify that it returns the display resolution.
@ -132,10 +133,10 @@ TEST_F(MediaPlaylistMultiSegmentTest, GetDisplayResolution) {
video_info->set_height(818); video_info->set_height(818);
video_info->set_pixel_width(1636); video_info->set_pixel_width(1636);
video_info->set_pixel_height(1635); video_info->set_pixel_height(1635);
ASSERT_TRUE(media_playlist_.SetMediaInfo(media_info)); ASSERT_TRUE(media_playlist_->SetMediaInfo(media_info));
uint32_t width = 0; uint32_t width = 0;
uint32_t height = 0; uint32_t height = 0;
EXPECT_TRUE(media_playlist_.GetDisplayResolution(&width, &height)); EXPECT_TRUE(media_playlist_->GetDisplayResolution(&width, &height));
EXPECT_EQ(1921u, width); EXPECT_EQ(1921u, width);
EXPECT_EQ(818u, height); EXPECT_EQ(818u, height);
} }
@ -154,9 +155,9 @@ TEST_F(MediaPlaylistSingleSegmentTest, InitRange) {
valid_video_media_info_.mutable_init_range()->set_begin(0); valid_video_media_info_.mutable_init_range()->set_begin(0);
valid_video_media_info_.mutable_init_range()->set_end(500); valid_video_media_info_.mutable_init_range()->set_end(500);
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
const char kMemoryFilePath[] = "memory://media.m3u8"; const char kMemoryFilePath[] = "memory://media.m3u8";
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath)); EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput); ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
} }
@ -174,9 +175,9 @@ TEST_F(MediaPlaylistSingleSegmentTest, InitRangeWithOffset) {
valid_video_media_info_.mutable_init_range()->set_begin(16); valid_video_media_info_.mutable_init_range()->set_begin(16);
valid_video_media_info_.mutable_init_range()->set_end(500); valid_video_media_info_.mutable_init_range()->set_end(500);
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
const char kMemoryFilePath[] = "memory://media.m3u8"; const char kMemoryFilePath[] = "memory://media.m3u8";
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath)); EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput); ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
} }
@ -203,26 +204,27 @@ TEST_F(MediaPlaylistSingleSegmentTest, AddSegmentByteRange) {
valid_video_media_info_.mutable_init_range()->set_begin(0); valid_video_media_info_.mutable_init_range()->set_begin(0);
valid_video_media_info_.mutable_init_range()->set_end(500); valid_video_media_info_.mutable_init_range()->set_end(500);
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
media_playlist_.AddSegment("file.mp4", 0, 10 * kTimeScale, 1000, 1 * kMBytes); media_playlist_->AddSegment("file.mp4", 0, 10 * kTimeScale, 1000,
media_playlist_.AddSegment("file.mp4", 10 * kTimeScale, 10 * kTimeScale, 1 * kMBytes);
media_playlist_->AddSegment("file.mp4", 10 * kTimeScale, 10 * kTimeScale,
1001000, 2 * kMBytes); 1001000, 2 * kMBytes);
const char kMemoryFilePath[] = "memory://media.m3u8"; const char kMemoryFilePath[] = "memory://media.m3u8";
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath)); EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput); ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
} }
// Verify that AddEncryptionInfo works (not crash). // Verify that AddEncryptionInfo works (not crash).
TEST_F(MediaPlaylistMultiSegmentTest, AddEncryptionInfo) { TEST_F(MediaPlaylistMultiSegmentTest, AddEncryptionInfo) {
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
media_playlist_.AddEncryptionInfo(MediaPlaylist::EncryptionMethod::kSampleAes, media_playlist_->AddEncryptionInfo(
"http://example.com", "", "0xabcedf", "", MediaPlaylist::EncryptionMethod::kSampleAes, "http://example.com", "",
""); "0xabcedf", "", "");
} }
TEST_F(MediaPlaylistMultiSegmentTest, WriteToFile) { TEST_F(MediaPlaylistMultiSegmentTest, WriteToFile) {
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
const char kExpectedOutput[] = const char kExpectedOutput[] =
"#EXTM3U\n" "#EXTM3U\n"
"#EXT-X-VERSION:6\n" "#EXT-X-VERSION:6\n"
@ -233,48 +235,48 @@ TEST_F(MediaPlaylistMultiSegmentTest, WriteToFile) {
"#EXT-X-ENDLIST\n"; "#EXT-X-ENDLIST\n";
const char kMemoryFilePath[] = "memory://media.m3u8"; const char kMemoryFilePath[] = "memory://media.m3u8";
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath)); EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput); ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
} }
// If bitrate (bandwidth) is not set in the MediaInfo, use it. // If bitrate (bandwidth) is not set in the MediaInfo, use it.
TEST_F(MediaPlaylistMultiSegmentTest, UseBitrateInMediaInfo) { TEST_F(MediaPlaylistMultiSegmentTest, UseBitrateInMediaInfo) {
valid_video_media_info_.set_bandwidth(8191); valid_video_media_info_.set_bandwidth(8191);
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
EXPECT_EQ(8191u, media_playlist_.Bitrate()); EXPECT_EQ(8191u, media_playlist_->Bitrate());
} }
// If bitrate (bandwidth) is not set in the MediaInfo, then calculate from the // If bitrate (bandwidth) is not set in the MediaInfo, then calculate from the
// segments. // segments.
TEST_F(MediaPlaylistMultiSegmentTest, GetBitrateFromSegments) { TEST_F(MediaPlaylistMultiSegmentTest, GetBitrateFromSegments) {
valid_video_media_info_.clear_bandwidth(); valid_video_media_info_.clear_bandwidth();
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
media_playlist_.AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset, media_playlist_->AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset,
kMBytes); kMBytes);
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 20 * kTimeScale, media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 20 * kTimeScale,
kZeroByteOffset, 5 * kMBytes); kZeroByteOffset, 5 * kMBytes);
// Max bitrate is 2000Kb/s. // Max bitrate is 2000Kb/s.
EXPECT_EQ(2000000u, media_playlist_.Bitrate()); EXPECT_EQ(2000000u, media_playlist_->Bitrate());
} }
TEST_F(MediaPlaylistMultiSegmentTest, GetLongestSegmentDuration) { TEST_F(MediaPlaylistMultiSegmentTest, GetLongestSegmentDuration) {
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
media_playlist_.AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset, media_playlist_->AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset,
kMBytes); kMBytes);
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale, media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
kZeroByteOffset, 5 * kMBytes); kZeroByteOffset, 5 * kMBytes);
media_playlist_.AddSegment("file3.ts", 40 * kTimeScale, 14 * kTimeScale, media_playlist_->AddSegment("file3.ts", 40 * kTimeScale, 14 * kTimeScale,
kZeroByteOffset, 3 * kMBytes); kZeroByteOffset, 3 * kMBytes);
EXPECT_NEAR(30.0, media_playlist_.GetLongestSegmentDuration(), 0.01); EXPECT_NEAR(30.0, media_playlist_->GetLongestSegmentDuration(), 0.01);
} }
TEST_F(MediaPlaylistMultiSegmentTest, SetTargetDuration) { TEST_F(MediaPlaylistMultiSegmentTest, SetTargetDuration) {
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
media_playlist_.SetTargetDuration(20); media_playlist_->SetTargetDuration(20);
const std::string kExpectedOutput = const std::string kExpectedOutput =
"#EXTM3U\n" "#EXTM3U\n"
"#EXT-X-VERSION:6\n" "#EXT-X-VERSION:6\n"
@ -285,17 +287,17 @@ TEST_F(MediaPlaylistMultiSegmentTest, SetTargetDuration) {
"#EXT-X-ENDLIST\n"; "#EXT-X-ENDLIST\n";
const char kMemoryFilePath[] = "memory://media.m3u8"; const char kMemoryFilePath[] = "memory://media.m3u8";
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath)); EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput); ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
} }
TEST_F(MediaPlaylistMultiSegmentTest, WriteToFileWithSegments) { TEST_F(MediaPlaylistMultiSegmentTest, WriteToFileWithSegments) {
valid_video_media_info_.set_reference_time_scale(90000); valid_video_media_info_.set_reference_time_scale(90000);
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
media_playlist_.AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset, media_playlist_->AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset,
kMBytes); kMBytes);
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale, media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
kZeroByteOffset, 5 * kMBytes); kZeroByteOffset, 5 * kMBytes);
const char kExpectedOutput[] = const char kExpectedOutput[] =
"#EXTM3U\n" "#EXTM3U\n"
@ -311,19 +313,19 @@ TEST_F(MediaPlaylistMultiSegmentTest, WriteToFileWithSegments) {
"#EXT-X-ENDLIST\n"; "#EXT-X-ENDLIST\n";
const char kMemoryFilePath[] = "memory://media.m3u8"; const char kMemoryFilePath[] = "memory://media.m3u8";
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath)); EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput); ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
} }
TEST_F(MediaPlaylistMultiSegmentTest, TEST_F(MediaPlaylistMultiSegmentTest,
WriteToFileWithSegmentsAndPlacementOpportunity) { WriteToFileWithSegmentsAndPlacementOpportunity) {
valid_video_media_info_.set_reference_time_scale(90000); valid_video_media_info_.set_reference_time_scale(90000);
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
media_playlist_.AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset, media_playlist_->AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset,
kMBytes); kMBytes);
media_playlist_.AddPlacementOpportunity(); media_playlist_->AddPlacementOpportunity();
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale, media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
kZeroByteOffset, 5 * kMBytes); kZeroByteOffset, 5 * kMBytes);
const char kExpectedOutput[] = const char kExpectedOutput[] =
"#EXTM3U\n" "#EXTM3U\n"
@ -340,20 +342,20 @@ TEST_F(MediaPlaylistMultiSegmentTest,
"#EXT-X-ENDLIST\n"; "#EXT-X-ENDLIST\n";
const char kMemoryFilePath[] = "memory://media.m3u8"; const char kMemoryFilePath[] = "memory://media.m3u8";
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath)); EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput); ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
} }
TEST_F(MediaPlaylistMultiSegmentTest, WriteToFileWithEncryptionInfo) { TEST_F(MediaPlaylistMultiSegmentTest, WriteToFileWithEncryptionInfo) {
valid_video_media_info_.set_reference_time_scale(90000); valid_video_media_info_.set_reference_time_scale(90000);
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
media_playlist_.AddEncryptionInfo(MediaPlaylist::EncryptionMethod::kSampleAes, media_playlist_->AddEncryptionInfo(
"http://example.com", "", "0x12345678", MediaPlaylist::EncryptionMethod::kSampleAes, "http://example.com", "",
"com.widevine", "1/2/4"); "0x12345678", "com.widevine", "1/2/4");
media_playlist_.AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset, media_playlist_->AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset,
kMBytes); kMBytes);
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale, media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
kZeroByteOffset, 5 * kMBytes); kZeroByteOffset, 5 * kMBytes);
const char kExpectedOutput[] = const char kExpectedOutput[] =
"#EXTM3U\n" "#EXTM3U\n"
@ -372,20 +374,20 @@ TEST_F(MediaPlaylistMultiSegmentTest, WriteToFileWithEncryptionInfo) {
"#EXT-X-ENDLIST\n"; "#EXT-X-ENDLIST\n";
const char kMemoryFilePath[] = "memory://media.m3u8"; const char kMemoryFilePath[] = "memory://media.m3u8";
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath)); EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput); ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
} }
TEST_F(MediaPlaylistMultiSegmentTest, WriteToFileWithEncryptionInfoEmptyIv) { TEST_F(MediaPlaylistMultiSegmentTest, WriteToFileWithEncryptionInfoEmptyIv) {
valid_video_media_info_.set_reference_time_scale(90000); valid_video_media_info_.set_reference_time_scale(90000);
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
media_playlist_.AddEncryptionInfo(MediaPlaylist::EncryptionMethod::kSampleAes, media_playlist_->AddEncryptionInfo(
"http://example.com", "", "", MediaPlaylist::EncryptionMethod::kSampleAes, "http://example.com", "", "",
"com.widevine", ""); "com.widevine", "");
media_playlist_.AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset, media_playlist_->AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset,
kMBytes); kMBytes);
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale, media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
kZeroByteOffset, 5 * kMBytes); kZeroByteOffset, 5 * kMBytes);
const char kExpectedOutput[] = const char kExpectedOutput[] =
"#EXTM3U\n" "#EXTM3U\n"
@ -403,22 +405,22 @@ TEST_F(MediaPlaylistMultiSegmentTest, WriteToFileWithEncryptionInfoEmptyIv) {
"#EXT-X-ENDLIST\n"; "#EXT-X-ENDLIST\n";
const char kMemoryFilePath[] = "memory://media.m3u8"; const char kMemoryFilePath[] = "memory://media.m3u8";
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath)); EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput); ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
} }
// Verify that EXT-X-DISCONTINUITY is inserted before EXT-X-KEY. // Verify that EXT-X-DISCONTINUITY is inserted before EXT-X-KEY.
TEST_F(MediaPlaylistMultiSegmentTest, WriteToFileWithClearLead) { TEST_F(MediaPlaylistMultiSegmentTest, WriteToFileWithClearLead) {
valid_video_media_info_.set_reference_time_scale(90000); valid_video_media_info_.set_reference_time_scale(90000);
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
media_playlist_.AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset, media_playlist_->AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset,
kMBytes); kMBytes);
media_playlist_.AddEncryptionInfo(MediaPlaylist::EncryptionMethod::kSampleAes, media_playlist_->AddEncryptionInfo(
"http://example.com", "", "0x12345678", MediaPlaylist::EncryptionMethod::kSampleAes, "http://example.com", "",
"com.widevine", "1/2/4"); "0x12345678", "com.widevine", "1/2/4");
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale, media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
kZeroByteOffset, 5 * kMBytes); kZeroByteOffset, 5 * kMBytes);
const char kExpectedOutput[] = const char kExpectedOutput[] =
"#EXTM3U\n" "#EXTM3U\n"
@ -438,7 +440,7 @@ TEST_F(MediaPlaylistMultiSegmentTest, WriteToFileWithClearLead) {
"#EXT-X-ENDLIST\n"; "#EXT-X-ENDLIST\n";
const char kMemoryFilePath[] = "memory://media.m3u8"; const char kMemoryFilePath[] = "memory://media.m3u8";
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath)); EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput); ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
} }
@ -448,16 +450,16 @@ TEST_F(MediaPlaylistMultiSegmentTest, GetLanguage) {
// Check conversions from long to short form. // Check conversions from long to short form.
media_info.mutable_audio_info()->set_language("eng"); media_info.mutable_audio_info()->set_language("eng");
ASSERT_TRUE(media_playlist_.SetMediaInfo(media_info)); ASSERT_TRUE(media_playlist_->SetMediaInfo(media_info));
EXPECT_EQ("en", media_playlist_.language()); // short form EXPECT_EQ("en", media_playlist_->language()); // short form
media_info.mutable_audio_info()->set_language("eng-US"); media_info.mutable_audio_info()->set_language("eng-US");
ASSERT_TRUE(media_playlist_.SetMediaInfo(media_info)); ASSERT_TRUE(media_playlist_->SetMediaInfo(media_info));
EXPECT_EQ("en-US", media_playlist_.language()); // region preserved EXPECT_EQ("en-US", media_playlist_->language()); // region preserved
media_info.mutable_audio_info()->set_language("apa"); media_info.mutable_audio_info()->set_language("apa");
ASSERT_TRUE(media_playlist_.SetMediaInfo(media_info)); ASSERT_TRUE(media_playlist_->SetMediaInfo(media_info));
EXPECT_EQ("apa", media_playlist_.language()); // no short form exists EXPECT_EQ("apa", media_playlist_->language()); // no short form exists
} }
TEST_F(MediaPlaylistMultiSegmentTest, GetNumChannels) { TEST_F(MediaPlaylistMultiSegmentTest, GetNumChannels) {
@ -465,25 +467,25 @@ TEST_F(MediaPlaylistMultiSegmentTest, GetNumChannels) {
media_info.set_reference_time_scale(kTimeScale); media_info.set_reference_time_scale(kTimeScale);
// Returns 0 by default if not audio. // Returns 0 by default if not audio.
EXPECT_EQ(0, media_playlist_.GetNumChannels()); EXPECT_EQ(0, media_playlist_->GetNumChannels());
media_info.mutable_audio_info()->set_num_channels(2); media_info.mutable_audio_info()->set_num_channels(2);
ASSERT_TRUE(media_playlist_.SetMediaInfo(media_info)); ASSERT_TRUE(media_playlist_->SetMediaInfo(media_info));
EXPECT_EQ(2, media_playlist_.GetNumChannels()); EXPECT_EQ(2, media_playlist_->GetNumChannels());
media_info.mutable_audio_info()->set_num_channels(8); media_info.mutable_audio_info()->set_num_channels(8);
ASSERT_TRUE(media_playlist_.SetMediaInfo(media_info)); ASSERT_TRUE(media_playlist_->SetMediaInfo(media_info));
EXPECT_EQ(8, media_playlist_.GetNumChannels()); EXPECT_EQ(8, media_playlist_->GetNumChannels());
} }
TEST_F(MediaPlaylistMultiSegmentTest, InitSegment) { TEST_F(MediaPlaylistMultiSegmentTest, InitSegment) {
valid_video_media_info_.set_reference_time_scale(90000); valid_video_media_info_.set_reference_time_scale(90000);
valid_video_media_info_.set_init_segment_url("init_segment.mp4"); valid_video_media_info_.set_init_segment_url("init_segment.mp4");
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
media_playlist_.AddSegment("file1.mp4", 0, 10 * kTimeScale, kZeroByteOffset, media_playlist_->AddSegment("file1.mp4", 0, 10 * kTimeScale, kZeroByteOffset,
kMBytes); kMBytes);
media_playlist_.AddSegment("file2.mp4", 10 * kTimeScale, 30 * kTimeScale, media_playlist_->AddSegment("file2.mp4", 10 * kTimeScale, 30 * kTimeScale,
kZeroByteOffset, 5 * kMBytes); kZeroByteOffset, 5 * kMBytes);
const char kExpectedOutput[] = const char kExpectedOutput[] =
@ -501,22 +503,22 @@ TEST_F(MediaPlaylistMultiSegmentTest, InitSegment) {
"#EXT-X-ENDLIST\n"; "#EXT-X-ENDLIST\n";
const char kMemoryFilePath[] = "memory://media.m3u8"; const char kMemoryFilePath[] = "memory://media.m3u8";
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath)); EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput); ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
} }
// Verify that kSampleAesCenc is handled correctly. // Verify that kSampleAesCenc is handled correctly.
TEST_F(MediaPlaylistMultiSegmentTest, SampleAesCenc) { TEST_F(MediaPlaylistMultiSegmentTest, SampleAesCenc) {
valid_video_media_info_.set_reference_time_scale(90000); valid_video_media_info_.set_reference_time_scale(90000);
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
media_playlist_.AddEncryptionInfo( media_playlist_->AddEncryptionInfo(
MediaPlaylist::EncryptionMethod::kSampleAesCenc, "http://example.com", "", MediaPlaylist::EncryptionMethod::kSampleAesCenc, "http://example.com", "",
"0x12345678", "com.widevine", "1/2/4"); "0x12345678", "com.widevine", "1/2/4");
media_playlist_.AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset, media_playlist_->AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset,
kMBytes); kMBytes);
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale, media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
kZeroByteOffset, 5 * kMBytes); kZeroByteOffset, 5 * kMBytes);
const char kExpectedOutput[] = const char kExpectedOutput[] =
"#EXTM3U\n" "#EXTM3U\n"
@ -535,24 +537,24 @@ TEST_F(MediaPlaylistMultiSegmentTest, SampleAesCenc) {
"#EXT-X-ENDLIST\n"; "#EXT-X-ENDLIST\n";
const char kMemoryFilePath[] = "memory://media.m3u8"; const char kMemoryFilePath[] = "memory://media.m3u8";
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath)); EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput); ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
} }
TEST_F(MediaPlaylistMultiSegmentTest, MultipleEncryptionInfo) { TEST_F(MediaPlaylistMultiSegmentTest, MultipleEncryptionInfo) {
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
media_playlist_.AddEncryptionInfo(MediaPlaylist::EncryptionMethod::kSampleAes, media_playlist_->AddEncryptionInfo(
"http://example.com", "", "0x12345678", MediaPlaylist::EncryptionMethod::kSampleAes, "http://example.com", "",
"com.widevine", "1/2/4"); "0x12345678", "com.widevine", "1/2/4");
media_playlist_.AddEncryptionInfo( media_playlist_->AddEncryptionInfo(
MediaPlaylist::EncryptionMethod::kSampleAes, "http://mydomain.com", MediaPlaylist::EncryptionMethod::kSampleAes, "http://mydomain.com",
"0xfedc", "0x12345678", "com.widevine.someother", "1"); "0xfedc", "0x12345678", "com.widevine.someother", "1");
media_playlist_.AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset, media_playlist_->AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset,
kMBytes); kMBytes);
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale, media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
kZeroByteOffset, 5 * kMBytes); kZeroByteOffset, 5 * kMBytes);
const char kExpectedOutput[] = const char kExpectedOutput[] =
"#EXTM3U\n" "#EXTM3U\n"
@ -575,7 +577,7 @@ TEST_F(MediaPlaylistMultiSegmentTest, MultipleEncryptionInfo) {
"#EXT-X-ENDLIST\n"; "#EXT-X-ENDLIST\n";
const char kMemoryFilePath[] = "memory://media.m3u8"; const char kMemoryFilePath[] = "memory://media.m3u8";
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath)); EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput); ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
} }
@ -586,11 +588,11 @@ class LiveMediaPlaylistTest : public MediaPlaylistMultiSegmentTest {
}; };
TEST_F(LiveMediaPlaylistTest, Basic) { TEST_F(LiveMediaPlaylistTest, Basic) {
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
media_playlist_.AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset, media_playlist_->AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset,
kMBytes); kMBytes);
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 20 * kTimeScale, media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 20 * kTimeScale,
kZeroByteOffset, 2 * kMBytes); kZeroByteOffset, 2 * kMBytes);
const char kExpectedOutput[] = const char kExpectedOutput[] =
"#EXTM3U\n" "#EXTM3U\n"
@ -604,18 +606,18 @@ TEST_F(LiveMediaPlaylistTest, Basic) {
"file2.ts\n"; "file2.ts\n";
const char kMemoryFilePath[] = "memory://media.m3u8"; const char kMemoryFilePath[] = "memory://media.m3u8";
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath)); EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput); ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
} }
TEST_F(LiveMediaPlaylistTest, TimeShifted) { TEST_F(LiveMediaPlaylistTest, TimeShifted) {
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
media_playlist_.AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset, media_playlist_->AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset,
kMBytes); kMBytes);
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 20 * kTimeScale, media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 20 * kTimeScale,
kZeroByteOffset, 2 * kMBytes); kZeroByteOffset, 2 * kMBytes);
media_playlist_.AddSegment("file3.ts", 30 * kTimeScale, 20 * kTimeScale, media_playlist_->AddSegment("file3.ts", 30 * kTimeScale, 20 * kTimeScale,
kZeroByteOffset, 2 * kMBytes); kZeroByteOffset, 2 * kMBytes);
const char kExpectedOutput[] = const char kExpectedOutput[] =
"#EXTM3U\n" "#EXTM3U\n"
@ -630,25 +632,25 @@ TEST_F(LiveMediaPlaylistTest, TimeShifted) {
"file3.ts\n"; "file3.ts\n";
const char kMemoryFilePath[] = "memory://media.m3u8"; const char kMemoryFilePath[] = "memory://media.m3u8";
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath)); EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput); ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
} }
TEST_F(LiveMediaPlaylistTest, TimeShiftedWithEncryptionInfo) { TEST_F(LiveMediaPlaylistTest, TimeShiftedWithEncryptionInfo) {
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
media_playlist_.AddEncryptionInfo(MediaPlaylist::EncryptionMethod::kSampleAes, media_playlist_->AddEncryptionInfo(
"http://example.com", "", "0x12345678", MediaPlaylist::EncryptionMethod::kSampleAes, "http://example.com", "",
"com.widevine", "1/2/4"); "0x12345678", "com.widevine", "1/2/4");
media_playlist_.AddEncryptionInfo( media_playlist_->AddEncryptionInfo(
MediaPlaylist::EncryptionMethod::kSampleAes, "http://mydomain.com", MediaPlaylist::EncryptionMethod::kSampleAes, "http://mydomain.com",
"0xfedc", "0x12345678", "com.widevine.someother", "1"); "0xfedc", "0x12345678", "com.widevine.someother", "1");
media_playlist_.AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset, media_playlist_->AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset,
kMBytes); kMBytes);
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 20 * kTimeScale, media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 20 * kTimeScale,
kZeroByteOffset, 2 * kMBytes); kZeroByteOffset, 2 * kMBytes);
media_playlist_.AddSegment("file3.ts", 30 * kTimeScale, 20 * kTimeScale, media_playlist_->AddSegment("file3.ts", 30 * kTimeScale, 20 * kTimeScale,
kZeroByteOffset, 2 * kMBytes); kZeroByteOffset, 2 * kMBytes);
const char kExpectedOutput[] = const char kExpectedOutput[] =
"#EXTM3U\n" "#EXTM3U\n"
@ -670,44 +672,44 @@ TEST_F(LiveMediaPlaylistTest, TimeShiftedWithEncryptionInfo) {
"file3.ts\n"; "file3.ts\n";
const char kMemoryFilePath[] = "memory://media.m3u8"; const char kMemoryFilePath[] = "memory://media.m3u8";
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath)); EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput); ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
} }
TEST_F(LiveMediaPlaylistTest, TimeShiftedWithEncryptionInfoShifted) { TEST_F(LiveMediaPlaylistTest, TimeShiftedWithEncryptionInfoShifted) {
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
media_playlist_.AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset, media_playlist_->AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset,
kMBytes); kMBytes);
media_playlist_.AddEncryptionInfo(MediaPlaylist::EncryptionMethod::kSampleAes, media_playlist_->AddEncryptionInfo(
"http://example.com", "", "0x12345678", MediaPlaylist::EncryptionMethod::kSampleAes, "http://example.com", "",
"com.widevine", "1/2/4"); "0x12345678", "com.widevine", "1/2/4");
media_playlist_.AddEncryptionInfo( media_playlist_->AddEncryptionInfo(
MediaPlaylist::EncryptionMethod::kSampleAes, "http://mydomain.com", MediaPlaylist::EncryptionMethod::kSampleAes, "http://mydomain.com",
"0xfedc", "0x12345678", "com.widevine.someother", "1"); "0xfedc", "0x12345678", "com.widevine.someother", "1");
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 20 * kTimeScale, media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 20 * kTimeScale,
kZeroByteOffset, 2 * kMBytes); kZeroByteOffset, 2 * kMBytes);
media_playlist_.AddEncryptionInfo(MediaPlaylist::EncryptionMethod::kSampleAes, media_playlist_->AddEncryptionInfo(
"http://example.com", "", "0x22345678", MediaPlaylist::EncryptionMethod::kSampleAes, "http://example.com", "",
"com.widevine", "1/2/4"); "0x22345678", "com.widevine", "1/2/4");
media_playlist_.AddEncryptionInfo( media_playlist_->AddEncryptionInfo(
MediaPlaylist::EncryptionMethod::kSampleAes, "http://mydomain.com", MediaPlaylist::EncryptionMethod::kSampleAes, "http://mydomain.com",
"0xfedd", "0x22345678", "com.widevine.someother", "1"); "0xfedd", "0x22345678", "com.widevine.someother", "1");
media_playlist_.AddSegment("file3.ts", 30 * kTimeScale, 20 * kTimeScale, media_playlist_->AddSegment("file3.ts", 30 * kTimeScale, 20 * kTimeScale,
kZeroByteOffset, 2 * kMBytes); kZeroByteOffset, 2 * kMBytes);
media_playlist_.AddEncryptionInfo(MediaPlaylist::EncryptionMethod::kSampleAes, media_playlist_->AddEncryptionInfo(
"http://example.com", "", "0x32345678", MediaPlaylist::EncryptionMethod::kSampleAes, "http://example.com", "",
"com.widevine", "1/2/4"); "0x32345678", "com.widevine", "1/2/4");
media_playlist_.AddEncryptionInfo( media_playlist_->AddEncryptionInfo(
MediaPlaylist::EncryptionMethod::kSampleAes, "http://mydomain.com", MediaPlaylist::EncryptionMethod::kSampleAes, "http://mydomain.com",
"0xfede", "0x32345678", "com.widevine.someother", "1"); "0xfede", "0x32345678", "com.widevine.someother", "1");
media_playlist_.AddSegment("file4.ts", 50 * kTimeScale, 20 * kTimeScale, media_playlist_->AddSegment("file4.ts", 50 * kTimeScale, 20 * kTimeScale,
kZeroByteOffset, 2 * kMBytes); kZeroByteOffset, 2 * kMBytes);
const char kExpectedOutput[] = const char kExpectedOutput[] =
"#EXTM3U\n" "#EXTM3U\n"
@ -737,7 +739,7 @@ TEST_F(LiveMediaPlaylistTest, TimeShiftedWithEncryptionInfoShifted) {
"file4.ts\n"; "file4.ts\n";
const char kMemoryFilePath[] = "memory://media.m3u8"; const char kMemoryFilePath[] = "memory://media.m3u8";
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath)); EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput); ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
} }
@ -748,11 +750,11 @@ class EventMediaPlaylistTest : public MediaPlaylistMultiSegmentTest {
}; };
TEST_F(EventMediaPlaylistTest, Basic) { TEST_F(EventMediaPlaylistTest, Basic) {
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
media_playlist_.AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset, media_playlist_->AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset,
kMBytes); kMBytes);
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 20 * kTimeScale, media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 20 * kTimeScale,
kZeroByteOffset, 2 * kMBytes); kZeroByteOffset, 2 * kMBytes);
const char kExpectedOutput[] = const char kExpectedOutput[] =
"#EXTM3U\n" "#EXTM3U\n"
@ -767,21 +769,21 @@ TEST_F(EventMediaPlaylistTest, Basic) {
"file2.ts\n"; "file2.ts\n";
const char kMemoryFilePath[] = "memory://media.m3u8"; const char kMemoryFilePath[] = "memory://media.m3u8";
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath)); EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput); ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
} }
class IFrameMediaPlaylistTest : public MediaPlaylistTest {}; class IFrameMediaPlaylistTest : public MediaPlaylistTest {};
TEST_F(IFrameMediaPlaylistTest, MediaPlaylistType) { TEST_F(IFrameMediaPlaylistTest, MediaPlaylistType) {
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
EXPECT_EQ(MediaPlaylist::MediaPlaylistStreamType::kVideo, EXPECT_EQ(MediaPlaylist::MediaPlaylistStreamType::kVideo,
media_playlist_.stream_type()); media_playlist_->stream_type());
media_playlist_.AddKeyFrame(0, 1000, 2345); media_playlist_->AddKeyFrame(0, 1000, 2345);
// Playlist stream type is updated to I-Frames only after seeing // Playlist stream type is updated to I-Frames only after seeing
// |AddKeyFrame|. // |AddKeyFrame|.
EXPECT_EQ(MediaPlaylist::MediaPlaylistStreamType::kVideoIFramesOnly, EXPECT_EQ(MediaPlaylist::MediaPlaylistStreamType::kVideoIFramesOnly,
media_playlist_.stream_type()); media_playlist_->stream_type());
} }
TEST_F(IFrameMediaPlaylistTest, SingleSegment) { TEST_F(IFrameMediaPlaylistTest, SingleSegment) {
@ -789,14 +791,14 @@ TEST_F(IFrameMediaPlaylistTest, SingleSegment) {
valid_video_media_info_.mutable_init_range()->set_begin(0); valid_video_media_info_.mutable_init_range()->set_begin(0);
valid_video_media_info_.mutable_init_range()->set_end(500); valid_video_media_info_.mutable_init_range()->set_end(500);
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
media_playlist_.AddKeyFrame(0, 1000, 2345); media_playlist_->AddKeyFrame(0, 1000, 2345);
media_playlist_.AddKeyFrame(2 * kTimeScale, 5000, 6345); media_playlist_->AddKeyFrame(2 * kTimeScale, 5000, 6345);
media_playlist_.AddSegment("file.mp4", 0, 10 * kTimeScale, kZeroByteOffset, media_playlist_->AddSegment("file.mp4", 0, 10 * kTimeScale, kZeroByteOffset,
kMBytes); kMBytes);
media_playlist_.AddKeyFrame(11 * kTimeScale, kMBytes + 1000, 2345); media_playlist_->AddKeyFrame(11 * kTimeScale, kMBytes + 1000, 2345);
media_playlist_.AddKeyFrame(15 * kTimeScale, kMBytes + 3345, 12345); media_playlist_->AddKeyFrame(15 * kTimeScale, kMBytes + 3345, 12345);
media_playlist_.AddSegment("file.mp4", 10 * kTimeScale, 10 * kTimeScale, media_playlist_->AddSegment("file.mp4", 10 * kTimeScale, 10 * kTimeScale,
1001000, 2 * kMBytes); 1001000, 2 * kMBytes);
const char kExpectedOutput[] = const char kExpectedOutput[] =
@ -823,21 +825,22 @@ TEST_F(IFrameMediaPlaylistTest, SingleSegment) {
"#EXT-X-ENDLIST\n"; "#EXT-X-ENDLIST\n";
const char kMemoryFilePath[] = "memory://media.m3u8"; const char kMemoryFilePath[] = "memory://media.m3u8";
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath)); EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput); ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
} }
TEST_F(IFrameMediaPlaylistTest, MultiSegment) { TEST_F(IFrameMediaPlaylistTest, MultiSegment) {
valid_video_media_info_.set_reference_time_scale(90000); valid_video_media_info_.set_reference_time_scale(90000);
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_)); valid_video_media_info_.set_segment_template_url("file$Number$.ts");
ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
media_playlist_.AddKeyFrame(0, 1000, 2345); media_playlist_->AddKeyFrame(0, 1000, 2345);
media_playlist_.AddKeyFrame(2 * kTimeScale, 5000, 6345); media_playlist_->AddKeyFrame(2 * kTimeScale, 5000, 6345);
media_playlist_.AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset, media_playlist_->AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset,
kMBytes); kMBytes);
media_playlist_.AddKeyFrame(11 * kTimeScale, 1000, 2345); media_playlist_->AddKeyFrame(11 * kTimeScale, 1000, 2345);
media_playlist_.AddKeyFrame(15 * kTimeScale, 3345, 12345); media_playlist_->AddKeyFrame(15 * kTimeScale, 3345, 12345);
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale, media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
kZeroByteOffset, 5 * kMBytes); kZeroByteOffset, 5 * kMBytes);
const char kExpectedOutput[] = const char kExpectedOutput[] =
@ -863,7 +866,7 @@ TEST_F(IFrameMediaPlaylistTest, MultiSegment) {
"#EXT-X-ENDLIST\n"; "#EXT-X-ENDLIST\n";
const char kMemoryFilePath[] = "memory://media.m3u8"; const char kMemoryFilePath[] = "memory://media.m3u8";
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath)); EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput); ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
} }

View File

@ -6,14 +6,15 @@
#include "packager/hls/base/mock_media_playlist.h" #include "packager/hls/base/mock_media_playlist.h"
#include "packager/hls/public/hls_params.h"
namespace shaka { namespace shaka {
namespace hls { namespace hls {
MockMediaPlaylist::MockMediaPlaylist(HlsPlaylistType type, MockMediaPlaylist::MockMediaPlaylist(const std::string& file_name,
const std::string& file_name,
const std::string& name, const std::string& name,
const std::string& group_id) const std::string& group_id)
: MediaPlaylist(type, 0, file_name, name, group_id) {} : MediaPlaylist(HlsParams(), file_name, name, group_id) {}
MockMediaPlaylist::~MockMediaPlaylist() {} MockMediaPlaylist::~MockMediaPlaylist() {}
} // namespace hls } // namespace hls

View File

@ -18,8 +18,7 @@ class MockMediaPlaylist : public MediaPlaylist {
public: public:
// The actual parameters to MediaPlaylist() (parent) constructor doesn't // The actual parameters to MediaPlaylist() (parent) constructor doesn't
// matter because the return value can be mocked. // matter because the return value can be mocked.
MockMediaPlaylist(HlsPlaylistType type, MockMediaPlaylist(const std::string& file_name,
const std::string& file_name,
const std::string& name, const std::string& name,
const std::string& group_id); const std::string& group_id);
~MockMediaPlaylist() override; ~MockMediaPlaylist() override;

View File

@ -104,6 +104,30 @@ std::string GenerateSegmentUrl(const std::string& segment_name,
return MakePathRelative(segment_name, playlist_dir); return MakePathRelative(segment_name, playlist_dir);
} }
MediaInfo MakeMediaInfoPathsRelativeToPlaylist(
const MediaInfo& media_info,
const std::string& base_url,
const std::string& output_dir,
const std::string& playlist_name) {
MediaInfo media_info_copy = media_info;
if (media_info_copy.has_init_segment_name()) {
media_info_copy.set_init_segment_url(
GenerateSegmentUrl(media_info_copy.init_segment_name(), base_url,
output_dir, playlist_name));
}
if (media_info_copy.has_media_file_name()) {
media_info_copy.set_media_file_url(
GenerateSegmentUrl(media_info_copy.media_file_name(), base_url,
output_dir, playlist_name));
}
if (media_info_copy.has_segment_template()) {
media_info_copy.set_segment_template_url(
GenerateSegmentUrl(media_info_copy.segment_template(), base_url,
output_dir, playlist_name));
}
return media_info_copy;
}
bool WidevinePsshToJson(const std::vector<uint8_t>& pssh_box, bool WidevinePsshToJson(const std::vector<uint8_t>& pssh_box,
const std::vector<uint8_t>& key_id, const std::vector<uint8_t>& key_id,
std::string* pssh_json) { std::string* pssh_json) {
@ -240,20 +264,16 @@ bool WriteMediaPlaylist(const std::string& output_dir,
MediaPlaylistFactory::~MediaPlaylistFactory() {} MediaPlaylistFactory::~MediaPlaylistFactory() {}
std::unique_ptr<MediaPlaylist> MediaPlaylistFactory::Create( std::unique_ptr<MediaPlaylist> MediaPlaylistFactory::Create(
HlsPlaylistType type, const HlsParams& hls_params,
double time_shift_buffer_depth,
const std::string& file_name, const std::string& file_name,
const std::string& name, const std::string& name,
const std::string& group_id) { const std::string& group_id) {
return std::unique_ptr<MediaPlaylist>(new MediaPlaylist( return std::unique_ptr<MediaPlaylist>(
type, time_shift_buffer_depth, file_name, name, group_id)); new MediaPlaylist(hls_params, file_name, name, group_id));
} }
SimpleHlsNotifier::SimpleHlsNotifier(const HlsParams& hls_params) SimpleHlsNotifier::SimpleHlsNotifier(const HlsParams& hls_params)
: HlsNotifier(hls_params.playlist_type), : HlsNotifier(hls_params),
time_shift_buffer_depth_(hls_params.time_shift_buffer_depth),
prefix_(hls_params.base_url),
key_uri_(hls_params.key_uri),
media_playlist_factory_(new MediaPlaylistFactory()) { media_playlist_factory_(new MediaPlaylistFactory()) {
const base::FilePath master_playlist_path( const base::FilePath master_playlist_path(
base::FilePath::FromUTF8Unsafe(hls_params.master_playlist_output)); base::FilePath::FromUTF8Unsafe(hls_params.master_playlist_output));
@ -277,27 +297,12 @@ bool SimpleHlsNotifier::NotifyNewStream(const MediaInfo& media_info,
DCHECK(stream_id); DCHECK(stream_id);
std::unique_ptr<MediaPlaylist> media_playlist = std::unique_ptr<MediaPlaylist> media_playlist =
media_playlist_factory_->Create(playlist_type(), time_shift_buffer_depth_, media_playlist_factory_->Create(hls_params(), playlist_name, name,
playlist_name, name, group_id); group_id);
MediaInfo adjusted_media_info = MakeMediaInfoPathsRelativeToPlaylist(
// Update init_segment_name to be relative to playlist path if needed. media_info, hls_params().base_url, output_dir_,
MediaInfo media_info_copy = media_info; media_playlist->file_name());
if (media_info_copy.has_init_segment_name()) { if (!media_playlist->SetMediaInfo(adjusted_media_info)) {
media_info_copy.set_init_segment_url(
GenerateSegmentUrl(media_info_copy.init_segment_name(), prefix_,
output_dir_, media_playlist->file_name()));
}
if (media_info_copy.has_media_file_name()) {
media_info_copy.set_media_file_url(
GenerateSegmentUrl(media_info_copy.media_file_name(), prefix_,
output_dir_, media_playlist->file_name()));
}
if (media_info_copy.has_segment_template()) {
media_info_copy.set_segment_template_url(
GenerateSegmentUrl(media_info_copy.segment_template(), prefix_,
output_dir_, media_playlist->file_name()));
}
if (!media_playlist->SetMediaInfo(media_info_copy)) {
LOG(ERROR) << "Failed to set media info for playlist " << playlist_name; LOG(ERROR) << "Failed to set media info for playlist " << playlist_name;
return false; return false;
} }
@ -338,8 +343,9 @@ bool SimpleHlsNotifier::NotifyNewSegment(uint32_t stream_id,
return false; return false;
} }
auto& media_playlist = stream_iterator->second->media_playlist; auto& media_playlist = stream_iterator->second->media_playlist;
const std::string& segment_url = GenerateSegmentUrl( const std::string& segment_url =
segment_name, prefix_, output_dir_, media_playlist->file_name()); GenerateSegmentUrl(segment_name, hls_params().base_url, output_dir_,
media_playlist->file_name());
media_playlist->AddSegment(segment_url, start_time, duration, media_playlist->AddSegment(segment_url, start_time, duration,
start_byte_offset, size); start_byte_offset, size);
@ -353,8 +359,8 @@ bool SimpleHlsNotifier::NotifyNewSegment(uint32_t stream_id,
} }
// Update the playlists when there is new segments in live mode. // Update the playlists when there is new segments in live mode.
if (playlist_type() == HlsPlaylistType::kLive || if (hls_params().playlist_type == HlsPlaylistType::kLive ||
playlist_type() == HlsPlaylistType::kEvent) { hls_params().playlist_type == HlsPlaylistType::kEvent) {
// Update all playlists if target duration is updated. // Update all playlists if target duration is updated.
if (target_duration_updated) { if (target_duration_updated) {
for (MediaPlaylist* playlist : media_playlists_) { for (MediaPlaylist* playlist : media_playlists_) {
@ -366,8 +372,8 @@ bool SimpleHlsNotifier::NotifyNewSegment(uint32_t stream_id,
if (!WriteMediaPlaylist(output_dir_, media_playlist.get())) if (!WriteMediaPlaylist(output_dir_, media_playlist.get()))
return false; return false;
} }
if (!master_playlist_->WriteMasterPlaylist(prefix_, output_dir_, if (!master_playlist_->WriteMasterPlaylist(hls_params().base_url,
media_playlists_)) { output_dir_, media_playlists_)) {
LOG(ERROR) << "Failed to write master playlist."; LOG(ERROR) << "Failed to write master playlist.";
return false; return false;
} }
@ -431,10 +437,8 @@ bool SimpleHlsNotifier::NotifyEncryptionUpdate(
const std::vector<uint8_t> empty_key_id; const std::vector<uint8_t> empty_key_id;
if (IsCommonSystemId(system_id)) { if (IsCommonSystemId(system_id)) {
std::string key_uri; std::string key_uri = hls_params().key_uri;
if (!key_uri_.empty()) { if (key_uri.empty()) {
key_uri = key_uri_;
} else {
// Use key_id as the key_uri. The player needs to have custom logic to // Use key_id as the key_uri. The player needs to have custom logic to
// convert it to the actual key uri. // convert it to the actual key uri.
std::string key_uri_data = VectorToString(key_id); std::string key_uri_data = VectorToString(key_id);
@ -444,10 +448,8 @@ bool SimpleHlsNotifier::NotifyEncryptionUpdate(
iv, "identity", "", media_playlist.get()); iv, "identity", "", media_playlist.get());
return true; return true;
} else if (IsFairplaySystemId(system_id)) { } else if (IsFairplaySystemId(system_id)) {
std::string key_uri; std::string key_uri = hls_params().key_uri;
if (!key_uri_.empty()) { if (key_uri.empty()) {
key_uri = key_uri_;
} else {
// Use key_id as the key_uri. The player needs to have custom logic to // Use key_id as the key_uri. The player needs to have custom logic to
// convert it to the actual key uri. // convert it to the actual key uri.
std::string key_uri_data = VectorToString(key_id); std::string key_uri_data = VectorToString(key_id);
@ -474,7 +476,7 @@ bool SimpleHlsNotifier::Flush() {
if (!WriteMediaPlaylist(output_dir_, playlist)) if (!WriteMediaPlaylist(output_dir_, playlist))
return false; return false;
} }
if (!master_playlist_->WriteMasterPlaylist(prefix_, output_dir_, if (!master_playlist_->WriteMasterPlaylist(hls_params().base_url, output_dir_,
media_playlists_)) { media_playlists_)) {
LOG(ERROR) << "Failed to write master playlist."; LOG(ERROR) << "Failed to write master playlist.";
return false; return false;

View File

@ -29,8 +29,7 @@ namespace hls {
class MediaPlaylistFactory { class MediaPlaylistFactory {
public: public:
virtual ~MediaPlaylistFactory(); virtual ~MediaPlaylistFactory();
virtual std::unique_ptr<MediaPlaylist> Create(HlsPlaylistType type, virtual std::unique_ptr<MediaPlaylist> Create(const HlsParams& hls_params,
double time_shift_buffer_depth,
const std::string& file_name, const std::string& file_name,
const std::string& name, const std::string& name,
const std::string& group_id); const std::string& group_id);
@ -79,9 +78,6 @@ class SimpleHlsNotifier : public HlsNotifier {
MediaPlaylist::EncryptionMethod encryption_method; MediaPlaylist::EncryptionMethod encryption_method;
}; };
const double time_shift_buffer_depth_ = 0;
const std::string prefix_;
const std::string key_uri_;
std::string output_dir_; std::string output_dir_;
uint32_t target_duration_ = 0; uint32_t target_duration_ = 0;

View File

@ -54,20 +54,18 @@ class MockMasterPlaylist : public MasterPlaylist {
class MockMediaPlaylistFactory : public MediaPlaylistFactory { class MockMediaPlaylistFactory : public MediaPlaylistFactory {
public: public:
MOCK_METHOD5(CreateMock, MOCK_METHOD4(CreateMock,
MediaPlaylist*(HlsPlaylistType type, MediaPlaylist*(const HlsParams& hls_params,
double time_shift_buffer_depth,
const std::string& file_name, const std::string& file_name,
const std::string& name, const std::string& name,
const std::string& group_id)); const std::string& group_id));
std::unique_ptr<MediaPlaylist> Create(HlsPlaylistType type, std::unique_ptr<MediaPlaylist> Create(const HlsParams& hls_params,
double time_shift_buffer_depth,
const std::string& file_name, const std::string& file_name,
const std::string& name, const std::string& name,
const std::string& group_id) override { const std::string& group_id) override {
return std::unique_ptr<MediaPlaylist>( return std::unique_ptr<MediaPlaylist>(
CreateMock(type, time_shift_buffer_depth, file_name, name, group_id)); CreateMock(hls_params, file_name, name, group_id));
} }
}; };
@ -133,7 +131,7 @@ class SimpleHlsNotifierTest : public ::testing::Test {
new MockMediaPlaylistFactory()); new MockMediaPlaylistFactory());
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true)); EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
EXPECT_CALL(*factory, CreateMock(_, _, _, _, _)) EXPECT_CALL(*factory, CreateMock(_, _, _, _))
.WillOnce(Return(mock_media_playlist)); .WillOnce(Return(mock_media_playlist));
InjectMasterPlaylist(std::move(mock_master_playlist), notifier); InjectMasterPlaylist(std::move(mock_master_playlist), notifier);
@ -167,7 +165,7 @@ TEST_F(SimpleHlsNotifierTest, RebaseSegmentUrl) {
// Pointer released by SimpleHlsNotifier. // Pointer released by SimpleHlsNotifier.
MockMediaPlaylist* mock_media_playlist = MockMediaPlaylist* mock_media_playlist =
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", ""); new MockMediaPlaylist("playlist.m3u8", "", "");
EXPECT_CALL(*mock_media_playlist, EXPECT_CALL(*mock_media_playlist,
SetMediaInfo(Property(&MediaInfo::init_segment_url, StrEq("")))) SetMediaInfo(Property(&MediaInfo::init_segment_url, StrEq(""))))
@ -177,9 +175,8 @@ TEST_F(SimpleHlsNotifierTest, RebaseSegmentUrl) {
EXPECT_CALL( EXPECT_CALL(
*mock_media_playlist, *mock_media_playlist,
AddSegment("http://testprefix.com/path/to/media1.ts", _, _, _, _)); AddSegment("http://testprefix.com/path/to/media1.ts", _, _, _, _));
EXPECT_CALL(*factory, CreateMock(kVodPlaylist, Eq(kTestTimeShiftBufferDepth), EXPECT_CALL(*factory, CreateMock(_, StrEq("video_playlist.m3u8"),
StrEq("video_playlist.m3u8"), StrEq("name"), StrEq("name"), StrEq("groupid")))
StrEq("groupid")))
.WillOnce(Return(mock_media_playlist)); .WillOnce(Return(mock_media_playlist));
SimpleHlsNotifier notifier(hls_params_); SimpleHlsNotifier notifier(hls_params_);
@ -206,7 +203,7 @@ TEST_F(SimpleHlsNotifierTest, RebaseInitSegmentUrl) {
// Pointer released by SimpleHlsNotifier. // Pointer released by SimpleHlsNotifier.
MockMediaPlaylist* mock_media_playlist = MockMediaPlaylist* mock_media_playlist =
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", ""); new MockMediaPlaylist("playlist.m3u8", "", "");
// Verify that the common prefix is stripped in init segment. // Verify that the common prefix is stripped in init segment.
EXPECT_CALL( EXPECT_CALL(
@ -215,9 +212,8 @@ TEST_F(SimpleHlsNotifierTest, RebaseInitSegmentUrl) {
StrEq("http://testprefix.com/path/to/init.mp4")))) StrEq("http://testprefix.com/path/to/init.mp4"))))
.WillOnce(Return(true)); .WillOnce(Return(true));
EXPECT_CALL(*factory, CreateMock(kVodPlaylist, Eq(kTestTimeShiftBufferDepth), EXPECT_CALL(*factory, CreateMock(_, StrEq("video_playlist.m3u8"),
StrEq("video_playlist.m3u8"), StrEq("name"), StrEq("name"), StrEq("groupid")))
StrEq("groupid")))
.WillOnce(Return(mock_media_playlist)); .WillOnce(Return(mock_media_playlist));
SimpleHlsNotifier notifier(hls_params_); SimpleHlsNotifier notifier(hls_params_);
@ -241,7 +237,7 @@ TEST_F(SimpleHlsNotifierTest, RebaseSegmentUrlRelativeToPlaylist) {
// Pointer released by SimpleHlsNotifier. // Pointer released by SimpleHlsNotifier.
MockMediaPlaylist* mock_media_playlist = MockMediaPlaylist* mock_media_playlist =
new MockMediaPlaylist(kVodPlaylist, "video/playlist.m3u8", "", ""); new MockMediaPlaylist("video/playlist.m3u8", "", "");
// Verify that the init segment URL is relative to playlist path. // Verify that the init segment URL is relative to playlist path.
EXPECT_CALL(*mock_media_playlist, EXPECT_CALL(*mock_media_playlist,
@ -252,9 +248,8 @@ TEST_F(SimpleHlsNotifierTest, RebaseSegmentUrlRelativeToPlaylist) {
// Verify that the segment URL is relative to playlist path. // Verify that the segment URL is relative to playlist path.
EXPECT_CALL(*mock_media_playlist, EXPECT_CALL(*mock_media_playlist,
AddSegment(StrEq("path/to/media1.m4s"), _, _, _, _)); AddSegment(StrEq("path/to/media1.m4s"), _, _, _, _));
EXPECT_CALL(*factory, CreateMock(kVodPlaylist, Eq(kTestTimeShiftBufferDepth), EXPECT_CALL(*factory, CreateMock(_, StrEq("video/playlist.m3u8"),
StrEq("video/playlist.m3u8"), StrEq("name"), StrEq("name"), StrEq("groupid")))
StrEq("groupid")))
.WillOnce(Return(mock_media_playlist)); .WillOnce(Return(mock_media_playlist));
hls_params_.base_url = kEmptyPrefix; hls_params_.base_url = kEmptyPrefix;
@ -289,16 +284,15 @@ TEST_F(SimpleHlsNotifierTest, RebaseAbsoluteSegmentPrefixAndOutputDirMatch) {
// Pointer released by SimpleHlsNotifier. // Pointer released by SimpleHlsNotifier.
MockMediaPlaylist* mock_media_playlist = MockMediaPlaylist* mock_media_playlist =
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", ""); new MockMediaPlaylist("playlist.m3u8", "", "");
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true)); EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
// Verify that the output_dir is stripped and then kTestPrefix is prepended. // Verify that the output_dir is stripped and then kTestPrefix is prepended.
EXPECT_CALL(*mock_media_playlist, EXPECT_CALL(*mock_media_playlist,
AddSegment("http://testprefix.com/media1.ts", _, _, _, _)); AddSegment("http://testprefix.com/media1.ts", _, _, _, _));
EXPECT_CALL(*factory, CreateMock(kVodPlaylist, Eq(kTestTimeShiftBufferDepth), EXPECT_CALL(*factory, CreateMock(_, StrEq("video_playlist.m3u8"),
StrEq("video_playlist.m3u8"), StrEq("name"), StrEq("name"), StrEq("groupid")))
StrEq("groupid")))
.WillOnce(Return(mock_media_playlist)); .WillOnce(Return(mock_media_playlist));
InjectMasterPlaylist(std::move(mock_master_playlist), &test_notifier); InjectMasterPlaylist(std::move(mock_master_playlist), &test_notifier);
@ -330,15 +324,14 @@ TEST_F(SimpleHlsNotifierTest,
// Pointer released by SimpleHlsNotifier. // Pointer released by SimpleHlsNotifier.
MockMediaPlaylist* mock_media_playlist = MockMediaPlaylist* mock_media_playlist =
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", ""); new MockMediaPlaylist("playlist.m3u8", "", "");
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true)); EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
EXPECT_CALL(*mock_media_playlist, EXPECT_CALL(*mock_media_playlist,
AddSegment("http://testprefix.com//var/somewhereelse/media1.ts", AddSegment("http://testprefix.com//var/somewhereelse/media1.ts",
_, _, _, _)); _, _, _, _));
EXPECT_CALL(*factory, CreateMock(kVodPlaylist, Eq(kTestTimeShiftBufferDepth), EXPECT_CALL(*factory, CreateMock(_, StrEq("video_playlist.m3u8"),
StrEq("video_playlist.m3u8"), StrEq("name"), StrEq("name"), StrEq("groupid")))
StrEq("groupid")))
.WillOnce(Return(mock_media_playlist)); .WillOnce(Return(mock_media_playlist));
InjectMasterPlaylist(std::move(mock_master_playlist), &test_notifier); InjectMasterPlaylist(std::move(mock_master_playlist), &test_notifier);
@ -374,12 +367,11 @@ TEST_F(SimpleHlsNotifierTest, NotifyNewStream) {
// Pointer released by SimpleHlsNotifier. // Pointer released by SimpleHlsNotifier.
MockMediaPlaylist* mock_media_playlist = MockMediaPlaylist* mock_media_playlist =
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", ""); new MockMediaPlaylist("playlist.m3u8", "", "");
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true)); EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
EXPECT_CALL(*factory, CreateMock(kVodPlaylist, Eq(kTestTimeShiftBufferDepth), EXPECT_CALL(*factory, CreateMock(_, StrEq("video_playlist.m3u8"),
StrEq("video_playlist.m3u8"), StrEq("name"), StrEq("name"), StrEq("groupid")))
StrEq("groupid")))
.WillOnce(Return(mock_media_playlist)); .WillOnce(Return(mock_media_playlist));
SimpleHlsNotifier notifier(hls_params_); SimpleHlsNotifier notifier(hls_params_);
@ -402,10 +394,10 @@ TEST_F(SimpleHlsNotifierTest, NotifyNewSegment) {
// Pointer released by SimpleHlsNotifier. // Pointer released by SimpleHlsNotifier.
MockMediaPlaylist* mock_media_playlist = MockMediaPlaylist* mock_media_playlist =
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", ""); new MockMediaPlaylist("playlist.m3u8", "", "");
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true)); EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
EXPECT_CALL(*factory, CreateMock(_, _, _, _, _)) EXPECT_CALL(*factory, CreateMock(_, _, _, _))
.WillOnce(Return(mock_media_playlist)); .WillOnce(Return(mock_media_playlist));
const uint64_t kStartTime = 1328; const uint64_t kStartTime = 1328;
@ -455,7 +447,7 @@ TEST_F(SimpleHlsNotifierTest, NotifyNewSegment) {
TEST_F(SimpleHlsNotifierTest, NotifyKeyFrame) { TEST_F(SimpleHlsNotifierTest, NotifyKeyFrame) {
// Pointer released by SimpleHlsNotifier. // Pointer released by SimpleHlsNotifier.
MockMediaPlaylist* mock_media_playlist = MockMediaPlaylist* mock_media_playlist =
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", ""); new MockMediaPlaylist("playlist.m3u8", "", "");
SimpleHlsNotifier notifier(hls_params_); SimpleHlsNotifier notifier(hls_params_);
const uint32_t stream_id = const uint32_t stream_id =
SetupStream(kCencProtectionScheme, mock_media_playlist, &notifier); SetupStream(kCencProtectionScheme, mock_media_playlist, &notifier);
@ -478,7 +470,7 @@ TEST_F(SimpleHlsNotifierTest, NotifyNewSegmentWithoutStreamsRegistered) {
TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateWidevine) { TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateWidevine) {
// Pointer released by SimpleHlsNotifier. // Pointer released by SimpleHlsNotifier.
MockMediaPlaylist* mock_media_playlist = MockMediaPlaylist* mock_media_playlist =
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", ""); new MockMediaPlaylist("playlist.m3u8", "", "");
SimpleHlsNotifier notifier(hls_params_); SimpleHlsNotifier notifier(hls_params_);
const uint32_t stream_id = const uint32_t stream_id =
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, &notifier); SetupStream(kSampleAesProtectionScheme, mock_media_playlist, &notifier);
@ -539,7 +531,7 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateWidevine) {
TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateWidevineNoKeyidsInPssh) { TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateWidevineNoKeyidsInPssh) {
// Pointer released by SimpleHlsNotifier. // Pointer released by SimpleHlsNotifier.
MockMediaPlaylist* mock_media_playlist = MockMediaPlaylist* mock_media_playlist =
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", ""); new MockMediaPlaylist("playlist.m3u8", "", "");
SimpleHlsNotifier notifier(hls_params_); SimpleHlsNotifier notifier(hls_params_);
const uint32_t stream_id = const uint32_t stream_id =
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, &notifier); SetupStream(kSampleAesProtectionScheme, mock_media_playlist, &notifier);
@ -596,7 +588,7 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateWidevineNoKeyidsInPssh) {
TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateIdentityKey) { TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateIdentityKey) {
// Pointer released by SimpleHlsNotifier. // Pointer released by SimpleHlsNotifier.
MockMediaPlaylist* mock_media_playlist = MockMediaPlaylist* mock_media_playlist =
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", ""); new MockMediaPlaylist("playlist.m3u8", "", "");
SimpleHlsNotifier notifier(hls_params_); SimpleHlsNotifier notifier(hls_params_);
const uint32_t stream_id = const uint32_t stream_id =
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, &notifier); SetupStream(kSampleAesProtectionScheme, mock_media_playlist, &notifier);
@ -624,7 +616,7 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateIdentityKey) {
TEST_F(SimpleHlsNotifierTest, WidevineMultipleKeyIdsNoContentIdInPssh) { TEST_F(SimpleHlsNotifierTest, WidevineMultipleKeyIdsNoContentIdInPssh) {
// Pointer released by SimpleHlsNotifier. // Pointer released by SimpleHlsNotifier.
MockMediaPlaylist* mock_media_playlist = MockMediaPlaylist* mock_media_playlist =
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", ""); new MockMediaPlaylist("playlist.m3u8", "", "");
SimpleHlsNotifier notifier(hls_params_); SimpleHlsNotifier notifier(hls_params_);
uint32_t stream_id = uint32_t stream_id =
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, &notifier); SetupStream(kSampleAesProtectionScheme, mock_media_playlist, &notifier);
@ -700,7 +692,7 @@ TEST_F(SimpleHlsNotifierTest, WidevineMultipleKeyIdsNoContentIdInPssh) {
TEST_F(SimpleHlsNotifierTest, EncryptionScheme) { TEST_F(SimpleHlsNotifierTest, EncryptionScheme) {
// Pointer released by SimpleHlsNotifier. // Pointer released by SimpleHlsNotifier.
MockMediaPlaylist* mock_media_playlist = MockMediaPlaylist* mock_media_playlist =
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", ""); new MockMediaPlaylist("playlist.m3u8", "", "");
hls_params_.key_uri = kIdentityKeyUri; hls_params_.key_uri = kIdentityKeyUri;
SimpleHlsNotifier notifier(hls_params_); SimpleHlsNotifier notifier(hls_params_);
const uint32_t stream_id = const uint32_t stream_id =
@ -724,7 +716,7 @@ TEST_F(SimpleHlsNotifierTest, EncryptionScheme) {
TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateFairplay) { TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateFairplay) {
// Pointer released by SimpleHlsNotifier. // Pointer released by SimpleHlsNotifier.
MockMediaPlaylist* mock_media_playlist = MockMediaPlaylist* mock_media_playlist =
new MockMediaPlaylist(kLivePlaylist, "playlist.m3u8", "", ""); new MockMediaPlaylist("playlist.m3u8", "", "");
hls_params_.playlist_type = kLivePlaylist; hls_params_.playlist_type = kLivePlaylist;
hls_params_.key_uri = kFairplayKeyUri; hls_params_.key_uri = kFairplayKeyUri;
SimpleHlsNotifier notifier(hls_params_); SimpleHlsNotifier notifier(hls_params_);
@ -747,7 +739,7 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateFairplay) {
TEST_F(SimpleHlsNotifierTest, WidevineCencEncryptionScheme) { TEST_F(SimpleHlsNotifierTest, WidevineCencEncryptionScheme) {
// Pointer released by SimpleHlsNotifier. // Pointer released by SimpleHlsNotifier.
MockMediaPlaylist* mock_media_playlist = MockMediaPlaylist* mock_media_playlist =
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", ""); new MockMediaPlaylist("playlist.m3u8", "", "");
SimpleHlsNotifier notifier(hls_params_); SimpleHlsNotifier notifier(hls_params_);
const uint32_t stream_id = const uint32_t stream_id =
SetupStream(kCencProtectionScheme, mock_media_playlist, &notifier); SetupStream(kCencProtectionScheme, mock_media_playlist, &notifier);
@ -794,7 +786,7 @@ TEST_F(SimpleHlsNotifierTest, WidevineCencEncryptionScheme) {
TEST_F(SimpleHlsNotifierTest, WidevineNotifyEncryptionUpdateEmptyIv) { TEST_F(SimpleHlsNotifierTest, WidevineNotifyEncryptionUpdateEmptyIv) {
// Pointer released by SimpleHlsNotifier. // Pointer released by SimpleHlsNotifier.
MockMediaPlaylist* mock_media_playlist = MockMediaPlaylist* mock_media_playlist =
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", ""); new MockMediaPlaylist("playlist.m3u8", "", "");
SimpleHlsNotifier notifier(hls_params_); SimpleHlsNotifier notifier(hls_params_);
const uint32_t stream_id = const uint32_t stream_id =
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, &notifier); SetupStream(kSampleAesProtectionScheme, mock_media_playlist, &notifier);
@ -870,7 +862,7 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateWithoutStreamsRegistered) {
TEST_F(SimpleHlsNotifierTest, NotifyCueEvent) { TEST_F(SimpleHlsNotifierTest, NotifyCueEvent) {
// Pointer released by SimpleHlsNotifier. // Pointer released by SimpleHlsNotifier.
MockMediaPlaylist* mock_media_playlist = MockMediaPlaylist* mock_media_playlist =
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", ""); new MockMediaPlaylist("playlist.m3u8", "", "");
SimpleHlsNotifier notifier(hls_params_); SimpleHlsNotifier notifier(hls_params_);
const uint32_t stream_id = const uint32_t stream_id =
SetupStream(kCencProtectionScheme, mock_media_playlist, &notifier); SetupStream(kCencProtectionScheme, mock_media_playlist, &notifier);
@ -899,10 +891,10 @@ TEST_P(LiveOrEventSimpleHlsNotifierTest, NotifyNewSegment) {
// Pointer released by SimpleHlsNotifier. // Pointer released by SimpleHlsNotifier.
MockMediaPlaylist* mock_media_playlist = MockMediaPlaylist* mock_media_playlist =
new MockMediaPlaylist(expected_playlist_type_, "playlist.m3u8", "", ""); new MockMediaPlaylist("playlist.m3u8", "", "");
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true)); EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
EXPECT_CALL(*factory, CreateMock(expected_playlist_type_, _, _, _, _)) EXPECT_CALL(*factory, CreateMock(_, _, _, _))
.WillOnce(Return(mock_media_playlist)); .WillOnce(Return(mock_media_playlist));
const uint64_t kStartTime = 1328; const uint64_t kStartTime = 1328;
@ -958,14 +950,14 @@ TEST_P(LiveOrEventSimpleHlsNotifierTest, NotifyNewSegmentsWithMultipleStreams) {
// Pointer released by SimpleHlsNotifier. // Pointer released by SimpleHlsNotifier.
MockMediaPlaylist* mock_media_playlist1 = MockMediaPlaylist* mock_media_playlist1 =
new MockMediaPlaylist(expected_playlist_type_, "playlist1.m3u8", "", ""); new MockMediaPlaylist("playlist1.m3u8", "", "");
MockMediaPlaylist* mock_media_playlist2 = MockMediaPlaylist* mock_media_playlist2 =
new MockMediaPlaylist(expected_playlist_type_, "playlist2.m3u8", "", ""); new MockMediaPlaylist("playlist2.m3u8", "", "");
EXPECT_CALL(*factory, CreateMock(_, _, StrEq("playlist1.m3u8"), _, _)) EXPECT_CALL(*factory, CreateMock(_, StrEq("playlist1.m3u8"), _, _))
.WillOnce(Return(mock_media_playlist1)); .WillOnce(Return(mock_media_playlist1));
EXPECT_CALL(*mock_media_playlist1, SetMediaInfo(_)).WillOnce(Return(true)); EXPECT_CALL(*mock_media_playlist1, SetMediaInfo(_)).WillOnce(Return(true));
EXPECT_CALL(*factory, CreateMock(_, _, StrEq("playlist2.m3u8"), _, _)) EXPECT_CALL(*factory, CreateMock(_, StrEq("playlist2.m3u8"), _, _))
.WillOnce(Return(mock_media_playlist2)); .WillOnce(Return(mock_media_playlist2));
EXPECT_CALL(*mock_media_playlist2, SetMediaInfo(_)).WillOnce(Return(true)); EXPECT_CALL(*mock_media_playlist2, SetMediaInfo(_)).WillOnce(Return(true));

View File

@ -26,7 +26,7 @@ namespace {
class MockHlsNotifier : public hls::HlsNotifier { class MockHlsNotifier : public hls::HlsNotifier {
public: public:
MockHlsNotifier() : HlsNotifier(HlsPlaylistType::kVod) {} MockHlsNotifier() : HlsNotifier(HlsParams()) {}
MOCK_METHOD0(Init, bool()); MOCK_METHOD0(Init, bool());
MOCK_METHOD5(NotifyNewStream, MOCK_METHOD5(NotifyNewStream,