Widevine HLS new key format media event side
- This change has the muxer listener side changes. - Also changed SetContentProtectionFields() to take vector for default_key_id so that MuxerListener subclasses don't need to convert it to string. Change-Id: I8832848a0c7e34b84e2b4e6baeba364861900ff1
This commit is contained in:
parent
437d48f041
commit
f3e91301c2
|
@ -49,11 +49,12 @@ void HlsNotifyMuxerListener::OnEncryptionInfoReady(
|
||||||
next_key_id_ = key_id;
|
next_key_id_ = key_id;
|
||||||
next_iv_ = iv;
|
next_iv_ = iv;
|
||||||
next_key_system_infos_ = key_system_infos;
|
next_key_system_infos_ = key_system_infos;
|
||||||
|
protection_scheme_ = protection_scheme;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (const ProtectionSystemSpecificInfo& info : key_system_infos) {
|
for (const ProtectionSystemSpecificInfo& info : key_system_infos) {
|
||||||
const bool result = hls_notifier_->NotifyEncryptionUpdate(
|
const bool result = hls_notifier_->NotifyEncryptionUpdate(
|
||||||
stream_id_, key_id, info.system_id(), iv, info.pssh_data());
|
stream_id_, key_id, info.system_id(), iv, info.CreateBox());
|
||||||
LOG_IF(WARNING, !result) << "Failed to add encryption info.";
|
LOG_IF(WARNING, !result) << "Failed to add encryption info.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +73,7 @@ void HlsNotifyMuxerListener::OnEncryptionStart() {
|
||||||
for (const ProtectionSystemSpecificInfo& info : next_key_system_infos_) {
|
for (const ProtectionSystemSpecificInfo& info : next_key_system_infos_) {
|
||||||
const bool result = hls_notifier_->NotifyEncryptionUpdate(
|
const bool result = hls_notifier_->NotifyEncryptionUpdate(
|
||||||
stream_id_, next_key_id_, info.system_id(), next_iv_,
|
stream_id_, next_key_id_, info.system_id(), next_iv_,
|
||||||
info.pssh_data());
|
info.CreateBox());
|
||||||
LOG_IF(WARNING, !result) << "Failed to add encryption info";
|
LOG_IF(WARNING, !result) << "Failed to add encryption info";
|
||||||
}
|
}
|
||||||
next_key_id_.clear();
|
next_key_id_.clear();
|
||||||
|
@ -91,6 +92,11 @@ void HlsNotifyMuxerListener::OnMediaStart(const MuxerOptions& muxer_options,
|
||||||
LOG(ERROR) << "Failed to generate MediaInfo from input.";
|
LOG(ERROR) << "Failed to generate MediaInfo from input.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (protection_scheme_ != FOURCC_NULL) {
|
||||||
|
internal::SetContentProtectionFields(protection_scheme_, next_key_id_,
|
||||||
|
next_key_system_infos_, &media_info);
|
||||||
|
}
|
||||||
|
|
||||||
const bool result = hls_notifier_->NotifyNewStream(
|
const bool result = hls_notifier_->NotifyNewStream(
|
||||||
media_info, playlist_name_, ext_x_media_name_, ext_x_media_group_id_,
|
media_info, playlist_name_, ext_x_media_name_, ext_x_media_group_id_,
|
||||||
&stream_id_);
|
&stream_id_);
|
||||||
|
|
|
@ -78,6 +78,7 @@ class HlsNotifyMuxerListener : public MuxerListener {
|
||||||
std::vector<uint8_t> next_key_id_;
|
std::vector<uint8_t> next_key_id_;
|
||||||
std::vector<uint8_t> next_iv_;
|
std::vector<uint8_t> next_iv_;
|
||||||
std::vector<ProtectionSystemSpecificInfo> next_key_system_infos_;
|
std::vector<ProtectionSystemSpecificInfo> next_key_system_infos_;
|
||||||
|
FourCC protection_scheme_ = FOURCC_NULL;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(HlsNotifyMuxerListener);
|
DISALLOW_COPY_AND_ASSIGN(HlsNotifyMuxerListener);
|
||||||
};
|
};
|
||||||
|
|
|
@ -69,6 +69,17 @@ const char kDefaultPlaylistName[] = "default_playlist.m3u8";
|
||||||
const char kDefaultName[] = "DEFAULTNAME";
|
const char kDefaultName[] = "DEFAULTNAME";
|
||||||
const char kDefaultGroupId[] = "DEFAULTGROUPID";
|
const char kDefaultGroupId[] = "DEFAULTGROUPID";
|
||||||
|
|
||||||
|
MATCHER_P(HasEncryptionScheme, expected_scheme, "") {
|
||||||
|
*result_listener << "it has_protected_content: "
|
||||||
|
<< arg.has_protected_content() << " has_protection_scheme: "
|
||||||
|
<< arg.protected_content().has_protection_scheme()
|
||||||
|
<< " protection_scheme: "
|
||||||
|
<< arg.protected_content().protection_scheme();
|
||||||
|
return arg.has_protected_content() &&
|
||||||
|
arg.protected_content().has_protection_scheme() &&
|
||||||
|
arg.protected_content().protection_scheme() == expected_scheme;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class HlsNotifyMuxerListenerTest : public ::testing::Test {
|
class HlsNotifyMuxerListenerTest : public ::testing::Test {
|
||||||
|
@ -152,8 +163,8 @@ TEST_F(HlsNotifyMuxerListenerTest, OnEncryptionStart) {
|
||||||
MuxerListener::kContainerMpeg2ts);
|
MuxerListener::kContainerMpeg2ts);
|
||||||
::testing::Mock::VerifyAndClearExpectations(&mock_notifier_);
|
::testing::Mock::VerifyAndClearExpectations(&mock_notifier_);
|
||||||
|
|
||||||
EXPECT_CALL(mock_notifier_,
|
EXPECT_CALL(mock_notifier_, NotifyEncryptionUpdate(_, key_id, system_id, iv,
|
||||||
NotifyEncryptionUpdate(_, key_id, system_id, iv, pssh_data))
|
info.CreateBox()))
|
||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
listener_.OnEncryptionStart();
|
listener_.OnEncryptionStart();
|
||||||
}
|
}
|
||||||
|
@ -190,8 +201,8 @@ TEST_F(HlsNotifyMuxerListenerTest, OnEncryptionStartBeforeMediaStart) {
|
||||||
// It doesn't really matter when this is called, could be called right away in
|
// It doesn't really matter when this is called, could be called right away in
|
||||||
// OnEncryptionStart() if that is possible. Just matters that it is called by
|
// OnEncryptionStart() if that is possible. Just matters that it is called by
|
||||||
// the time OnMediaStart() returns.
|
// the time OnMediaStart() returns.
|
||||||
EXPECT_CALL(mock_notifier_,
|
EXPECT_CALL(mock_notifier_, NotifyEncryptionUpdate(_, key_id, system_id, iv,
|
||||||
NotifyEncryptionUpdate(_, key_id, system_id, iv, pssh_data))
|
info.CreateBox()))
|
||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
listener_.OnEncryptionStart();
|
listener_.OnEncryptionStart();
|
||||||
listener_.OnMediaStart(muxer_options, *video_stream_info, 90000,
|
listener_.OnMediaStart(muxer_options, *video_stream_info, 90000,
|
||||||
|
@ -256,13 +267,45 @@ TEST_F(HlsNotifyMuxerListenerTest, OnEncryptionInfoReady) {
|
||||||
|
|
||||||
std::vector<uint8_t> iv(16, 0x54);
|
std::vector<uint8_t> iv(16, 0x54);
|
||||||
|
|
||||||
EXPECT_CALL(mock_notifier_,
|
EXPECT_CALL(mock_notifier_, NotifyEncryptionUpdate(_, key_id, system_id, iv,
|
||||||
NotifyEncryptionUpdate(_, key_id, system_id, iv, pssh_data))
|
info.CreateBox()))
|
||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
listener_.OnEncryptionInfoReady(kInitialEncryptionInfo, FOURCC_cbcs, key_id,
|
listener_.OnEncryptionInfoReady(kInitialEncryptionInfo, FOURCC_cbcs, key_id,
|
||||||
iv, key_system_infos);
|
iv, key_system_infos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify that if protection scheme is specified in OnEncryptionInfoReady(),
|
||||||
|
// the information is copied to MediaInfo in OnMediaStart().
|
||||||
|
TEST_F(HlsNotifyMuxerListenerTest, OnEncryptionInfoReadyWithProtectionScheme) {
|
||||||
|
ProtectionSystemSpecificInfo info;
|
||||||
|
std::vector<uint8_t> system_id(kAnySystemId,
|
||||||
|
kAnySystemId + arraysize(kAnySystemId));
|
||||||
|
info.set_system_id(system_id.data(), system_id.size());
|
||||||
|
std::vector<uint8_t> pssh_data(kAnyData, kAnyData + arraysize(kAnyData));
|
||||||
|
info.set_pssh_data(pssh_data);
|
||||||
|
|
||||||
|
std::vector<uint8_t> key_id(16, 0x05);
|
||||||
|
std::vector<ProtectionSystemSpecificInfo> key_system_infos;
|
||||||
|
key_system_infos.push_back(info);
|
||||||
|
|
||||||
|
std::vector<uint8_t> iv(16, 0x54);
|
||||||
|
|
||||||
|
listener_.OnEncryptionInfoReady(kInitialEncryptionInfo, FOURCC_cenc, key_id,
|
||||||
|
iv, key_system_infos);
|
||||||
|
::testing::Mock::VerifyAndClearExpectations(&mock_notifier_);
|
||||||
|
|
||||||
|
ON_CALL(mock_notifier_,
|
||||||
|
NotifyNewStream(HasEncryptionScheme("cenc"), _, _, _, _))
|
||||||
|
.WillByDefault(Return(true));
|
||||||
|
VideoStreamInfoParameters video_params = GetDefaultVideoStreamInfoParams();
|
||||||
|
std::shared_ptr<StreamInfo> video_stream_info =
|
||||||
|
CreateVideoStreamInfo(video_params);
|
||||||
|
MuxerOptions muxer_options;
|
||||||
|
|
||||||
|
listener_.OnMediaStart(muxer_options, *video_stream_info, 90000,
|
||||||
|
MuxerListener::kContainerMpeg2ts);
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure it doesn't crash.
|
// Make sure it doesn't crash.
|
||||||
TEST_F(HlsNotifyMuxerListenerTest, OnSampleDurationReady) {
|
TEST_F(HlsNotifyMuxerListenerTest, OnSampleDurationReady) {
|
||||||
listener_.OnSampleDurationReady(2340);
|
listener_.OnSampleDurationReady(2340);
|
||||||
|
|
|
@ -38,7 +38,7 @@ void MpdNotifyMuxerListener::OnEncryptionInfoReady(
|
||||||
LOG_IF(WARNING, is_encrypted_)
|
LOG_IF(WARNING, is_encrypted_)
|
||||||
<< "Updating initial encryption information.";
|
<< "Updating initial encryption information.";
|
||||||
protection_scheme_ = protection_scheme;
|
protection_scheme_ = protection_scheme;
|
||||||
default_key_id_.assign(key_id.begin(), key_id.end());
|
default_key_id_ = key_id;
|
||||||
key_system_info_ = key_system_info;
|
key_system_info_ = key_system_info;
|
||||||
is_encrypted_ = true;
|
is_encrypted_ = true;
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -74,7 +74,7 @@ class MpdNotifyMuxerListener : public MuxerListener {
|
||||||
bool is_encrypted_;
|
bool is_encrypted_;
|
||||||
// Storage for values passed to OnEncryptionInfoReady().
|
// Storage for values passed to OnEncryptionInfoReady().
|
||||||
FourCC protection_scheme_;
|
FourCC protection_scheme_;
|
||||||
std::string default_key_id_;
|
std::vector<uint8_t> default_key_id_;
|
||||||
std::vector<ProtectionSystemSpecificInfo> key_system_info_;
|
std::vector<ProtectionSystemSpecificInfo> key_system_info_;
|
||||||
|
|
||||||
// Saves all the subsegment information for VOD. This should be used to call
|
// Saves all the subsegment information for VOD. This should be used to call
|
||||||
|
|
|
@ -241,19 +241,18 @@ bool SetVodInformation(bool has_init_range,
|
||||||
|
|
||||||
void SetContentProtectionFields(
|
void SetContentProtectionFields(
|
||||||
FourCC protection_scheme,
|
FourCC protection_scheme,
|
||||||
const std::string& default_key_id,
|
const std::vector<uint8_t>& default_key_id,
|
||||||
const std::vector<ProtectionSystemSpecificInfo>& key_system_info,
|
const std::vector<ProtectionSystemSpecificInfo>& key_system_info,
|
||||||
MediaInfo* media_info) {
|
MediaInfo* media_info) {
|
||||||
DCHECK(media_info);
|
DCHECK(media_info);
|
||||||
MediaInfo::ProtectedContent* protected_content =
|
MediaInfo::ProtectedContent* protected_content =
|
||||||
media_info->mutable_protected_content();
|
media_info->mutable_protected_content();
|
||||||
|
|
||||||
DCHECK(protection_scheme == FOURCC_cenc || protection_scheme == FOURCC_cbc1 ||
|
|
||||||
protection_scheme == FOURCC_cens || protection_scheme == FOURCC_cbcs);
|
|
||||||
protected_content->set_protection_scheme(FourCCToString(protection_scheme));
|
protected_content->set_protection_scheme(FourCCToString(protection_scheme));
|
||||||
|
|
||||||
if (!default_key_id.empty())
|
if (!default_key_id.empty()) {
|
||||||
protected_content->set_default_key_id(default_key_id);
|
protected_content->set_default_key_id(default_key_id.data(),
|
||||||
|
default_key_id.size());
|
||||||
|
}
|
||||||
|
|
||||||
for (const ProtectionSystemSpecificInfo& info : key_system_info) {
|
for (const ProtectionSystemSpecificInfo& info : key_system_info) {
|
||||||
MediaInfo::ProtectedContent::ContentProtectionEntry* entry =
|
MediaInfo::ProtectedContent::ContentProtectionEntry* entry =
|
||||||
|
|
|
@ -54,7 +54,7 @@ bool SetVodInformation(bool has_init_range,
|
||||||
/// cannot be null.
|
/// cannot be null.
|
||||||
void SetContentProtectionFields(
|
void SetContentProtectionFields(
|
||||||
FourCC protection_scheme,
|
FourCC protection_scheme,
|
||||||
const std::string& default_key_id,
|
const std::vector<uint8_t>& default_key_id,
|
||||||
const std::vector<ProtectionSystemSpecificInfo>& key_system_info,
|
const std::vector<ProtectionSystemSpecificInfo>& key_system_info,
|
||||||
MediaInfo* media_info);
|
MediaInfo* media_info);
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ void VodMediaInfoDumpMuxerListener::OnEncryptionInfoReady(
|
||||||
<< "Updating (non initial) encryption info is not supported by "
|
<< "Updating (non initial) encryption info is not supported by "
|
||||||
"this module.";
|
"this module.";
|
||||||
protection_scheme_ = protection_scheme;
|
protection_scheme_ = protection_scheme;
|
||||||
default_key_id_.assign(default_key_id.begin(), default_key_id.end());
|
default_key_id_ = default_key_id;
|
||||||
key_system_info_ = key_system_info;
|
key_system_info_ = key_system_info;
|
||||||
is_encrypted_ = true;
|
is_encrypted_ = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ class VodMediaInfoDumpMuxerListener : public MuxerListener {
|
||||||
bool is_encrypted_;
|
bool is_encrypted_;
|
||||||
// Storage for values passed to OnEncryptionInfoReady().
|
// Storage for values passed to OnEncryptionInfoReady().
|
||||||
FourCC protection_scheme_;
|
FourCC protection_scheme_;
|
||||||
std::string default_key_id_;
|
std::vector<uint8_t> default_key_id_;
|
||||||
std::vector<ProtectionSystemSpecificInfo> key_system_info_;
|
std::vector<ProtectionSystemSpecificInfo> key_system_info_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(VodMediaInfoDumpMuxerListener);
|
DISALLOW_COPY_AND_ASSIGN(VodMediaInfoDumpMuxerListener);
|
||||||
|
|
Loading…
Reference in New Issue