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:
parent
adc9549e2d
commit
60d7a4b2d5
|
@ -19,8 +19,7 @@ namespace hls {
|
|||
// TODO(rkuroiwa): Consider merging this with MpdNotifier.
|
||||
class HlsNotifier {
|
||||
public:
|
||||
explicit HlsNotifier(HlsPlaylistType playlist_type)
|
||||
: playlist_type_(playlist_type) {}
|
||||
explicit HlsNotifier(const HlsParams& hls_params) : hls_params_(hls_params) {}
|
||||
virtual ~HlsNotifier() {}
|
||||
|
||||
/// Intialize the notifier.
|
||||
|
@ -92,11 +91,11 @@ class HlsNotifier {
|
|||
/// @return true on success, false otherwise.
|
||||
virtual bool Flush() = 0;
|
||||
|
||||
/// @return the playlist type.
|
||||
HlsPlaylistType playlist_type() const { return playlist_type_; }
|
||||
/// @return The HLS parameters.
|
||||
const HlsParams& hls_params() const { return hls_params_; }
|
||||
|
||||
private:
|
||||
HlsPlaylistType playlist_type_;
|
||||
const HlsParams hls_params_;
|
||||
};
|
||||
|
||||
} // namespace hls
|
||||
|
|
|
@ -31,7 +31,6 @@ const char kDefaultMasterPlaylistName[] = "playlist.m3u8";
|
|||
const char kDefaultLanguage[] = "en";
|
||||
const uint32_t kWidth = 800;
|
||||
const uint32_t kHeight = 600;
|
||||
const HlsPlaylistType kVodPlaylist = HlsPlaylistType::kVod;
|
||||
|
||||
std::unique_ptr<MockMediaPlaylist> CreateVideoPlaylist(
|
||||
const std::string& filename,
|
||||
|
@ -41,7 +40,7 @@ std::unique_ptr<MockMediaPlaylist> CreateVideoPlaylist(
|
|||
const char kNoGroup[] = "";
|
||||
|
||||
std::unique_ptr<MockMediaPlaylist> playlist(
|
||||
new MockMediaPlaylist(kVodPlaylist, filename, kNoName, kNoGroup));
|
||||
new MockMediaPlaylist(filename, kNoName, kNoGroup));
|
||||
|
||||
playlist->SetStreamTypeForTesting(
|
||||
MediaPlaylist::MediaPlaylistStreamType::kVideo);
|
||||
|
@ -76,7 +75,7 @@ std::unique_ptr<MockMediaPlaylist> CreateAudioPlaylist(
|
|||
uint64_t channels,
|
||||
uint64_t bitrate) {
|
||||
std::unique_ptr<MockMediaPlaylist> playlist(
|
||||
new MockMediaPlaylist(kVodPlaylist, filename, name, group));
|
||||
new MockMediaPlaylist(filename, name, group));
|
||||
|
||||
EXPECT_CALL(*playlist, GetNumChannels()).WillRepeatedly(Return(channels));
|
||||
|
||||
|
@ -100,7 +99,7 @@ std::unique_ptr<MockMediaPlaylist> CreateTextPlaylist(
|
|||
const std::string& codec,
|
||||
const std::string& language) {
|
||||
std::unique_ptr<MockMediaPlaylist> playlist(
|
||||
new MockMediaPlaylist(kVodPlaylist, filename, name, group));
|
||||
new MockMediaPlaylist(filename, name, group));
|
||||
|
||||
playlist->SetStreamTypeForTesting(
|
||||
MediaPlaylist::MediaPlaylistStreamType::kSubtitle);
|
||||
|
|
|
@ -321,13 +321,11 @@ double LatestSegmentStartTime(
|
|||
HlsEntry::HlsEntry(HlsEntry::EntryType type) : type_(type) {}
|
||||
HlsEntry::~HlsEntry() {}
|
||||
|
||||
MediaPlaylist::MediaPlaylist(HlsPlaylistType playlist_type,
|
||||
double time_shift_buffer_depth,
|
||||
MediaPlaylist::MediaPlaylist(const HlsParams& hls_params,
|
||||
const std::string& file_name,
|
||||
const std::string& name,
|
||||
const std::string& group_id)
|
||||
: playlist_type_(playlist_type),
|
||||
time_shift_buffer_depth_(time_shift_buffer_depth),
|
||||
: hls_params_(hls_params),
|
||||
file_name_(file_name),
|
||||
name_(name),
|
||||
group_id_(group_id) {}
|
||||
|
@ -440,7 +438,8 @@ void MediaPlaylist::AddPlacementOpportunity() {
|
|||
}
|
||||
|
||||
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
|
||||
// once at the end of the file in VOD.
|
||||
CHECK_EQ(key_frames_.size(), 1u);
|
||||
|
@ -456,13 +455,13 @@ bool MediaPlaylist::WriteToFile(const std::string& file_path) {
|
|||
}
|
||||
|
||||
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_);
|
||||
|
||||
for (const auto& entry : entries_)
|
||||
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";
|
||||
}
|
||||
|
||||
|
@ -550,8 +549,8 @@ void MediaPlaylist::AddSegmentInfoEntry(const std::string& segment_file_name,
|
|||
|
||||
void MediaPlaylist::SlideWindow() {
|
||||
DCHECK(!entries_.empty());
|
||||
if (time_shift_buffer_depth_ <= 0.0 ||
|
||||
playlist_type_ != HlsPlaylistType::kLive) {
|
||||
if (hls_params_.time_shift_buffer_depth <= 0.0 ||
|
||||
hls_params_.playlist_type != HlsPlaylistType::kLive) {
|
||||
return;
|
||||
}
|
||||
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,
|
||||
// and this should guarantee that the latest segment will stay in the list.
|
||||
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;
|
||||
|
||||
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
|
||||
// remove <3> without removing <1> and <2> below (<1> and <2> are moved to the
|
||||
|
|
|
@ -58,17 +58,14 @@ class MediaPlaylist {
|
|||
kSampleAesCenc, // 'cenc' encrypted content.
|
||||
};
|
||||
|
||||
/// @param playlist_type is the type of this media playlist.
|
||||
/// @param time_shift_buffer_depth determines the duration of the time
|
||||
/// shifting buffer, only for live HLS.
|
||||
/// @param hls_params contains HLS parameters.
|
||||
/// @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
|
||||
/// value of the NAME attribute for EXT-X-MEDIA. This is not
|
||||
/// necessarily the same as @a file_name.
|
||||
/// @param group_id is the group ID for this playlist. This is the value of
|
||||
/// GROUP-ID attribute for EXT-X-MEDIA.
|
||||
MediaPlaylist(HlsPlaylistType playlist_type,
|
||||
double time_shift_buffer_depth,
|
||||
MediaPlaylist(const HlsParams& hls_params,
|
||||
const std::string& file_name,
|
||||
const std::string& name,
|
||||
const std::string& group_id);
|
||||
|
@ -192,8 +189,7 @@ class MediaPlaylist {
|
|||
// |sequence_number_| by the number of segments removed.
|
||||
void SlideWindow();
|
||||
|
||||
const HlsPlaylistType playlist_type_;
|
||||
const double time_shift_buffer_depth_;
|
||||
const HlsParams hls_params_;
|
||||
// Mainly for MasterPlaylist to use these values.
|
||||
const std::string file_name_;
|
||||
const std::string name_;
|
||||
|
|
|
@ -41,12 +41,13 @@ class MediaPlaylistTest : public ::testing::Test {
|
|||
MediaPlaylistTest(HlsPlaylistType type)
|
||||
: default_file_name_(kDefaultPlaylistFileName),
|
||||
default_name_("default_name"),
|
||||
default_group_id_("default_group_id"),
|
||||
media_playlist_(type,
|
||||
kTimeShiftBufferDepth,
|
||||
default_file_name_,
|
||||
default_name_,
|
||||
default_group_id_) {}
|
||||
default_group_id_("default_group_id") {
|
||||
HlsParams hls_params;
|
||||
hls_params.playlist_type = type;
|
||||
hls_params.time_shift_buffer_depth = kTimeShiftBufferDepth;
|
||||
media_playlist_.reset(new MediaPlaylist(hls_params, default_file_name_,
|
||||
default_name_, default_group_id_));
|
||||
}
|
||||
|
||||
void SetUp() override {
|
||||
SetPackagerVersionForTesting("test");
|
||||
|
@ -67,7 +68,7 @@ class MediaPlaylistTest : public ::testing::Test {
|
|||
const std::string default_file_name_;
|
||||
const std::string default_name_;
|
||||
const std::string default_group_id_;
|
||||
MediaPlaylist media_playlist_;
|
||||
std::unique_ptr<MediaPlaylist> media_playlist_;
|
||||
|
||||
MediaInfo valid_video_media_info_;
|
||||
};
|
||||
|
@ -96,7 +97,7 @@ class MediaPlaylistSingleSegmentTest : public MediaPlaylistTest {
|
|||
// Verify that SetMediaInfo() fails if timescale is not present.
|
||||
TEST_F(MediaPlaylistMultiSegmentTest, NoTimeScale) {
|
||||
MediaInfo media_info;
|
||||
EXPECT_FALSE(media_playlist_.SetMediaInfo(media_info));
|
||||
EXPECT_FALSE(media_playlist_->SetMediaInfo(media_info));
|
||||
}
|
||||
|
||||
TEST_F(MediaPlaylistMultiSegmentTest, SetMediaInfoText) {
|
||||
|
@ -104,7 +105,7 @@ TEST_F(MediaPlaylistMultiSegmentTest, SetMediaInfoText) {
|
|||
media_info.set_reference_time_scale(kTimeScale);
|
||||
MediaInfo::TextInfo* text_info = media_info.mutable_text_info();
|
||||
text_info->set_codec("wvtt");
|
||||
EXPECT_TRUE(media_playlist_.SetMediaInfo(media_info));
|
||||
EXPECT_TRUE(media_playlist_->SetMediaInfo(media_info));
|
||||
}
|
||||
|
||||
TEST_F(MediaPlaylistMultiSegmentTest, SetMediaInfo) {
|
||||
|
@ -113,13 +114,13 @@ TEST_F(MediaPlaylistMultiSegmentTest, SetMediaInfo) {
|
|||
MediaInfo::VideoInfo* video_info = media_info.mutable_video_info();
|
||||
video_info->set_width(1280);
|
||||
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).
|
||||
TEST_F(MediaPlaylistMultiSegmentTest, AddSegment) {
|
||||
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_));
|
||||
media_playlist_.AddSegment("file1.ts", 900000, 0, kZeroByteOffset, 1000000);
|
||||
ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
|
||||
media_playlist_->AddSegment("file1.ts", 900000, 0, kZeroByteOffset, 1000000);
|
||||
}
|
||||
|
||||
// Verify that it returns the display resolution.
|
||||
|
@ -132,10 +133,10 @@ TEST_F(MediaPlaylistMultiSegmentTest, GetDisplayResolution) {
|
|||
video_info->set_height(818);
|
||||
video_info->set_pixel_width(1636);
|
||||
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 height = 0;
|
||||
EXPECT_TRUE(media_playlist_.GetDisplayResolution(&width, &height));
|
||||
EXPECT_TRUE(media_playlist_->GetDisplayResolution(&width, &height));
|
||||
EXPECT_EQ(1921u, width);
|
||||
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_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";
|
||||
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath));
|
||||
EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
|
||||
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_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";
|
||||
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath));
|
||||
EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
|
||||
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_end(500);
|
||||
|
||||
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", 10 * kTimeScale, 10 * kTimeScale,
|
||||
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", 10 * kTimeScale, 10 * kTimeScale,
|
||||
1001000, 2 * kMBytes);
|
||||
|
||||
const char kMemoryFilePath[] = "memory://media.m3u8";
|
||||
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath));
|
||||
EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
|
||||
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
|
||||
}
|
||||
|
||||
// Verify that AddEncryptionInfo works (not crash).
|
||||
TEST_F(MediaPlaylistMultiSegmentTest, AddEncryptionInfo) {
|
||||
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_));
|
||||
media_playlist_.AddEncryptionInfo(MediaPlaylist::EncryptionMethod::kSampleAes,
|
||||
"http://example.com", "", "0xabcedf", "",
|
||||
"");
|
||||
ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
|
||||
media_playlist_->AddEncryptionInfo(
|
||||
MediaPlaylist::EncryptionMethod::kSampleAes, "http://example.com", "",
|
||||
"0xabcedf", "", "");
|
||||
}
|
||||
|
||||
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[] =
|
||||
"#EXTM3U\n"
|
||||
"#EXT-X-VERSION:6\n"
|
||||
|
@ -233,48 +235,48 @@ TEST_F(MediaPlaylistMultiSegmentTest, WriteToFile) {
|
|||
"#EXT-X-ENDLIST\n";
|
||||
|
||||
const char kMemoryFilePath[] = "memory://media.m3u8";
|
||||
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath));
|
||||
EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
|
||||
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
|
||||
}
|
||||
|
||||
// If bitrate (bandwidth) is not set in the MediaInfo, use it.
|
||||
TEST_F(MediaPlaylistMultiSegmentTest, UseBitrateInMediaInfo) {
|
||||
valid_video_media_info_.set_bandwidth(8191);
|
||||
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_));
|
||||
EXPECT_EQ(8191u, media_playlist_.Bitrate());
|
||||
ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
|
||||
EXPECT_EQ(8191u, media_playlist_->Bitrate());
|
||||
}
|
||||
|
||||
// If bitrate (bandwidth) is not set in the MediaInfo, then calculate from the
|
||||
// segments.
|
||||
TEST_F(MediaPlaylistMultiSegmentTest, GetBitrateFromSegments) {
|
||||
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);
|
||||
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 20 * kTimeScale,
|
||||
media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 20 * kTimeScale,
|
||||
kZeroByteOffset, 5 * kMBytes);
|
||||
|
||||
// Max bitrate is 2000Kb/s.
|
||||
EXPECT_EQ(2000000u, media_playlist_.Bitrate());
|
||||
EXPECT_EQ(2000000u, media_playlist_->Bitrate());
|
||||
}
|
||||
|
||||
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);
|
||||
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
|
||||
media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
|
||||
kZeroByteOffset, 5 * kMBytes);
|
||||
media_playlist_.AddSegment("file3.ts", 40 * kTimeScale, 14 * kTimeScale,
|
||||
media_playlist_->AddSegment("file3.ts", 40 * kTimeScale, 14 * kTimeScale,
|
||||
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) {
|
||||
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_));
|
||||
media_playlist_.SetTargetDuration(20);
|
||||
ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
|
||||
media_playlist_->SetTargetDuration(20);
|
||||
const std::string kExpectedOutput =
|
||||
"#EXTM3U\n"
|
||||
"#EXT-X-VERSION:6\n"
|
||||
|
@ -285,17 +287,17 @@ TEST_F(MediaPlaylistMultiSegmentTest, SetTargetDuration) {
|
|||
"#EXT-X-ENDLIST\n";
|
||||
|
||||
const char kMemoryFilePath[] = "memory://media.m3u8";
|
||||
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath));
|
||||
EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
|
||||
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
|
||||
}
|
||||
|
||||
TEST_F(MediaPlaylistMultiSegmentTest, WriteToFileWithSegments) {
|
||||
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);
|
||||
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
|
||||
media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
|
||||
kZeroByteOffset, 5 * kMBytes);
|
||||
const char kExpectedOutput[] =
|
||||
"#EXTM3U\n"
|
||||
|
@ -311,19 +313,19 @@ TEST_F(MediaPlaylistMultiSegmentTest, WriteToFileWithSegments) {
|
|||
"#EXT-X-ENDLIST\n";
|
||||
|
||||
const char kMemoryFilePath[] = "memory://media.m3u8";
|
||||
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath));
|
||||
EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
|
||||
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
|
||||
}
|
||||
|
||||
TEST_F(MediaPlaylistMultiSegmentTest,
|
||||
WriteToFileWithSegmentsAndPlacementOpportunity) {
|
||||
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);
|
||||
media_playlist_.AddPlacementOpportunity();
|
||||
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
|
||||
media_playlist_->AddPlacementOpportunity();
|
||||
media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
|
||||
kZeroByteOffset, 5 * kMBytes);
|
||||
const char kExpectedOutput[] =
|
||||
"#EXTM3U\n"
|
||||
|
@ -340,20 +342,20 @@ TEST_F(MediaPlaylistMultiSegmentTest,
|
|||
"#EXT-X-ENDLIST\n";
|
||||
|
||||
const char kMemoryFilePath[] = "memory://media.m3u8";
|
||||
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath));
|
||||
EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
|
||||
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
|
||||
}
|
||||
|
||||
TEST_F(MediaPlaylistMultiSegmentTest, WriteToFileWithEncryptionInfo) {
|
||||
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,
|
||||
"http://example.com", "", "0x12345678",
|
||||
"com.widevine", "1/2/4");
|
||||
media_playlist_.AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset,
|
||||
media_playlist_->AddEncryptionInfo(
|
||||
MediaPlaylist::EncryptionMethod::kSampleAes, "http://example.com", "",
|
||||
"0x12345678", "com.widevine", "1/2/4");
|
||||
media_playlist_->AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset,
|
||||
kMBytes);
|
||||
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
|
||||
media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
|
||||
kZeroByteOffset, 5 * kMBytes);
|
||||
const char kExpectedOutput[] =
|
||||
"#EXTM3U\n"
|
||||
|
@ -372,20 +374,20 @@ TEST_F(MediaPlaylistMultiSegmentTest, WriteToFileWithEncryptionInfo) {
|
|||
"#EXT-X-ENDLIST\n";
|
||||
|
||||
const char kMemoryFilePath[] = "memory://media.m3u8";
|
||||
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath));
|
||||
EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
|
||||
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
|
||||
}
|
||||
|
||||
TEST_F(MediaPlaylistMultiSegmentTest, WriteToFileWithEncryptionInfoEmptyIv) {
|
||||
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,
|
||||
"http://example.com", "", "",
|
||||
media_playlist_->AddEncryptionInfo(
|
||||
MediaPlaylist::EncryptionMethod::kSampleAes, "http://example.com", "", "",
|
||||
"com.widevine", "");
|
||||
media_playlist_.AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset,
|
||||
media_playlist_->AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset,
|
||||
kMBytes);
|
||||
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
|
||||
media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
|
||||
kZeroByteOffset, 5 * kMBytes);
|
||||
const char kExpectedOutput[] =
|
||||
"#EXTM3U\n"
|
||||
|
@ -403,22 +405,22 @@ TEST_F(MediaPlaylistMultiSegmentTest, WriteToFileWithEncryptionInfoEmptyIv) {
|
|||
"#EXT-X-ENDLIST\n";
|
||||
|
||||
const char kMemoryFilePath[] = "memory://media.m3u8";
|
||||
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath));
|
||||
EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
|
||||
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
|
||||
}
|
||||
|
||||
// Verify that EXT-X-DISCONTINUITY is inserted before EXT-X-KEY.
|
||||
TEST_F(MediaPlaylistMultiSegmentTest, WriteToFileWithClearLead) {
|
||||
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);
|
||||
|
||||
media_playlist_.AddEncryptionInfo(MediaPlaylist::EncryptionMethod::kSampleAes,
|
||||
"http://example.com", "", "0x12345678",
|
||||
"com.widevine", "1/2/4");
|
||||
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
|
||||
media_playlist_->AddEncryptionInfo(
|
||||
MediaPlaylist::EncryptionMethod::kSampleAes, "http://example.com", "",
|
||||
"0x12345678", "com.widevine", "1/2/4");
|
||||
media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
|
||||
kZeroByteOffset, 5 * kMBytes);
|
||||
const char kExpectedOutput[] =
|
||||
"#EXTM3U\n"
|
||||
|
@ -438,7 +440,7 @@ TEST_F(MediaPlaylistMultiSegmentTest, WriteToFileWithClearLead) {
|
|||
"#EXT-X-ENDLIST\n";
|
||||
|
||||
const char kMemoryFilePath[] = "memory://media.m3u8";
|
||||
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath));
|
||||
EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
|
||||
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
|
||||
}
|
||||
|
||||
|
@ -448,16 +450,16 @@ TEST_F(MediaPlaylistMultiSegmentTest, GetLanguage) {
|
|||
|
||||
// Check conversions from long to short form.
|
||||
media_info.mutable_audio_info()->set_language("eng");
|
||||
ASSERT_TRUE(media_playlist_.SetMediaInfo(media_info));
|
||||
EXPECT_EQ("en", media_playlist_.language()); // short form
|
||||
ASSERT_TRUE(media_playlist_->SetMediaInfo(media_info));
|
||||
EXPECT_EQ("en", media_playlist_->language()); // short form
|
||||
|
||||
media_info.mutable_audio_info()->set_language("eng-US");
|
||||
ASSERT_TRUE(media_playlist_.SetMediaInfo(media_info));
|
||||
EXPECT_EQ("en-US", media_playlist_.language()); // region preserved
|
||||
ASSERT_TRUE(media_playlist_->SetMediaInfo(media_info));
|
||||
EXPECT_EQ("en-US", media_playlist_->language()); // region preserved
|
||||
|
||||
media_info.mutable_audio_info()->set_language("apa");
|
||||
ASSERT_TRUE(media_playlist_.SetMediaInfo(media_info));
|
||||
EXPECT_EQ("apa", media_playlist_.language()); // no short form exists
|
||||
ASSERT_TRUE(media_playlist_->SetMediaInfo(media_info));
|
||||
EXPECT_EQ("apa", media_playlist_->language()); // no short form exists
|
||||
}
|
||||
|
||||
TEST_F(MediaPlaylistMultiSegmentTest, GetNumChannels) {
|
||||
|
@ -465,25 +467,25 @@ TEST_F(MediaPlaylistMultiSegmentTest, GetNumChannels) {
|
|||
media_info.set_reference_time_scale(kTimeScale);
|
||||
|
||||
// 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);
|
||||
ASSERT_TRUE(media_playlist_.SetMediaInfo(media_info));
|
||||
EXPECT_EQ(2, media_playlist_.GetNumChannels());
|
||||
ASSERT_TRUE(media_playlist_->SetMediaInfo(media_info));
|
||||
EXPECT_EQ(2, media_playlist_->GetNumChannels());
|
||||
|
||||
media_info.mutable_audio_info()->set_num_channels(8);
|
||||
ASSERT_TRUE(media_playlist_.SetMediaInfo(media_info));
|
||||
EXPECT_EQ(8, media_playlist_.GetNumChannels());
|
||||
ASSERT_TRUE(media_playlist_->SetMediaInfo(media_info));
|
||||
EXPECT_EQ(8, media_playlist_->GetNumChannels());
|
||||
}
|
||||
|
||||
TEST_F(MediaPlaylistMultiSegmentTest, InitSegment) {
|
||||
valid_video_media_info_.set_reference_time_scale(90000);
|
||||
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);
|
||||
media_playlist_.AddSegment("file2.mp4", 10 * kTimeScale, 30 * kTimeScale,
|
||||
media_playlist_->AddSegment("file2.mp4", 10 * kTimeScale, 30 * kTimeScale,
|
||||
kZeroByteOffset, 5 * kMBytes);
|
||||
|
||||
const char kExpectedOutput[] =
|
||||
|
@ -501,22 +503,22 @@ TEST_F(MediaPlaylistMultiSegmentTest, InitSegment) {
|
|||
"#EXT-X-ENDLIST\n";
|
||||
|
||||
const char kMemoryFilePath[] = "memory://media.m3u8";
|
||||
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath));
|
||||
EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
|
||||
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
|
||||
}
|
||||
|
||||
// Verify that kSampleAesCenc is handled correctly.
|
||||
TEST_F(MediaPlaylistMultiSegmentTest, SampleAesCenc) {
|
||||
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", "",
|
||||
"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);
|
||||
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
|
||||
media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
|
||||
kZeroByteOffset, 5 * kMBytes);
|
||||
const char kExpectedOutput[] =
|
||||
"#EXTM3U\n"
|
||||
|
@ -535,24 +537,24 @@ TEST_F(MediaPlaylistMultiSegmentTest, SampleAesCenc) {
|
|||
"#EXT-X-ENDLIST\n";
|
||||
|
||||
const char kMemoryFilePath[] = "memory://media.m3u8";
|
||||
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath));
|
||||
EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
|
||||
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
|
||||
}
|
||||
|
||||
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,
|
||||
"http://example.com", "", "0x12345678",
|
||||
"com.widevine", "1/2/4");
|
||||
media_playlist_->AddEncryptionInfo(
|
||||
MediaPlaylist::EncryptionMethod::kSampleAes, "http://example.com", "",
|
||||
"0x12345678", "com.widevine", "1/2/4");
|
||||
|
||||
media_playlist_.AddEncryptionInfo(
|
||||
media_playlist_->AddEncryptionInfo(
|
||||
MediaPlaylist::EncryptionMethod::kSampleAes, "http://mydomain.com",
|
||||
"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);
|
||||
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
|
||||
media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
|
||||
kZeroByteOffset, 5 * kMBytes);
|
||||
const char kExpectedOutput[] =
|
||||
"#EXTM3U\n"
|
||||
|
@ -575,7 +577,7 @@ TEST_F(MediaPlaylistMultiSegmentTest, MultipleEncryptionInfo) {
|
|||
"#EXT-X-ENDLIST\n";
|
||||
|
||||
const char kMemoryFilePath[] = "memory://media.m3u8";
|
||||
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath));
|
||||
EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
|
||||
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
|
||||
}
|
||||
|
||||
|
@ -586,11 +588,11 @@ class LiveMediaPlaylistTest : public MediaPlaylistMultiSegmentTest {
|
|||
};
|
||||
|
||||
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);
|
||||
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 20 * kTimeScale,
|
||||
media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 20 * kTimeScale,
|
||||
kZeroByteOffset, 2 * kMBytes);
|
||||
const char kExpectedOutput[] =
|
||||
"#EXTM3U\n"
|
||||
|
@ -604,18 +606,18 @@ TEST_F(LiveMediaPlaylistTest, Basic) {
|
|||
"file2.ts\n";
|
||||
|
||||
const char kMemoryFilePath[] = "memory://media.m3u8";
|
||||
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath));
|
||||
EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
|
||||
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
|
||||
}
|
||||
|
||||
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);
|
||||
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 20 * kTimeScale,
|
||||
media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 20 * kTimeScale,
|
||||
kZeroByteOffset, 2 * kMBytes);
|
||||
media_playlist_.AddSegment("file3.ts", 30 * kTimeScale, 20 * kTimeScale,
|
||||
media_playlist_->AddSegment("file3.ts", 30 * kTimeScale, 20 * kTimeScale,
|
||||
kZeroByteOffset, 2 * kMBytes);
|
||||
const char kExpectedOutput[] =
|
||||
"#EXTM3U\n"
|
||||
|
@ -630,25 +632,25 @@ TEST_F(LiveMediaPlaylistTest, TimeShifted) {
|
|||
"file3.ts\n";
|
||||
|
||||
const char kMemoryFilePath[] = "memory://media.m3u8";
|
||||
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath));
|
||||
EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
|
||||
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
|
||||
}
|
||||
|
||||
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,
|
||||
"http://example.com", "", "0x12345678",
|
||||
"com.widevine", "1/2/4");
|
||||
media_playlist_.AddEncryptionInfo(
|
||||
media_playlist_->AddEncryptionInfo(
|
||||
MediaPlaylist::EncryptionMethod::kSampleAes, "http://example.com", "",
|
||||
"0x12345678", "com.widevine", "1/2/4");
|
||||
media_playlist_->AddEncryptionInfo(
|
||||
MediaPlaylist::EncryptionMethod::kSampleAes, "http://mydomain.com",
|
||||
"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);
|
||||
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 20 * kTimeScale,
|
||||
media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 20 * kTimeScale,
|
||||
kZeroByteOffset, 2 * kMBytes);
|
||||
media_playlist_.AddSegment("file3.ts", 30 * kTimeScale, 20 * kTimeScale,
|
||||
media_playlist_->AddSegment("file3.ts", 30 * kTimeScale, 20 * kTimeScale,
|
||||
kZeroByteOffset, 2 * kMBytes);
|
||||
const char kExpectedOutput[] =
|
||||
"#EXTM3U\n"
|
||||
|
@ -670,44 +672,44 @@ TEST_F(LiveMediaPlaylistTest, TimeShiftedWithEncryptionInfo) {
|
|||
"file3.ts\n";
|
||||
|
||||
const char kMemoryFilePath[] = "memory://media.m3u8";
|
||||
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath));
|
||||
EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
|
||||
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
media_playlist_.AddEncryptionInfo(MediaPlaylist::EncryptionMethod::kSampleAes,
|
||||
"http://example.com", "", "0x12345678",
|
||||
"com.widevine", "1/2/4");
|
||||
media_playlist_.AddEncryptionInfo(
|
||||
media_playlist_->AddEncryptionInfo(
|
||||
MediaPlaylist::EncryptionMethod::kSampleAes, "http://example.com", "",
|
||||
"0x12345678", "com.widevine", "1/2/4");
|
||||
media_playlist_->AddEncryptionInfo(
|
||||
MediaPlaylist::EncryptionMethod::kSampleAes, "http://mydomain.com",
|
||||
"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);
|
||||
|
||||
media_playlist_.AddEncryptionInfo(MediaPlaylist::EncryptionMethod::kSampleAes,
|
||||
"http://example.com", "", "0x22345678",
|
||||
"com.widevine", "1/2/4");
|
||||
media_playlist_.AddEncryptionInfo(
|
||||
media_playlist_->AddEncryptionInfo(
|
||||
MediaPlaylist::EncryptionMethod::kSampleAes, "http://example.com", "",
|
||||
"0x22345678", "com.widevine", "1/2/4");
|
||||
media_playlist_->AddEncryptionInfo(
|
||||
MediaPlaylist::EncryptionMethod::kSampleAes, "http://mydomain.com",
|
||||
"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);
|
||||
|
||||
media_playlist_.AddEncryptionInfo(MediaPlaylist::EncryptionMethod::kSampleAes,
|
||||
"http://example.com", "", "0x32345678",
|
||||
"com.widevine", "1/2/4");
|
||||
media_playlist_.AddEncryptionInfo(
|
||||
media_playlist_->AddEncryptionInfo(
|
||||
MediaPlaylist::EncryptionMethod::kSampleAes, "http://example.com", "",
|
||||
"0x32345678", "com.widevine", "1/2/4");
|
||||
media_playlist_->AddEncryptionInfo(
|
||||
MediaPlaylist::EncryptionMethod::kSampleAes, "http://mydomain.com",
|
||||
"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);
|
||||
const char kExpectedOutput[] =
|
||||
"#EXTM3U\n"
|
||||
|
@ -737,7 +739,7 @@ TEST_F(LiveMediaPlaylistTest, TimeShiftedWithEncryptionInfoShifted) {
|
|||
"file4.ts\n";
|
||||
|
||||
const char kMemoryFilePath[] = "memory://media.m3u8";
|
||||
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath));
|
||||
EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
|
||||
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
|
||||
}
|
||||
|
||||
|
@ -748,11 +750,11 @@ class EventMediaPlaylistTest : public MediaPlaylistMultiSegmentTest {
|
|||
};
|
||||
|
||||
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);
|
||||
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 20 * kTimeScale,
|
||||
media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 20 * kTimeScale,
|
||||
kZeroByteOffset, 2 * kMBytes);
|
||||
const char kExpectedOutput[] =
|
||||
"#EXTM3U\n"
|
||||
|
@ -767,21 +769,21 @@ TEST_F(EventMediaPlaylistTest, Basic) {
|
|||
"file2.ts\n";
|
||||
|
||||
const char kMemoryFilePath[] = "memory://media.m3u8";
|
||||
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath));
|
||||
EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
|
||||
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
|
||||
}
|
||||
|
||||
class IFrameMediaPlaylistTest : public MediaPlaylistTest {};
|
||||
|
||||
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,
|
||||
media_playlist_.stream_type());
|
||||
media_playlist_.AddKeyFrame(0, 1000, 2345);
|
||||
media_playlist_->stream_type());
|
||||
media_playlist_->AddKeyFrame(0, 1000, 2345);
|
||||
// Playlist stream type is updated to I-Frames only after seeing
|
||||
// |AddKeyFrame|.
|
||||
EXPECT_EQ(MediaPlaylist::MediaPlaylistStreamType::kVideoIFramesOnly,
|
||||
media_playlist_.stream_type());
|
||||
media_playlist_->stream_type());
|
||||
}
|
||||
|
||||
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_end(500);
|
||||
|
||||
ASSERT_TRUE(media_playlist_.SetMediaInfo(valid_video_media_info_));
|
||||
media_playlist_.AddKeyFrame(0, 1000, 2345);
|
||||
media_playlist_.AddKeyFrame(2 * kTimeScale, 5000, 6345);
|
||||
media_playlist_.AddSegment("file.mp4", 0, 10 * kTimeScale, kZeroByteOffset,
|
||||
ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_));
|
||||
media_playlist_->AddKeyFrame(0, 1000, 2345);
|
||||
media_playlist_->AddKeyFrame(2 * kTimeScale, 5000, 6345);
|
||||
media_playlist_->AddSegment("file.mp4", 0, 10 * kTimeScale, kZeroByteOffset,
|
||||
kMBytes);
|
||||
media_playlist_.AddKeyFrame(11 * kTimeScale, kMBytes + 1000, 2345);
|
||||
media_playlist_.AddKeyFrame(15 * kTimeScale, kMBytes + 3345, 12345);
|
||||
media_playlist_.AddSegment("file.mp4", 10 * kTimeScale, 10 * kTimeScale,
|
||||
media_playlist_->AddKeyFrame(11 * kTimeScale, kMBytes + 1000, 2345);
|
||||
media_playlist_->AddKeyFrame(15 * kTimeScale, kMBytes + 3345, 12345);
|
||||
media_playlist_->AddSegment("file.mp4", 10 * kTimeScale, 10 * kTimeScale,
|
||||
1001000, 2 * kMBytes);
|
||||
|
||||
const char kExpectedOutput[] =
|
||||
|
@ -823,21 +825,22 @@ TEST_F(IFrameMediaPlaylistTest, SingleSegment) {
|
|||
"#EXT-X-ENDLIST\n";
|
||||
|
||||
const char kMemoryFilePath[] = "memory://media.m3u8";
|
||||
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath));
|
||||
EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
|
||||
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
|
||||
}
|
||||
|
||||
TEST_F(IFrameMediaPlaylistTest, MultiSegment) {
|
||||
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(2 * kTimeScale, 5000, 6345);
|
||||
media_playlist_.AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset,
|
||||
media_playlist_->AddKeyFrame(0, 1000, 2345);
|
||||
media_playlist_->AddKeyFrame(2 * kTimeScale, 5000, 6345);
|
||||
media_playlist_->AddSegment("file1.ts", 0, 10 * kTimeScale, kZeroByteOffset,
|
||||
kMBytes);
|
||||
media_playlist_.AddKeyFrame(11 * kTimeScale, 1000, 2345);
|
||||
media_playlist_.AddKeyFrame(15 * kTimeScale, 3345, 12345);
|
||||
media_playlist_.AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
|
||||
media_playlist_->AddKeyFrame(11 * kTimeScale, 1000, 2345);
|
||||
media_playlist_->AddKeyFrame(15 * kTimeScale, 3345, 12345);
|
||||
media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 30 * kTimeScale,
|
||||
kZeroByteOffset, 5 * kMBytes);
|
||||
|
||||
const char kExpectedOutput[] =
|
||||
|
@ -863,7 +866,7 @@ TEST_F(IFrameMediaPlaylistTest, MultiSegment) {
|
|||
"#EXT-X-ENDLIST\n";
|
||||
|
||||
const char kMemoryFilePath[] = "memory://media.m3u8";
|
||||
EXPECT_TRUE(media_playlist_.WriteToFile(kMemoryFilePath));
|
||||
EXPECT_TRUE(media_playlist_->WriteToFile(kMemoryFilePath));
|
||||
ASSERT_FILE_STREQ(kMemoryFilePath, kExpectedOutput);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,14 +6,15 @@
|
|||
|
||||
#include "packager/hls/base/mock_media_playlist.h"
|
||||
|
||||
#include "packager/hls/public/hls_params.h"
|
||||
|
||||
namespace shaka {
|
||||
namespace hls {
|
||||
|
||||
MockMediaPlaylist::MockMediaPlaylist(HlsPlaylistType type,
|
||||
const std::string& file_name,
|
||||
MockMediaPlaylist::MockMediaPlaylist(const std::string& file_name,
|
||||
const std::string& name,
|
||||
const std::string& group_id)
|
||||
: MediaPlaylist(type, 0, file_name, name, group_id) {}
|
||||
: MediaPlaylist(HlsParams(), file_name, name, group_id) {}
|
||||
MockMediaPlaylist::~MockMediaPlaylist() {}
|
||||
|
||||
} // namespace hls
|
||||
|
|
|
@ -18,8 +18,7 @@ class MockMediaPlaylist : public MediaPlaylist {
|
|||
public:
|
||||
// The actual parameters to MediaPlaylist() (parent) constructor doesn't
|
||||
// matter because the return value can be mocked.
|
||||
MockMediaPlaylist(HlsPlaylistType type,
|
||||
const std::string& file_name,
|
||||
MockMediaPlaylist(const std::string& file_name,
|
||||
const std::string& name,
|
||||
const std::string& group_id);
|
||||
~MockMediaPlaylist() override;
|
||||
|
|
|
@ -104,6 +104,30 @@ std::string GenerateSegmentUrl(const std::string& segment_name,
|
|||
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,
|
||||
const std::vector<uint8_t>& key_id,
|
||||
std::string* pssh_json) {
|
||||
|
@ -240,20 +264,16 @@ bool WriteMediaPlaylist(const std::string& output_dir,
|
|||
MediaPlaylistFactory::~MediaPlaylistFactory() {}
|
||||
|
||||
std::unique_ptr<MediaPlaylist> MediaPlaylistFactory::Create(
|
||||
HlsPlaylistType type,
|
||||
double time_shift_buffer_depth,
|
||||
const HlsParams& hls_params,
|
||||
const std::string& file_name,
|
||||
const std::string& name,
|
||||
const std::string& group_id) {
|
||||
return std::unique_ptr<MediaPlaylist>(new MediaPlaylist(
|
||||
type, time_shift_buffer_depth, file_name, name, group_id));
|
||||
return std::unique_ptr<MediaPlaylist>(
|
||||
new MediaPlaylist(hls_params, file_name, name, group_id));
|
||||
}
|
||||
|
||||
SimpleHlsNotifier::SimpleHlsNotifier(const HlsParams& hls_params)
|
||||
: HlsNotifier(hls_params.playlist_type),
|
||||
time_shift_buffer_depth_(hls_params.time_shift_buffer_depth),
|
||||
prefix_(hls_params.base_url),
|
||||
key_uri_(hls_params.key_uri),
|
||||
: HlsNotifier(hls_params),
|
||||
media_playlist_factory_(new MediaPlaylistFactory()) {
|
||||
const base::FilePath master_playlist_path(
|
||||
base::FilePath::FromUTF8Unsafe(hls_params.master_playlist_output));
|
||||
|
@ -277,27 +297,12 @@ bool SimpleHlsNotifier::NotifyNewStream(const MediaInfo& media_info,
|
|||
DCHECK(stream_id);
|
||||
|
||||
std::unique_ptr<MediaPlaylist> media_playlist =
|
||||
media_playlist_factory_->Create(playlist_type(), time_shift_buffer_depth_,
|
||||
playlist_name, name, group_id);
|
||||
|
||||
// Update init_segment_name to be relative to playlist path if needed.
|
||||
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(), 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)) {
|
||||
media_playlist_factory_->Create(hls_params(), playlist_name, name,
|
||||
group_id);
|
||||
MediaInfo adjusted_media_info = MakeMediaInfoPathsRelativeToPlaylist(
|
||||
media_info, hls_params().base_url, output_dir_,
|
||||
media_playlist->file_name());
|
||||
if (!media_playlist->SetMediaInfo(adjusted_media_info)) {
|
||||
LOG(ERROR) << "Failed to set media info for playlist " << playlist_name;
|
||||
return false;
|
||||
}
|
||||
|
@ -338,8 +343,9 @@ bool SimpleHlsNotifier::NotifyNewSegment(uint32_t stream_id,
|
|||
return false;
|
||||
}
|
||||
auto& media_playlist = stream_iterator->second->media_playlist;
|
||||
const std::string& segment_url = GenerateSegmentUrl(
|
||||
segment_name, prefix_, output_dir_, media_playlist->file_name());
|
||||
const std::string& segment_url =
|
||||
GenerateSegmentUrl(segment_name, hls_params().base_url, output_dir_,
|
||||
media_playlist->file_name());
|
||||
media_playlist->AddSegment(segment_url, start_time, duration,
|
||||
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.
|
||||
if (playlist_type() == HlsPlaylistType::kLive ||
|
||||
playlist_type() == HlsPlaylistType::kEvent) {
|
||||
if (hls_params().playlist_type == HlsPlaylistType::kLive ||
|
||||
hls_params().playlist_type == HlsPlaylistType::kEvent) {
|
||||
// Update all playlists if target duration is updated.
|
||||
if (target_duration_updated) {
|
||||
for (MediaPlaylist* playlist : media_playlists_) {
|
||||
|
@ -366,8 +372,8 @@ bool SimpleHlsNotifier::NotifyNewSegment(uint32_t stream_id,
|
|||
if (!WriteMediaPlaylist(output_dir_, media_playlist.get()))
|
||||
return false;
|
||||
}
|
||||
if (!master_playlist_->WriteMasterPlaylist(prefix_, output_dir_,
|
||||
media_playlists_)) {
|
||||
if (!master_playlist_->WriteMasterPlaylist(hls_params().base_url,
|
||||
output_dir_, media_playlists_)) {
|
||||
LOG(ERROR) << "Failed to write master playlist.";
|
||||
return false;
|
||||
}
|
||||
|
@ -431,10 +437,8 @@ bool SimpleHlsNotifier::NotifyEncryptionUpdate(
|
|||
const std::vector<uint8_t> empty_key_id;
|
||||
|
||||
if (IsCommonSystemId(system_id)) {
|
||||
std::string key_uri;
|
||||
if (!key_uri_.empty()) {
|
||||
key_uri = key_uri_;
|
||||
} else {
|
||||
std::string key_uri = hls_params().key_uri;
|
||||
if (key_uri.empty()) {
|
||||
// Use key_id as the key_uri. The player needs to have custom logic to
|
||||
// convert it to the actual key uri.
|
||||
std::string key_uri_data = VectorToString(key_id);
|
||||
|
@ -444,10 +448,8 @@ bool SimpleHlsNotifier::NotifyEncryptionUpdate(
|
|||
iv, "identity", "", media_playlist.get());
|
||||
return true;
|
||||
} else if (IsFairplaySystemId(system_id)) {
|
||||
std::string key_uri;
|
||||
if (!key_uri_.empty()) {
|
||||
key_uri = key_uri_;
|
||||
} else {
|
||||
std::string key_uri = hls_params().key_uri;
|
||||
if (key_uri.empty()) {
|
||||
// Use key_id as the key_uri. The player needs to have custom logic to
|
||||
// convert it to the actual key uri.
|
||||
std::string key_uri_data = VectorToString(key_id);
|
||||
|
@ -474,7 +476,7 @@ bool SimpleHlsNotifier::Flush() {
|
|||
if (!WriteMediaPlaylist(output_dir_, playlist))
|
||||
return false;
|
||||
}
|
||||
if (!master_playlist_->WriteMasterPlaylist(prefix_, output_dir_,
|
||||
if (!master_playlist_->WriteMasterPlaylist(hls_params().base_url, output_dir_,
|
||||
media_playlists_)) {
|
||||
LOG(ERROR) << "Failed to write master playlist.";
|
||||
return false;
|
||||
|
|
|
@ -29,8 +29,7 @@ namespace hls {
|
|||
class MediaPlaylistFactory {
|
||||
public:
|
||||
virtual ~MediaPlaylistFactory();
|
||||
virtual std::unique_ptr<MediaPlaylist> Create(HlsPlaylistType type,
|
||||
double time_shift_buffer_depth,
|
||||
virtual std::unique_ptr<MediaPlaylist> Create(const HlsParams& hls_params,
|
||||
const std::string& file_name,
|
||||
const std::string& name,
|
||||
const std::string& group_id);
|
||||
|
@ -79,9 +78,6 @@ class SimpleHlsNotifier : public HlsNotifier {
|
|||
MediaPlaylist::EncryptionMethod encryption_method;
|
||||
};
|
||||
|
||||
const double time_shift_buffer_depth_ = 0;
|
||||
const std::string prefix_;
|
||||
const std::string key_uri_;
|
||||
std::string output_dir_;
|
||||
uint32_t target_duration_ = 0;
|
||||
|
||||
|
|
|
@ -54,20 +54,18 @@ class MockMasterPlaylist : public MasterPlaylist {
|
|||
|
||||
class MockMediaPlaylistFactory : public MediaPlaylistFactory {
|
||||
public:
|
||||
MOCK_METHOD5(CreateMock,
|
||||
MediaPlaylist*(HlsPlaylistType type,
|
||||
double time_shift_buffer_depth,
|
||||
MOCK_METHOD4(CreateMock,
|
||||
MediaPlaylist*(const HlsParams& hls_params,
|
||||
const std::string& file_name,
|
||||
const std::string& name,
|
||||
const std::string& group_id));
|
||||
|
||||
std::unique_ptr<MediaPlaylist> Create(HlsPlaylistType type,
|
||||
double time_shift_buffer_depth,
|
||||
std::unique_ptr<MediaPlaylist> Create(const HlsParams& hls_params,
|
||||
const std::string& file_name,
|
||||
const std::string& name,
|
||||
const std::string& group_id) override {
|
||||
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());
|
||||
|
||||
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
|
||||
EXPECT_CALL(*factory, CreateMock(_, _, _, _, _))
|
||||
EXPECT_CALL(*factory, CreateMock(_, _, _, _))
|
||||
.WillOnce(Return(mock_media_playlist));
|
||||
|
||||
InjectMasterPlaylist(std::move(mock_master_playlist), notifier);
|
||||
|
@ -167,7 +165,7 @@ TEST_F(SimpleHlsNotifierTest, RebaseSegmentUrl) {
|
|||
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||
new MockMediaPlaylist("playlist.m3u8", "", "");
|
||||
|
||||
EXPECT_CALL(*mock_media_playlist,
|
||||
SetMediaInfo(Property(&MediaInfo::init_segment_url, StrEq(""))))
|
||||
|
@ -177,9 +175,8 @@ TEST_F(SimpleHlsNotifierTest, RebaseSegmentUrl) {
|
|||
EXPECT_CALL(
|
||||
*mock_media_playlist,
|
||||
AddSegment("http://testprefix.com/path/to/media1.ts", _, _, _, _));
|
||||
EXPECT_CALL(*factory, CreateMock(kVodPlaylist, Eq(kTestTimeShiftBufferDepth),
|
||||
StrEq("video_playlist.m3u8"), StrEq("name"),
|
||||
StrEq("groupid")))
|
||||
EXPECT_CALL(*factory, CreateMock(_, StrEq("video_playlist.m3u8"),
|
||||
StrEq("name"), StrEq("groupid")))
|
||||
.WillOnce(Return(mock_media_playlist));
|
||||
|
||||
SimpleHlsNotifier notifier(hls_params_);
|
||||
|
@ -206,7 +203,7 @@ TEST_F(SimpleHlsNotifierTest, RebaseInitSegmentUrl) {
|
|||
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||
new MockMediaPlaylist("playlist.m3u8", "", "");
|
||||
|
||||
// Verify that the common prefix is stripped in init segment.
|
||||
EXPECT_CALL(
|
||||
|
@ -215,9 +212,8 @@ TEST_F(SimpleHlsNotifierTest, RebaseInitSegmentUrl) {
|
|||
StrEq("http://testprefix.com/path/to/init.mp4"))))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_CALL(*factory, CreateMock(kVodPlaylist, Eq(kTestTimeShiftBufferDepth),
|
||||
StrEq("video_playlist.m3u8"), StrEq("name"),
|
||||
StrEq("groupid")))
|
||||
EXPECT_CALL(*factory, CreateMock(_, StrEq("video_playlist.m3u8"),
|
||||
StrEq("name"), StrEq("groupid")))
|
||||
.WillOnce(Return(mock_media_playlist));
|
||||
|
||||
SimpleHlsNotifier notifier(hls_params_);
|
||||
|
@ -241,7 +237,7 @@ TEST_F(SimpleHlsNotifierTest, RebaseSegmentUrlRelativeToPlaylist) {
|
|||
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
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.
|
||||
EXPECT_CALL(*mock_media_playlist,
|
||||
|
@ -252,9 +248,8 @@ TEST_F(SimpleHlsNotifierTest, RebaseSegmentUrlRelativeToPlaylist) {
|
|||
// Verify that the segment URL is relative to playlist path.
|
||||
EXPECT_CALL(*mock_media_playlist,
|
||||
AddSegment(StrEq("path/to/media1.m4s"), _, _, _, _));
|
||||
EXPECT_CALL(*factory, CreateMock(kVodPlaylist, Eq(kTestTimeShiftBufferDepth),
|
||||
StrEq("video/playlist.m3u8"), StrEq("name"),
|
||||
StrEq("groupid")))
|
||||
EXPECT_CALL(*factory, CreateMock(_, StrEq("video/playlist.m3u8"),
|
||||
StrEq("name"), StrEq("groupid")))
|
||||
.WillOnce(Return(mock_media_playlist));
|
||||
|
||||
hls_params_.base_url = kEmptyPrefix;
|
||||
|
@ -289,16 +284,15 @@ TEST_F(SimpleHlsNotifierTest, RebaseAbsoluteSegmentPrefixAndOutputDirMatch) {
|
|||
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||
new MockMediaPlaylist("playlist.m3u8", "", "");
|
||||
|
||||
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
|
||||
|
||||
// Verify that the output_dir is stripped and then kTestPrefix is prepended.
|
||||
EXPECT_CALL(*mock_media_playlist,
|
||||
AddSegment("http://testprefix.com/media1.ts", _, _, _, _));
|
||||
EXPECT_CALL(*factory, CreateMock(kVodPlaylist, Eq(kTestTimeShiftBufferDepth),
|
||||
StrEq("video_playlist.m3u8"), StrEq("name"),
|
||||
StrEq("groupid")))
|
||||
EXPECT_CALL(*factory, CreateMock(_, StrEq("video_playlist.m3u8"),
|
||||
StrEq("name"), StrEq("groupid")))
|
||||
.WillOnce(Return(mock_media_playlist));
|
||||
|
||||
InjectMasterPlaylist(std::move(mock_master_playlist), &test_notifier);
|
||||
|
@ -330,15 +324,14 @@ TEST_F(SimpleHlsNotifierTest,
|
|||
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
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,
|
||||
AddSegment("http://testprefix.com//var/somewhereelse/media1.ts",
|
||||
_, _, _, _));
|
||||
EXPECT_CALL(*factory, CreateMock(kVodPlaylist, Eq(kTestTimeShiftBufferDepth),
|
||||
StrEq("video_playlist.m3u8"), StrEq("name"),
|
||||
StrEq("groupid")))
|
||||
EXPECT_CALL(*factory, CreateMock(_, StrEq("video_playlist.m3u8"),
|
||||
StrEq("name"), StrEq("groupid")))
|
||||
.WillOnce(Return(mock_media_playlist));
|
||||
|
||||
InjectMasterPlaylist(std::move(mock_master_playlist), &test_notifier);
|
||||
|
@ -374,12 +367,11 @@ TEST_F(SimpleHlsNotifierTest, NotifyNewStream) {
|
|||
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||
new MockMediaPlaylist("playlist.m3u8", "", "");
|
||||
|
||||
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
|
||||
EXPECT_CALL(*factory, CreateMock(kVodPlaylist, Eq(kTestTimeShiftBufferDepth),
|
||||
StrEq("video_playlist.m3u8"), StrEq("name"),
|
||||
StrEq("groupid")))
|
||||
EXPECT_CALL(*factory, CreateMock(_, StrEq("video_playlist.m3u8"),
|
||||
StrEq("name"), StrEq("groupid")))
|
||||
.WillOnce(Return(mock_media_playlist));
|
||||
|
||||
SimpleHlsNotifier notifier(hls_params_);
|
||||
|
@ -402,10 +394,10 @@ TEST_F(SimpleHlsNotifierTest, NotifyNewSegment) {
|
|||
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||
new MockMediaPlaylist("playlist.m3u8", "", "");
|
||||
|
||||
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
|
||||
EXPECT_CALL(*factory, CreateMock(_, _, _, _, _))
|
||||
EXPECT_CALL(*factory, CreateMock(_, _, _, _))
|
||||
.WillOnce(Return(mock_media_playlist));
|
||||
|
||||
const uint64_t kStartTime = 1328;
|
||||
|
@ -455,7 +447,7 @@ TEST_F(SimpleHlsNotifierTest, NotifyNewSegment) {
|
|||
TEST_F(SimpleHlsNotifierTest, NotifyKeyFrame) {
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||
new MockMediaPlaylist("playlist.m3u8", "", "");
|
||||
SimpleHlsNotifier notifier(hls_params_);
|
||||
const uint32_t stream_id =
|
||||
SetupStream(kCencProtectionScheme, mock_media_playlist, ¬ifier);
|
||||
|
@ -478,7 +470,7 @@ TEST_F(SimpleHlsNotifierTest, NotifyNewSegmentWithoutStreamsRegistered) {
|
|||
TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateWidevine) {
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||
new MockMediaPlaylist("playlist.m3u8", "", "");
|
||||
SimpleHlsNotifier notifier(hls_params_);
|
||||
const uint32_t stream_id =
|
||||
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, ¬ifier);
|
||||
|
@ -539,7 +531,7 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateWidevine) {
|
|||
TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateWidevineNoKeyidsInPssh) {
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||
new MockMediaPlaylist("playlist.m3u8", "", "");
|
||||
SimpleHlsNotifier notifier(hls_params_);
|
||||
const uint32_t stream_id =
|
||||
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, ¬ifier);
|
||||
|
@ -596,7 +588,7 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateWidevineNoKeyidsInPssh) {
|
|||
TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateIdentityKey) {
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||
new MockMediaPlaylist("playlist.m3u8", "", "");
|
||||
SimpleHlsNotifier notifier(hls_params_);
|
||||
const uint32_t stream_id =
|
||||
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, ¬ifier);
|
||||
|
@ -624,7 +616,7 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateIdentityKey) {
|
|||
TEST_F(SimpleHlsNotifierTest, WidevineMultipleKeyIdsNoContentIdInPssh) {
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||
new MockMediaPlaylist("playlist.m3u8", "", "");
|
||||
SimpleHlsNotifier notifier(hls_params_);
|
||||
uint32_t stream_id =
|
||||
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, ¬ifier);
|
||||
|
@ -700,7 +692,7 @@ TEST_F(SimpleHlsNotifierTest, WidevineMultipleKeyIdsNoContentIdInPssh) {
|
|||
TEST_F(SimpleHlsNotifierTest, EncryptionScheme) {
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||
new MockMediaPlaylist("playlist.m3u8", "", "");
|
||||
hls_params_.key_uri = kIdentityKeyUri;
|
||||
SimpleHlsNotifier notifier(hls_params_);
|
||||
const uint32_t stream_id =
|
||||
|
@ -724,7 +716,7 @@ TEST_F(SimpleHlsNotifierTest, EncryptionScheme) {
|
|||
TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateFairplay) {
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kLivePlaylist, "playlist.m3u8", "", "");
|
||||
new MockMediaPlaylist("playlist.m3u8", "", "");
|
||||
hls_params_.playlist_type = kLivePlaylist;
|
||||
hls_params_.key_uri = kFairplayKeyUri;
|
||||
SimpleHlsNotifier notifier(hls_params_);
|
||||
|
@ -747,7 +739,7 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateFairplay) {
|
|||
TEST_F(SimpleHlsNotifierTest, WidevineCencEncryptionScheme) {
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||
new MockMediaPlaylist("playlist.m3u8", "", "");
|
||||
SimpleHlsNotifier notifier(hls_params_);
|
||||
const uint32_t stream_id =
|
||||
SetupStream(kCencProtectionScheme, mock_media_playlist, ¬ifier);
|
||||
|
@ -794,7 +786,7 @@ TEST_F(SimpleHlsNotifierTest, WidevineCencEncryptionScheme) {
|
|||
TEST_F(SimpleHlsNotifierTest, WidevineNotifyEncryptionUpdateEmptyIv) {
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||
new MockMediaPlaylist("playlist.m3u8", "", "");
|
||||
SimpleHlsNotifier notifier(hls_params_);
|
||||
const uint32_t stream_id =
|
||||
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, ¬ifier);
|
||||
|
@ -870,7 +862,7 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateWithoutStreamsRegistered) {
|
|||
TEST_F(SimpleHlsNotifierTest, NotifyCueEvent) {
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||
new MockMediaPlaylist("playlist.m3u8", "", "");
|
||||
SimpleHlsNotifier notifier(hls_params_);
|
||||
const uint32_t stream_id =
|
||||
SetupStream(kCencProtectionScheme, mock_media_playlist, ¬ifier);
|
||||
|
@ -899,10 +891,10 @@ TEST_P(LiveOrEventSimpleHlsNotifierTest, NotifyNewSegment) {
|
|||
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
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(*factory, CreateMock(expected_playlist_type_, _, _, _, _))
|
||||
EXPECT_CALL(*factory, CreateMock(_, _, _, _))
|
||||
.WillOnce(Return(mock_media_playlist));
|
||||
|
||||
const uint64_t kStartTime = 1328;
|
||||
|
@ -958,14 +950,14 @@ TEST_P(LiveOrEventSimpleHlsNotifierTest, NotifyNewSegmentsWithMultipleStreams) {
|
|||
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
MockMediaPlaylist* mock_media_playlist1 =
|
||||
new MockMediaPlaylist(expected_playlist_type_, "playlist1.m3u8", "", "");
|
||||
new MockMediaPlaylist("playlist1.m3u8", "", "");
|
||||
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));
|
||||
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));
|
||||
EXPECT_CALL(*mock_media_playlist2, SetMediaInfo(_)).WillOnce(Return(true));
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace {
|
|||
|
||||
class MockHlsNotifier : public hls::HlsNotifier {
|
||||
public:
|
||||
MockHlsNotifier() : HlsNotifier(HlsPlaylistType::kVod) {}
|
||||
MockHlsNotifier() : HlsNotifier(HlsParams()) {}
|
||||
|
||||
MOCK_METHOD0(Init, bool());
|
||||
MOCK_METHOD5(NotifyNewStream,
|
||||
|
|
Loading…
Reference in New Issue