Consolidate various playlist_type types
Change-Id: If6fafc0867e7e1f3cd2ed612617e91c7cb144f20
This commit is contained in:
parent
61c58724ec
commit
b451d3a7ca
|
@ -22,6 +22,7 @@
|
||||||
#include "packager/base/optional.h"
|
#include "packager/base/optional.h"
|
||||||
#include "packager/base/strings/string_number_conversions.h"
|
#include "packager/base/strings/string_number_conversions.h"
|
||||||
#include "packager/base/strings/string_split.h"
|
#include "packager/base/strings/string_split.h"
|
||||||
|
#include "packager/base/strings/string_util.h"
|
||||||
#include "packager/base/strings/stringprintf.h"
|
#include "packager/base/strings/stringprintf.h"
|
||||||
#include "packager/file/file.h"
|
#include "packager/file/file.h"
|
||||||
#include "packager/packager.h"
|
#include "packager/packager.h"
|
||||||
|
@ -118,6 +119,21 @@ bool GetWidevineSigner(WidevineSigner* signer) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GetHlsPlaylistType(const std::string& playlist_type,
|
||||||
|
HlsPlaylistType* playlist_type_enum) {
|
||||||
|
if (base::ToUpperASCII(playlist_type) == "VOD") {
|
||||||
|
*playlist_type_enum = HlsPlaylistType::kVod;
|
||||||
|
} else if (base::ToUpperASCII(playlist_type) == "LIVE") {
|
||||||
|
*playlist_type_enum = HlsPlaylistType::kLive;
|
||||||
|
} else if (base::ToUpperASCII(playlist_type) == "EVENT") {
|
||||||
|
*playlist_type_enum = HlsPlaylistType::kEvent;
|
||||||
|
} else {
|
||||||
|
LOG(ERROR) << "Unrecognized playlist type " << playlist_type;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
base::Optional<PackagingParams> GetPackagingParams() {
|
base::Optional<PackagingParams> GetPackagingParams() {
|
||||||
PackagingParams packaging_params;
|
PackagingParams packaging_params;
|
||||||
|
|
||||||
|
@ -263,14 +279,7 @@ base::Optional<PackagingParams> GetPackagingParams() {
|
||||||
mpd_params.default_language = FLAGS_default_language;
|
mpd_params.default_language = FLAGS_default_language;
|
||||||
|
|
||||||
HlsParams& hls_params = packaging_params.hls_params;
|
HlsParams& hls_params = packaging_params.hls_params;
|
||||||
if (FLAGS_hls_playlist_type == "VOD") {
|
if (!GetHlsPlaylistType(FLAGS_hls_playlist_type, &hls_params.playlist_type)) {
|
||||||
hls_params.playlist_type = HlsPlaylistType::kVod;
|
|
||||||
} else if (FLAGS_hls_playlist_type == "LIVE") {
|
|
||||||
hls_params.playlist_type = HlsPlaylistType::kLive;
|
|
||||||
} else if (FLAGS_hls_playlist_type == "EVENT") {
|
|
||||||
hls_params.playlist_type = HlsPlaylistType::kEvent;
|
|
||||||
} else {
|
|
||||||
LOG(ERROR) << "Unrecognized playlist type " << FLAGS_hls_playlist_type;
|
|
||||||
return base::nullopt;
|
return base::nullopt;
|
||||||
}
|
}
|
||||||
hls_params.master_playlist_output = FLAGS_hls_master_playlist_output;
|
hls_params.master_playlist_output = FLAGS_hls_master_playlist_output;
|
||||||
|
|
|
@ -10,22 +10,17 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "packager/hls/public/hls_playlist_type.h"
|
||||||
#include "packager/mpd/base/media_info.pb.h"
|
#include "packager/mpd/base/media_info.pb.h"
|
||||||
|
|
||||||
namespace shaka {
|
namespace shaka {
|
||||||
namespace hls {
|
namespace hls {
|
||||||
|
|
||||||
// TODO(kqyang): Combine with MediaPlaylistType in media_playlist.h.
|
|
||||||
enum class HlsProfile {
|
|
||||||
kOnDemandProfile,
|
|
||||||
kEventProfile,
|
|
||||||
kLiveProfile,
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO(rkuroiwa): Consider merging this with MpdNotifier.
|
// TODO(rkuroiwa): Consider merging this with MpdNotifier.
|
||||||
class HlsNotifier {
|
class HlsNotifier {
|
||||||
public:
|
public:
|
||||||
explicit HlsNotifier(HlsProfile profile) : profile_(profile) {}
|
explicit HlsNotifier(HlsPlaylistType playlist_type)
|
||||||
|
: playlist_type_(playlist_type) {}
|
||||||
virtual ~HlsNotifier() {}
|
virtual ~HlsNotifier() {}
|
||||||
|
|
||||||
/// Intialize the notifier.
|
/// Intialize the notifier.
|
||||||
|
@ -81,13 +76,14 @@ class HlsNotifier {
|
||||||
/// @return true on success, false otherwise.
|
/// @return true on success, false otherwise.
|
||||||
virtual bool Flush() = 0;
|
virtual bool Flush() = 0;
|
||||||
|
|
||||||
/// @return the profile.
|
/// @return the playlist type.
|
||||||
HlsProfile profile() const { return profile_; }
|
HlsPlaylistType playlist_type() const { return playlist_type_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HlsProfile profile_;
|
HlsPlaylistType playlist_type_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace hls
|
} // namespace hls
|
||||||
} // namespace shaka
|
} // namespace shaka
|
||||||
|
|
||||||
#endif // PACKAGER_HLS_BASE_HLS_NOTIFIER_H_
|
#endif // PACKAGER_HLS_BASE_HLS_NOTIFIER_H_
|
||||||
|
|
|
@ -30,8 +30,7 @@ namespace {
|
||||||
const char kDefaultMasterPlaylistName[] = "playlist.m3u8";
|
const char kDefaultMasterPlaylistName[] = "playlist.m3u8";
|
||||||
const uint32_t kWidth = 800;
|
const uint32_t kWidth = 800;
|
||||||
const uint32_t kHeight = 600;
|
const uint32_t kHeight = 600;
|
||||||
const MediaPlaylist::MediaPlaylistType kVodPlaylist =
|
const HlsPlaylistType kVodPlaylist = HlsPlaylistType::kVod;
|
||||||
MediaPlaylist::MediaPlaylistType::kVod;
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class MasterPlaylistTest : public ::testing::Test {
|
class MasterPlaylistTest : public ::testing::Test {
|
||||||
|
|
|
@ -59,10 +59,9 @@ std::string CreateExtXMap(const MediaInfo& media_info) {
|
||||||
return ext_x_map;
|
return ext_x_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CreatePlaylistHeader(
|
std::string CreatePlaylistHeader(const MediaInfo& media_info,
|
||||||
const MediaInfo& media_info,
|
|
||||||
uint32_t target_duration,
|
uint32_t target_duration,
|
||||||
MediaPlaylist::MediaPlaylistType type,
|
HlsPlaylistType type,
|
||||||
int media_sequence_number,
|
int media_sequence_number,
|
||||||
int discontinuity_sequence_number) {
|
int discontinuity_sequence_number) {
|
||||||
const std::string version = GetPackagerVersion();
|
const std::string version = GetPackagerVersion();
|
||||||
|
@ -82,13 +81,13 @@ std::string CreatePlaylistHeader(
|
||||||
version_line.c_str(), target_duration);
|
version_line.c_str(), target_duration);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case MediaPlaylist::MediaPlaylistType::kVod:
|
case HlsPlaylistType::kVod:
|
||||||
header += "#EXT-X-PLAYLIST-TYPE:VOD\n";
|
header += "#EXT-X-PLAYLIST-TYPE:VOD\n";
|
||||||
break;
|
break;
|
||||||
case MediaPlaylist::MediaPlaylistType::kEvent:
|
case HlsPlaylistType::kEvent:
|
||||||
header += "#EXT-X-PLAYLIST-TYPE:EVENT\n";
|
header += "#EXT-X-PLAYLIST-TYPE:EVENT\n";
|
||||||
break;
|
break;
|
||||||
case MediaPlaylist::MediaPlaylistType::kLive:
|
case HlsPlaylistType::kLive:
|
||||||
if (media_sequence_number > 0) {
|
if (media_sequence_number > 0) {
|
||||||
base::StringAppendF(&header, "#EXT-X-MEDIA-SEQUENCE:%d\n",
|
base::StringAppendF(&header, "#EXT-X-MEDIA-SEQUENCE:%d\n",
|
||||||
media_sequence_number);
|
media_sequence_number);
|
||||||
|
@ -278,7 +277,7 @@ double LatestSegmentStartTime(
|
||||||
HlsEntry::HlsEntry(HlsEntry::EntryType type) : type_(type) {}
|
HlsEntry::HlsEntry(HlsEntry::EntryType type) : type_(type) {}
|
||||||
HlsEntry::~HlsEntry() {}
|
HlsEntry::~HlsEntry() {}
|
||||||
|
|
||||||
MediaPlaylist::MediaPlaylist(MediaPlaylistType playlist_type,
|
MediaPlaylist::MediaPlaylist(HlsPlaylistType playlist_type,
|
||||||
double time_shift_buffer_depth,
|
double time_shift_buffer_depth,
|
||||||
const std::string& file_name,
|
const std::string& file_name,
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
|
@ -379,8 +378,8 @@ bool MediaPlaylist::WriteToFile(const std::string& file_path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string header = CreatePlaylistHeader(
|
std::string header = CreatePlaylistHeader(
|
||||||
media_info_, target_duration_, playlist_type_,
|
media_info_, target_duration_, playlist_type_, media_sequence_number_,
|
||||||
media_sequence_number_, discontinuity_sequence_number_);
|
discontinuity_sequence_number_);
|
||||||
|
|
||||||
std::string body;
|
std::string body;
|
||||||
for (const auto& entry : entries_)
|
for (const auto& entry : entries_)
|
||||||
|
@ -388,7 +387,7 @@ bool MediaPlaylist::WriteToFile(const std::string& file_path) {
|
||||||
|
|
||||||
std::string content = header + body;
|
std::string content = header + body;
|
||||||
|
|
||||||
if (playlist_type_ == MediaPlaylistType::kVod) {
|
if (playlist_type_ == HlsPlaylistType::kVod) {
|
||||||
content += "#EXT-X-ENDLIST\n";
|
content += "#EXT-X-ENDLIST\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,7 +455,7 @@ bool MediaPlaylist::GetDisplayResolution(uint32_t* width,
|
||||||
void MediaPlaylist::SlideWindow() {
|
void MediaPlaylist::SlideWindow() {
|
||||||
DCHECK(!entries_.empty());
|
DCHECK(!entries_.empty());
|
||||||
if (time_shift_buffer_depth_ <= 0.0 ||
|
if (time_shift_buffer_depth_ <= 0.0 ||
|
||||||
playlist_type_ != MediaPlaylistType::kLive) {
|
playlist_type_ != HlsPlaylistType::kLive) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DCHECK_GT(time_scale_, 0u);
|
DCHECK_GT(time_scale_, 0u);
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "packager/base/macros.h"
|
#include "packager/base/macros.h"
|
||||||
|
#include "packager/hls/public/hls_playlist_type.h"
|
||||||
#include "packager/mpd/base/media_info.pb.h"
|
#include "packager/mpd/base/media_info.pb.h"
|
||||||
|
|
||||||
namespace shaka {
|
namespace shaka {
|
||||||
|
@ -42,11 +43,6 @@ class HlsEntry {
|
||||||
/// Methods are virtual for mocking.
|
/// Methods are virtual for mocking.
|
||||||
class MediaPlaylist {
|
class MediaPlaylist {
|
||||||
public:
|
public:
|
||||||
enum class MediaPlaylistType {
|
|
||||||
kVod,
|
|
||||||
kEvent,
|
|
||||||
kLive,
|
|
||||||
};
|
|
||||||
enum class MediaPlaylistStreamType {
|
enum class MediaPlaylistStreamType {
|
||||||
kPlaylistUnknown,
|
kPlaylistUnknown,
|
||||||
kPlayListAudio,
|
kPlayListAudio,
|
||||||
|
@ -60,7 +56,7 @@ class MediaPlaylist {
|
||||||
kSampleAesCenc, // 'cenc' encrypted content.
|
kSampleAesCenc, // 'cenc' encrypted content.
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @param type is the type of this media playlist.
|
/// @param playlist_type is the type of this media playlist.
|
||||||
/// @param time_shift_buffer_depth determines the duration of the time
|
/// @param time_shift_buffer_depth determines the duration of the time
|
||||||
/// shifting buffer, only for live HLS.
|
/// 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.
|
||||||
|
@ -69,7 +65,7 @@ class MediaPlaylist {
|
||||||
/// 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(MediaPlaylistType playlist_type,
|
MediaPlaylist(HlsPlaylistType playlist_type,
|
||||||
double time_shift_buffer_depth,
|
double time_shift_buffer_depth,
|
||||||
const std::string& file_name,
|
const std::string& file_name,
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
|
@ -168,7 +164,7 @@ class MediaPlaylist {
|
||||||
// |sequence_number_| by the number of segments removed.
|
// |sequence_number_| by the number of segments removed.
|
||||||
void SlideWindow();
|
void SlideWindow();
|
||||||
|
|
||||||
const MediaPlaylistType playlist_type_;
|
const HlsPlaylistType playlist_type_;
|
||||||
const double time_shift_buffer_depth_;
|
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_;
|
||||||
|
|
|
@ -36,10 +36,9 @@ MATCHER_P(MatchesString, expected_string, "") {
|
||||||
|
|
||||||
class MediaPlaylistTest : public ::testing::Test {
|
class MediaPlaylistTest : public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
MediaPlaylistTest()
|
MediaPlaylistTest() : MediaPlaylistTest(HlsPlaylistType::kVod) {}
|
||||||
: MediaPlaylistTest(MediaPlaylist::MediaPlaylistType::kVod) {}
|
|
||||||
|
|
||||||
MediaPlaylistTest(MediaPlaylist::MediaPlaylistType 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"),
|
||||||
|
@ -77,7 +76,7 @@ class MediaPlaylistMultiSegmentTest : public MediaPlaylistTest {
|
||||||
protected:
|
protected:
|
||||||
MediaPlaylistMultiSegmentTest() : MediaPlaylistTest() {}
|
MediaPlaylistMultiSegmentTest() : MediaPlaylistTest() {}
|
||||||
// This constructor is for Live and Event playlist tests.
|
// This constructor is for Live and Event playlist tests.
|
||||||
MediaPlaylistMultiSegmentTest(MediaPlaylist::MediaPlaylistType type)
|
MediaPlaylistMultiSegmentTest(HlsPlaylistType type)
|
||||||
: MediaPlaylistTest(type) {}
|
: MediaPlaylistTest(type) {}
|
||||||
|
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
|
@ -538,8 +537,7 @@ TEST_F(MediaPlaylistMultiSegmentTest, MultipleEncryptionInfo) {
|
||||||
class LiveMediaPlaylistTest : public MediaPlaylistMultiSegmentTest {
|
class LiveMediaPlaylistTest : public MediaPlaylistMultiSegmentTest {
|
||||||
protected:
|
protected:
|
||||||
LiveMediaPlaylistTest()
|
LiveMediaPlaylistTest()
|
||||||
: MediaPlaylistMultiSegmentTest(MediaPlaylist::MediaPlaylistType::kLive) {
|
: MediaPlaylistMultiSegmentTest(HlsPlaylistType::kLive) {}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(LiveMediaPlaylistTest, Basic) {
|
TEST_F(LiveMediaPlaylistTest, Basic) {
|
||||||
|
@ -701,8 +699,7 @@ TEST_F(LiveMediaPlaylistTest, TimeShiftedWithEncryptionInfoShifted) {
|
||||||
class EventMediaPlaylistTest : public MediaPlaylistMultiSegmentTest {
|
class EventMediaPlaylistTest : public MediaPlaylistMultiSegmentTest {
|
||||||
protected:
|
protected:
|
||||||
EventMediaPlaylistTest()
|
EventMediaPlaylistTest()
|
||||||
: MediaPlaylistMultiSegmentTest(
|
: MediaPlaylistMultiSegmentTest(HlsPlaylistType::kEvent) {}
|
||||||
MediaPlaylist::MediaPlaylistType::kEvent) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(EventMediaPlaylistTest, Basic) {
|
TEST_F(EventMediaPlaylistTest, Basic) {
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
namespace shaka {
|
namespace shaka {
|
||||||
namespace hls {
|
namespace hls {
|
||||||
|
|
||||||
MockMediaPlaylist::MockMediaPlaylist(MediaPlaylistType type,
|
MockMediaPlaylist::MockMediaPlaylist(HlsPlaylistType type,
|
||||||
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)
|
||||||
|
|
|
@ -18,7 +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(MediaPlaylistType type,
|
MockMediaPlaylist(HlsPlaylistType type,
|
||||||
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);
|
||||||
|
@ -31,7 +31,6 @@ class MockMediaPlaylist : public MediaPlaylist {
|
||||||
uint64_t duration,
|
uint64_t duration,
|
||||||
uint64_t start_byte_offset,
|
uint64_t start_byte_offset,
|
||||||
uint64_t size));
|
uint64_t size));
|
||||||
MOCK_METHOD0(RemoveOldestSegment, void());
|
|
||||||
MOCK_METHOD6(AddEncryptionInfo,
|
MOCK_METHOD6(AddEncryptionInfo,
|
||||||
void(EncryptionMethod method,
|
void(EncryptionMethod method,
|
||||||
const std::string& url,
|
const std::string& url,
|
||||||
|
|
|
@ -211,7 +211,7 @@ bool WriteMediaPlaylist(const std::string& output_dir,
|
||||||
MediaPlaylistFactory::~MediaPlaylistFactory() {}
|
MediaPlaylistFactory::~MediaPlaylistFactory() {}
|
||||||
|
|
||||||
std::unique_ptr<MediaPlaylist> MediaPlaylistFactory::Create(
|
std::unique_ptr<MediaPlaylist> MediaPlaylistFactory::Create(
|
||||||
MediaPlaylist::MediaPlaylistType type,
|
HlsPlaylistType type,
|
||||||
double time_shift_buffer_depth,
|
double time_shift_buffer_depth,
|
||||||
const std::string& file_name,
|
const std::string& file_name,
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
|
@ -220,12 +220,12 @@ std::unique_ptr<MediaPlaylist> MediaPlaylistFactory::Create(
|
||||||
type, time_shift_buffer_depth, file_name, name, group_id));
|
type, time_shift_buffer_depth, file_name, name, group_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleHlsNotifier::SimpleHlsNotifier(HlsProfile profile,
|
SimpleHlsNotifier::SimpleHlsNotifier(HlsPlaylistType playlist_type,
|
||||||
double time_shift_buffer_depth,
|
double time_shift_buffer_depth,
|
||||||
const std::string& prefix,
|
const std::string& prefix,
|
||||||
const std::string& output_dir,
|
const std::string& output_dir,
|
||||||
const std::string& master_playlist_name)
|
const std::string& master_playlist_name)
|
||||||
: HlsNotifier(profile),
|
: HlsNotifier(playlist_type),
|
||||||
time_shift_buffer_depth_(time_shift_buffer_depth),
|
time_shift_buffer_depth_(time_shift_buffer_depth),
|
||||||
prefix_(prefix),
|
prefix_(prefix),
|
||||||
output_dir_(output_dir),
|
output_dir_(output_dir),
|
||||||
|
@ -245,27 +245,11 @@ bool SimpleHlsNotifier::NotifyNewStream(const MediaInfo& media_info,
|
||||||
uint32_t* stream_id) {
|
uint32_t* stream_id) {
|
||||||
DCHECK(stream_id);
|
DCHECK(stream_id);
|
||||||
|
|
||||||
MediaPlaylist::MediaPlaylistType type;
|
|
||||||
switch (profile()) {
|
|
||||||
case HlsProfile::kLiveProfile:
|
|
||||||
type = MediaPlaylist::MediaPlaylistType::kLive;
|
|
||||||
break;
|
|
||||||
case HlsProfile::kOnDemandProfile:
|
|
||||||
type = MediaPlaylist::MediaPlaylistType::kVod;
|
|
||||||
break;
|
|
||||||
case HlsProfile::kEventProfile:
|
|
||||||
type = MediaPlaylist::MediaPlaylistType::kEvent;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
NOTREACHED();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
MediaInfo adjusted_media_info(media_info);
|
MediaInfo adjusted_media_info(media_info);
|
||||||
MakePathsRelativeToOutputDirectory(output_dir_, &adjusted_media_info);
|
MakePathsRelativeToOutputDirectory(output_dir_, &adjusted_media_info);
|
||||||
|
|
||||||
std::unique_ptr<MediaPlaylist> media_playlist =
|
std::unique_ptr<MediaPlaylist> media_playlist =
|
||||||
media_playlist_factory_->Create(type, time_shift_buffer_depth_,
|
media_playlist_factory_->Create(playlist_type(), time_shift_buffer_depth_,
|
||||||
playlist_name, name, group_id);
|
playlist_name, name, group_id);
|
||||||
if (!media_playlist->SetMediaInfo(adjusted_media_info)) {
|
if (!media_playlist->SetMediaInfo(adjusted_media_info)) {
|
||||||
LOG(ERROR) << "Failed to set media info for playlist " << playlist_name;
|
LOG(ERROR) << "Failed to set media info for playlist " << playlist_name;
|
||||||
|
@ -324,8 +308,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 (profile() == HlsProfile::kLiveProfile ||
|
if (playlist_type() == HlsPlaylistType::kLive ||
|
||||||
profile() == HlsProfile::kEventProfile) {
|
playlist_type() == HlsPlaylistType::kEvent) {
|
||||||
if (!master_playlist_->WriteMasterPlaylist(prefix_, output_dir_)) {
|
if (!master_playlist_->WriteMasterPlaylist(prefix_, output_dir_)) {
|
||||||
LOG(ERROR) << "Failed to write master playlist.";
|
LOG(ERROR) << "Failed to write master playlist.";
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "packager/hls/base/hls_notifier.h"
|
#include "packager/hls/base/hls_notifier.h"
|
||||||
#include "packager/hls/base/master_playlist.h"
|
#include "packager/hls/base/master_playlist.h"
|
||||||
#include "packager/hls/base/media_playlist.h"
|
#include "packager/hls/base/media_playlist.h"
|
||||||
|
#include "packager/hls/public/hls_playlist_type.h"
|
||||||
|
|
||||||
namespace shaka {
|
namespace shaka {
|
||||||
namespace hls {
|
namespace hls {
|
||||||
|
@ -27,8 +28,7 @@ namespace hls {
|
||||||
class MediaPlaylistFactory {
|
class MediaPlaylistFactory {
|
||||||
public:
|
public:
|
||||||
virtual ~MediaPlaylistFactory();
|
virtual ~MediaPlaylistFactory();
|
||||||
virtual std::unique_ptr<MediaPlaylist> Create(
|
virtual std::unique_ptr<MediaPlaylist> Create(HlsPlaylistType type,
|
||||||
MediaPlaylist::MediaPlaylistType type,
|
|
||||||
double time_shift_buffer_depth,
|
double time_shift_buffer_depth,
|
||||||
const std::string& file_name,
|
const std::string& file_name,
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
|
@ -40,7 +40,7 @@ class SimpleHlsNotifier : public HlsNotifier {
|
||||||
public:
|
public:
|
||||||
/// @a prefix is used as hte prefix for all the URIs for Media Playlist. This
|
/// @a prefix is used as hte prefix for all the URIs for Media Playlist. This
|
||||||
/// includes the segment URIs in the Media Playlists.
|
/// includes the segment URIs in the Media Playlists.
|
||||||
/// @param profile is the profile of the playlists.
|
/// @param playlist_type is the type of the playlists.
|
||||||
/// @param time_shift_buffer_depth determines the duration of the time
|
/// @param time_shift_buffer_depth determines the duration of the time
|
||||||
/// shifting buffer, only for live HLS.
|
/// shifting buffer, only for live HLS.
|
||||||
/// @param prefix is the used as the prefix for MediaPlaylist URIs. May be
|
/// @param prefix is the used as the prefix for MediaPlaylist URIs. May be
|
||||||
|
@ -48,7 +48,7 @@ class SimpleHlsNotifier : public HlsNotifier {
|
||||||
/// @param output_dir is the output directory of the playlists. May be empty
|
/// @param output_dir is the output directory of the playlists. May be empty
|
||||||
/// to write to current directory.
|
/// to write to current directory.
|
||||||
/// @param master_playlist_name is the name of the master playlist.
|
/// @param master_playlist_name is the name of the master playlist.
|
||||||
SimpleHlsNotifier(HlsProfile profile,
|
SimpleHlsNotifier(HlsPlaylistType playlist_type,
|
||||||
double time_shift_buffer_depth,
|
double time_shift_buffer_depth,
|
||||||
const std::string& prefix,
|
const std::string& prefix,
|
||||||
const std::string& output_dir,
|
const std::string& output_dir,
|
||||||
|
|
|
@ -30,8 +30,7 @@ using ::testing::_;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const char kMasterPlaylistName[] = "master.m3u8";
|
const char kMasterPlaylistName[] = "master.m3u8";
|
||||||
const MediaPlaylist::MediaPlaylistType kVodPlaylist =
|
const HlsPlaylistType kVodPlaylist = HlsPlaylistType::kVod;
|
||||||
MediaPlaylist::MediaPlaylistType::kVod;
|
|
||||||
|
|
||||||
class MockMasterPlaylist : public MasterPlaylist {
|
class MockMasterPlaylist : public MasterPlaylist {
|
||||||
public:
|
public:
|
||||||
|
@ -45,13 +44,13 @@ class MockMasterPlaylist : public MasterPlaylist {
|
||||||
class MockMediaPlaylistFactory : public MediaPlaylistFactory {
|
class MockMediaPlaylistFactory : public MediaPlaylistFactory {
|
||||||
public:
|
public:
|
||||||
MOCK_METHOD5(CreateMock,
|
MOCK_METHOD5(CreateMock,
|
||||||
MediaPlaylist*(MediaPlaylist::MediaPlaylistType type,
|
MediaPlaylist*(HlsPlaylistType type,
|
||||||
double time_shift_buffer_depth,
|
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(MediaPlaylist::MediaPlaylistType type,
|
std::unique_ptr<MediaPlaylist> Create(HlsPlaylistType type,
|
||||||
double time_shift_buffer_depth,
|
double time_shift_buffer_depth,
|
||||||
const std::string& file_name,
|
const std::string& file_name,
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
|
@ -87,10 +86,9 @@ const char kSampleAesProtectionScheme[] = "cbca";
|
||||||
|
|
||||||
class SimpleHlsNotifierTest : public ::testing::Test {
|
class SimpleHlsNotifierTest : public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
SimpleHlsNotifierTest()
|
SimpleHlsNotifierTest() : SimpleHlsNotifierTest(kVodPlaylist) {}
|
||||||
: SimpleHlsNotifierTest(HlsProfile::kOnDemandProfile) {}
|
|
||||||
|
|
||||||
SimpleHlsNotifierTest(HlsProfile profile)
|
SimpleHlsNotifierTest(HlsPlaylistType playlist_type)
|
||||||
: widevine_system_id_(
|
: widevine_system_id_(
|
||||||
media::kWidevineSystemId,
|
media::kWidevineSystemId,
|
||||||
media::kWidevineSystemId + arraysize(media::kWidevineSystemId)),
|
media::kWidevineSystemId + arraysize(media::kWidevineSystemId)),
|
||||||
|
@ -144,9 +142,8 @@ class SimpleHlsNotifierTest : public ::testing::Test {
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(SimpleHlsNotifierTest, Init) {
|
TEST_F(SimpleHlsNotifierTest, Init) {
|
||||||
SimpleHlsNotifier notifier(HlsProfile::kOnDemandProfile,
|
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||||
kTestTimeShiftBufferDepth, kTestPrefix,
|
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||||
kAnyOutputDir, kMasterPlaylistName);
|
|
||||||
EXPECT_TRUE(notifier.Init());
|
EXPECT_TRUE(notifier.Init());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,9 +174,8 @@ TEST_F(SimpleHlsNotifierTest, RebaseSegmentTemplateRelative) {
|
||||||
StrEq("groupid")))
|
StrEq("groupid")))
|
||||||
.WillOnce(Return(mock_media_playlist));
|
.WillOnce(Return(mock_media_playlist));
|
||||||
|
|
||||||
SimpleHlsNotifier notifier(HlsProfile::kOnDemandProfile,
|
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||||
kTestTimeShiftBufferDepth, kTestPrefix,
|
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||||
kAnyOutputDir, kMasterPlaylistName);
|
|
||||||
|
|
||||||
InjectMasterPlaylist(std::move(mock_master_playlist), ¬ifier);
|
InjectMasterPlaylist(std::move(mock_master_playlist), ¬ifier);
|
||||||
InjectMediaPlaylistFactory(std::move(factory), ¬ifier);
|
InjectMediaPlaylistFactory(std::move(factory), ¬ifier);
|
||||||
|
@ -201,9 +197,9 @@ TEST_F(SimpleHlsNotifierTest, RebaseSegmentTemplateRelative) {
|
||||||
TEST_F(SimpleHlsNotifierTest,
|
TEST_F(SimpleHlsNotifierTest,
|
||||||
RebaseAbsoluteSegmentTemplatePrefixAndOutputDirMatch) {
|
RebaseAbsoluteSegmentTemplatePrefixAndOutputDirMatch) {
|
||||||
const char kAbsoluteOutputDir[] = "/tmp/something/";
|
const char kAbsoluteOutputDir[] = "/tmp/something/";
|
||||||
SimpleHlsNotifier test_notifier(HlsProfile::kOnDemandProfile,
|
SimpleHlsNotifier test_notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||||
kTestTimeShiftBufferDepth, kTestPrefix,
|
kTestPrefix, kAbsoluteOutputDir,
|
||||||
kAbsoluteOutputDir, kMasterPlaylistName);
|
kMasterPlaylistName);
|
||||||
|
|
||||||
std::unique_ptr<MockMasterPlaylist> mock_master_playlist(
|
std::unique_ptr<MockMasterPlaylist> mock_master_playlist(
|
||||||
new MockMasterPlaylist());
|
new MockMasterPlaylist());
|
||||||
|
@ -246,9 +242,9 @@ TEST_F(SimpleHlsNotifierTest,
|
||||||
TEST_F(SimpleHlsNotifierTest,
|
TEST_F(SimpleHlsNotifierTest,
|
||||||
RebaseAbsoluteSegmentTemplateCompletelyDifferentDirectory) {
|
RebaseAbsoluteSegmentTemplateCompletelyDifferentDirectory) {
|
||||||
const char kAbsoluteOutputDir[] = "/tmp/something/";
|
const char kAbsoluteOutputDir[] = "/tmp/something/";
|
||||||
SimpleHlsNotifier test_notifier(HlsProfile::kOnDemandProfile,
|
SimpleHlsNotifier test_notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||||
kTestTimeShiftBufferDepth, kTestPrefix,
|
kTestPrefix, kAbsoluteOutputDir,
|
||||||
kAbsoluteOutputDir, kMasterPlaylistName);
|
kMasterPlaylistName);
|
||||||
|
|
||||||
std::unique_ptr<MockMasterPlaylist> mock_master_playlist(
|
std::unique_ptr<MockMasterPlaylist> mock_master_playlist(
|
||||||
new MockMasterPlaylist());
|
new MockMasterPlaylist());
|
||||||
|
@ -286,9 +282,8 @@ TEST_F(SimpleHlsNotifierTest,
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SimpleHlsNotifierTest, Flush) {
|
TEST_F(SimpleHlsNotifierTest, Flush) {
|
||||||
SimpleHlsNotifier notifier(HlsProfile::kOnDemandProfile,
|
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||||
kTestTimeShiftBufferDepth, kTestPrefix,
|
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||||
kAnyOutputDir, kMasterPlaylistName);
|
|
||||||
std::unique_ptr<MockMasterPlaylist> mock_master_playlist(
|
std::unique_ptr<MockMasterPlaylist> mock_master_playlist(
|
||||||
new MockMasterPlaylist());
|
new MockMasterPlaylist());
|
||||||
EXPECT_CALL(*mock_master_playlist,
|
EXPECT_CALL(*mock_master_playlist,
|
||||||
|
@ -316,9 +311,8 @@ TEST_F(SimpleHlsNotifierTest, NotifyNewStream) {
|
||||||
StrEq("groupid")))
|
StrEq("groupid")))
|
||||||
.WillOnce(Return(mock_media_playlist));
|
.WillOnce(Return(mock_media_playlist));
|
||||||
|
|
||||||
SimpleHlsNotifier notifier(HlsProfile::kOnDemandProfile,
|
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||||
kTestTimeShiftBufferDepth, kTestPrefix,
|
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||||
kAnyOutputDir, kMasterPlaylistName);
|
|
||||||
|
|
||||||
InjectMasterPlaylist(std::move(mock_master_playlist), ¬ifier);
|
InjectMasterPlaylist(std::move(mock_master_playlist), ¬ifier);
|
||||||
InjectMediaPlaylistFactory(std::move(factory), ¬ifier);
|
InjectMediaPlaylistFactory(std::move(factory), ¬ifier);
|
||||||
|
@ -360,9 +354,8 @@ TEST_F(SimpleHlsNotifierTest, NotifyNewSegment) {
|
||||||
EXPECT_CALL(*mock_media_playlist, GetLongestSegmentDuration())
|
EXPECT_CALL(*mock_media_playlist, GetLongestSegmentDuration())
|
||||||
.WillOnce(Return(kLongestSegmentDuration));
|
.WillOnce(Return(kLongestSegmentDuration));
|
||||||
|
|
||||||
SimpleHlsNotifier notifier(HlsProfile::kOnDemandProfile,
|
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||||
kTestTimeShiftBufferDepth, kTestPrefix,
|
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||||
kAnyOutputDir, kMasterPlaylistName);
|
|
||||||
MockMasterPlaylist* mock_master_playlist_ptr = mock_master_playlist.get();
|
MockMasterPlaylist* mock_master_playlist_ptr = mock_master_playlist.get();
|
||||||
InjectMasterPlaylist(std::move(mock_master_playlist), ¬ifier);
|
InjectMasterPlaylist(std::move(mock_master_playlist), ¬ifier);
|
||||||
InjectMediaPlaylistFactory(std::move(factory), ¬ifier);
|
InjectMediaPlaylistFactory(std::move(factory), ¬ifier);
|
||||||
|
@ -393,9 +386,8 @@ TEST_F(SimpleHlsNotifierTest, NotifyNewSegment) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SimpleHlsNotifierTest, NotifyNewSegmentWithoutStreamsRegistered) {
|
TEST_F(SimpleHlsNotifierTest, NotifyNewSegmentWithoutStreamsRegistered) {
|
||||||
SimpleHlsNotifier notifier(HlsProfile::kOnDemandProfile,
|
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||||
kTestTimeShiftBufferDepth, kTestPrefix,
|
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||||
kAnyOutputDir, kMasterPlaylistName);
|
|
||||||
EXPECT_TRUE(notifier.Init());
|
EXPECT_TRUE(notifier.Init());
|
||||||
EXPECT_FALSE(notifier.NotifyNewSegment(1u, "anything", 0u, 0u, 0u, 0u));
|
EXPECT_FALSE(notifier.NotifyNewSegment(1u, "anything", 0u, 0u, 0u, 0u));
|
||||||
}
|
}
|
||||||
|
@ -404,9 +396,8 @@ 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(kVodPlaylist, "playlist.m3u8", "", "");
|
||||||
SimpleHlsNotifier notifier(HlsProfile::kOnDemandProfile,
|
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||||
kTestTimeShiftBufferDepth, kTestPrefix,
|
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||||
kAnyOutputDir, kMasterPlaylistName);
|
|
||||||
const uint32_t stream_id =
|
const uint32_t stream_id =
|
||||||
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, ¬ifier);
|
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, ¬ifier);
|
||||||
|
|
||||||
|
@ -467,9 +458,8 @@ 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(kVodPlaylist, "playlist.m3u8", "", "");
|
||||||
SimpleHlsNotifier notifier(HlsProfile::kOnDemandProfile,
|
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||||
kTestTimeShiftBufferDepth, kTestPrefix,
|
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||||
kAnyOutputDir, kMasterPlaylistName);
|
|
||||||
const uint32_t stream_id =
|
const uint32_t stream_id =
|
||||||
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, ¬ifier);
|
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, ¬ifier);
|
||||||
|
|
||||||
|
@ -526,9 +516,8 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateFixedKey) {
|
||||||
// Pointer released by SimpleHlsNotifier.
|
// Pointer released by SimpleHlsNotifier.
|
||||||
MockMediaPlaylist* mock_media_playlist =
|
MockMediaPlaylist* mock_media_playlist =
|
||||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||||
SimpleHlsNotifier notifier(HlsProfile::kOnDemandProfile,
|
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||||
kTestTimeShiftBufferDepth, kTestPrefix,
|
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||||
kAnyOutputDir, kMasterPlaylistName);
|
|
||||||
const uint32_t stream_id =
|
const uint32_t stream_id =
|
||||||
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, ¬ifier);
|
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, ¬ifier);
|
||||||
|
|
||||||
|
@ -556,9 +545,8 @@ 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(kVodPlaylist, "playlist.m3u8", "", "");
|
||||||
SimpleHlsNotifier notifier(HlsProfile::kOnDemandProfile,
|
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||||
kTestTimeShiftBufferDepth, kTestPrefix,
|
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||||
kAnyOutputDir, kMasterPlaylistName);
|
|
||||||
uint32_t stream_id =
|
uint32_t stream_id =
|
||||||
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, ¬ifier);
|
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, ¬ifier);
|
||||||
|
|
||||||
|
@ -634,9 +622,8 @@ 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(kVodPlaylist, "playlist.m3u8", "", "");
|
||||||
SimpleHlsNotifier notifier(HlsProfile::kOnDemandProfile,
|
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||||
kTestTimeShiftBufferDepth, kTestPrefix,
|
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||||
kAnyOutputDir, kMasterPlaylistName);
|
|
||||||
const uint32_t stream_id =
|
const uint32_t stream_id =
|
||||||
SetupStream(kCencProtectionScheme, mock_media_playlist, ¬ifier);
|
SetupStream(kCencProtectionScheme, mock_media_playlist, ¬ifier);
|
||||||
|
|
||||||
|
@ -663,9 +650,8 @@ 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(kVodPlaylist, "playlist.m3u8", "", "");
|
||||||
SimpleHlsNotifier notifier(HlsProfile::kOnDemandProfile,
|
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||||
kTestTimeShiftBufferDepth, kTestPrefix,
|
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||||
kAnyOutputDir, kMasterPlaylistName);
|
|
||||||
const uint32_t stream_id =
|
const uint32_t stream_id =
|
||||||
SetupStream(kCencProtectionScheme, mock_media_playlist, ¬ifier);
|
SetupStream(kCencProtectionScheme, mock_media_playlist, ¬ifier);
|
||||||
|
|
||||||
|
@ -712,9 +698,8 @@ 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(kVodPlaylist, "playlist.m3u8", "", "");
|
||||||
SimpleHlsNotifier notifier(HlsProfile::kOnDemandProfile,
|
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||||
kTestTimeShiftBufferDepth, kTestPrefix,
|
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||||
kAnyOutputDir, kMasterPlaylistName);
|
|
||||||
const uint32_t stream_id =
|
const uint32_t stream_id =
|
||||||
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, ¬ifier);
|
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, ¬ifier);
|
||||||
|
|
||||||
|
@ -780,9 +765,8 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateWithoutStreamsRegistered) {
|
||||||
std::vector<uint8_t> iv;
|
std::vector<uint8_t> iv;
|
||||||
std::vector<uint8_t> pssh_data;
|
std::vector<uint8_t> pssh_data;
|
||||||
std::vector<uint8_t> key_id;
|
std::vector<uint8_t> key_id;
|
||||||
SimpleHlsNotifier notifier(HlsProfile::kOnDemandProfile,
|
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||||
kTestTimeShiftBufferDepth, kTestPrefix,
|
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||||
kAnyOutputDir, kMasterPlaylistName);
|
|
||||||
EXPECT_TRUE(notifier.Init());
|
EXPECT_TRUE(notifier.Init());
|
||||||
EXPECT_FALSE(
|
EXPECT_FALSE(
|
||||||
notifier.NotifyEncryptionUpdate(1238u, key_id, system_id, iv, pssh_data));
|
notifier.NotifyEncryptionUpdate(1238u, key_id, system_id, iv, pssh_data));
|
||||||
|
@ -790,23 +774,13 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateWithoutStreamsRegistered) {
|
||||||
|
|
||||||
class LiveOrEventSimpleHlsNotifierTest
|
class LiveOrEventSimpleHlsNotifierTest
|
||||||
: public SimpleHlsNotifierTest,
|
: public SimpleHlsNotifierTest,
|
||||||
public ::testing::WithParamInterface<HlsProfile> {
|
public ::testing::WithParamInterface<HlsPlaylistType> {
|
||||||
protected:
|
protected:
|
||||||
LiveOrEventSimpleHlsNotifierTest() : SimpleHlsNotifierTest(GetParam()) {
|
LiveOrEventSimpleHlsNotifierTest() : SimpleHlsNotifierTest(GetParam()) {
|
||||||
switch (GetParam()) {
|
expected_playlist_type_ = GetParam();
|
||||||
case HlsProfile::kLiveProfile:
|
|
||||||
expected_playlist_type_ = MediaPlaylist::MediaPlaylistType::kLive;
|
|
||||||
break;
|
|
||||||
case HlsProfile::kOnDemandProfile:
|
|
||||||
expected_playlist_type_ = MediaPlaylist::MediaPlaylistType::kVod;
|
|
||||||
break;
|
|
||||||
case HlsProfile::kEventProfile:
|
|
||||||
expected_playlist_type_ = MediaPlaylist::MediaPlaylistType::kEvent;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaPlaylist::MediaPlaylistType expected_playlist_type_;
|
HlsPlaylistType expected_playlist_type_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(LiveOrEventSimpleHlsNotifierTest, NotifyNewSegment) {
|
TEST_P(LiveOrEventSimpleHlsNotifierTest, NotifyNewSegment) {
|
||||||
|
@ -959,7 +933,7 @@ TEST_P(LiveOrEventSimpleHlsNotifierTest, NotifyNewSegmentsWithMultipleStreams) {
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(PlaylistTypes,
|
INSTANTIATE_TEST_CASE_P(PlaylistTypes,
|
||||||
LiveOrEventSimpleHlsNotifierTest,
|
LiveOrEventSimpleHlsNotifierTest,
|
||||||
::testing::Values(HlsProfile::kLiveProfile,
|
::testing::Values(HlsPlaylistType::kLive,
|
||||||
HlsProfile::kEventProfile));
|
HlsPlaylistType::kEvent));
|
||||||
} // namespace hls
|
} // namespace hls
|
||||||
} // namespace shaka
|
} // namespace shaka
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
'base/media_playlist.h',
|
'base/media_playlist.h',
|
||||||
'base/simple_hls_notifier.cc',
|
'base/simple_hls_notifier.cc',
|
||||||
'base/simple_hls_notifier.h',
|
'base/simple_hls_notifier.h',
|
||||||
|
'public/hls_playlist_type.h',
|
||||||
],
|
],
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
'../base/base.gyp:base',
|
'../base/base.gyp:base',
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2017 Google Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file or at
|
||||||
|
// https://developers.google.com/open-source/licenses/bsd
|
||||||
|
|
||||||
|
#ifndef PACKAGER_HLS_PUBLIC_HLS_PLAYLIST_TYPE_H_
|
||||||
|
#define PACKAGER_HLS_PUBLIC_HLS_PLAYLIST_TYPE_H_
|
||||||
|
|
||||||
|
namespace shaka {
|
||||||
|
|
||||||
|
/// Defines the EXT-X-PLAYLIST-TYPE in the HLS specification. For
|
||||||
|
/// HlsPlaylistType of kLive, EXT-X-PLAYLIST-TYPE tag is omitted.
|
||||||
|
enum class HlsPlaylistType {
|
||||||
|
kVod,
|
||||||
|
kEvent,
|
||||||
|
kLive,
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace shaka
|
||||||
|
|
||||||
|
#endif // PACKAGER_HLS_PUBLIC_HLS_PLAYLIST_TYPE_H_
|
|
@ -24,7 +24,7 @@ namespace {
|
||||||
|
|
||||||
class MockHlsNotifier : public hls::HlsNotifier {
|
class MockHlsNotifier : public hls::HlsNotifier {
|
||||||
public:
|
public:
|
||||||
MockHlsNotifier() : HlsNotifier(hls::HlsProfile::kOnDemandProfile) {}
|
MockHlsNotifier() : HlsNotifier(HlsPlaylistType::kVod) {}
|
||||||
|
|
||||||
MOCK_METHOD0(Init, bool());
|
MOCK_METHOD0(Init, bool());
|
||||||
MOCK_METHOD5(NotifyNewStream,
|
MOCK_METHOD5(NotifyNewStream,
|
||||||
|
|
|
@ -205,20 +205,6 @@ bool ValidateParams(const PackagingParams& packaging_params,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
hls::HlsProfile GetHlsNotifierProfile(HlsPlaylistType playlist_type) {
|
|
||||||
switch (playlist_type) {
|
|
||||||
case HlsPlaylistType::kVod:
|
|
||||||
return hls::HlsProfile::kOnDemandProfile;
|
|
||||||
case HlsPlaylistType::kEvent:
|
|
||||||
return hls::HlsProfile::kEventProfile;
|
|
||||||
case HlsPlaylistType::kLive:
|
|
||||||
return hls::HlsProfile::kLiveProfile;
|
|
||||||
}
|
|
||||||
LOG(WARNING) << "Unrecognized playlist type ("
|
|
||||||
<< static_cast<int>(playlist_type) << "). Assuming VOD.";
|
|
||||||
return hls::HlsProfile::kOnDemandProfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
class StreamDescriptorCompareFn {
|
class StreamDescriptorCompareFn {
|
||||||
public:
|
public:
|
||||||
bool operator()(const StreamDescriptor& a, const StreamDescriptor& b) {
|
bool operator()(const StreamDescriptor& a, const StreamDescriptor& b) {
|
||||||
|
@ -647,8 +633,8 @@ Status Packager::Initialize(
|
||||||
base::FilePath master_playlist_name = master_playlist_path.BaseName();
|
base::FilePath master_playlist_name = master_playlist_path.BaseName();
|
||||||
|
|
||||||
internal->hls_notifier.reset(new hls::SimpleHlsNotifier(
|
internal->hls_notifier.reset(new hls::SimpleHlsNotifier(
|
||||||
media::GetHlsNotifierProfile(hls_params.playlist_type),
|
hls_params.playlist_type, hls_params.time_shift_buffer_depth,
|
||||||
hls_params.time_shift_buffer_depth, hls_params.base_url,
|
hls_params.base_url,
|
||||||
master_playlist_path.DirName().AsEndingWithSeparator().AsUTF8Unsafe(),
|
master_playlist_path.DirName().AsEndingWithSeparator().AsUTF8Unsafe(),
|
||||||
master_playlist_name.AsUTF8Unsafe()));
|
master_playlist_name.AsUTF8Unsafe()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "packager/hls/public/hls_playlist_type.h"
|
||||||
#include "packager/status.h"
|
#include "packager/status.h"
|
||||||
|
|
||||||
namespace shaka {
|
namespace shaka {
|
||||||
|
@ -94,14 +95,6 @@ struct MpdParams {
|
||||||
bool generate_dash_if_iop_compliant_mpd = true;
|
bool generate_dash_if_iop_compliant_mpd = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Defines the EXT-X-PLAYLIST-TYPE in the HLS specification. For
|
|
||||||
/// HlsPlaylistType of kLive, EXT-X-PLAYLIST-TYPE tag is omitted.
|
|
||||||
enum class HlsPlaylistType {
|
|
||||||
kVod,
|
|
||||||
kEvent,
|
|
||||||
kLive,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// HLS related parameters.
|
/// HLS related parameters.
|
||||||
struct HlsParams {
|
struct HlsParams {
|
||||||
/// HLS playlist type. See HLS specification for details.
|
/// HLS playlist type. See HLS specification for details.
|
||||||
|
|
Loading…
Reference in New Issue