Consolidate various playlist_type types

Change-Id: If6fafc0867e7e1f3cd2ed612617e91c7cb144f20
This commit is contained in:
KongQun Yang 2017-06-30 13:42:46 -07:00
parent 61c58724ec
commit b451d3a7ca
16 changed files with 134 additions and 179 deletions

View File

@ -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;

View File

@ -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_

View File

@ -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 {

View File

@ -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);

View File

@ -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_;

View File

@ -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) {

View File

@ -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)

View File

@ -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,

View File

@ -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;

View File

@ -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,

View File

@ -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), &notifier); InjectMasterPlaylist(std::move(mock_master_playlist), &notifier);
InjectMediaPlaylistFactory(std::move(factory), &notifier); InjectMediaPlaylistFactory(std::move(factory), &notifier);
@ -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), &notifier); InjectMasterPlaylist(std::move(mock_master_playlist), &notifier);
InjectMediaPlaylistFactory(std::move(factory), &notifier); InjectMediaPlaylistFactory(std::move(factory), &notifier);
@ -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), &notifier); InjectMasterPlaylist(std::move(mock_master_playlist), &notifier);
InjectMediaPlaylistFactory(std::move(factory), &notifier); InjectMediaPlaylistFactory(std::move(factory), &notifier);
@ -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, &notifier); SetupStream(kSampleAesProtectionScheme, mock_media_playlist, &notifier);
@ -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, &notifier); SetupStream(kSampleAesProtectionScheme, mock_media_playlist, &notifier);
@ -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, &notifier); SetupStream(kSampleAesProtectionScheme, mock_media_playlist, &notifier);
@ -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, &notifier); SetupStream(kSampleAesProtectionScheme, mock_media_playlist, &notifier);
@ -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, &notifier); SetupStream(kCencProtectionScheme, mock_media_playlist, &notifier);
@ -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, &notifier); SetupStream(kCencProtectionScheme, mock_media_playlist, &notifier);
@ -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, &notifier); SetupStream(kSampleAesProtectionScheme, mock_media_playlist, &notifier);
@ -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

View File

@ -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',

View File

@ -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_

View File

@ -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,

View File

@ -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()));
} }

View File

@ -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.