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_iv_ = iv;
|
||||
next_key_system_infos_ = key_system_infos;
|
||||
protection_scheme_ = protection_scheme;
|
||||
return;
|
||||
}
|
||||
for (const ProtectionSystemSpecificInfo& info : key_system_infos) {
|
||||
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.";
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +73,7 @@ void HlsNotifyMuxerListener::OnEncryptionStart() {
|
|||
for (const ProtectionSystemSpecificInfo& info : next_key_system_infos_) {
|
||||
const bool result = hls_notifier_->NotifyEncryptionUpdate(
|
||||
stream_id_, next_key_id_, info.system_id(), next_iv_,
|
||||
info.pssh_data());
|
||||
info.CreateBox());
|
||||
LOG_IF(WARNING, !result) << "Failed to add encryption info";
|
||||
}
|
||||
next_key_id_.clear();
|
||||
|
@ -91,6 +92,11 @@ void HlsNotifyMuxerListener::OnMediaStart(const MuxerOptions& muxer_options,
|
|||
LOG(ERROR) << "Failed to generate MediaInfo from input.";
|
||||
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(
|
||||
media_info, playlist_name_, ext_x_media_name_, ext_x_media_group_id_,
|
||||
&stream_id_);
|
||||
|
|
|
@ -78,6 +78,7 @@ class HlsNotifyMuxerListener : public MuxerListener {
|
|||
std::vector<uint8_t> next_key_id_;
|
||||
std::vector<uint8_t> next_iv_;
|
||||
std::vector<ProtectionSystemSpecificInfo> next_key_system_infos_;
|
||||
FourCC protection_scheme_ = FOURCC_NULL;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(HlsNotifyMuxerListener);
|
||||
};
|
||||
|
|
|
@ -69,6 +69,17 @@ const char kDefaultPlaylistName[] = "default_playlist.m3u8";
|
|||
const char kDefaultName[] = "DEFAULTNAME";
|
||||
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
|
||||
|
||||
class HlsNotifyMuxerListenerTest : public ::testing::Test {
|
||||
|
@ -152,8 +163,8 @@ TEST_F(HlsNotifyMuxerListenerTest, OnEncryptionStart) {
|
|||
MuxerListener::kContainerMpeg2ts);
|
||||
::testing::Mock::VerifyAndClearExpectations(&mock_notifier_);
|
||||
|
||||
EXPECT_CALL(mock_notifier_,
|
||||
NotifyEncryptionUpdate(_, key_id, system_id, iv, pssh_data))
|
||||
EXPECT_CALL(mock_notifier_, NotifyEncryptionUpdate(_, key_id, system_id, iv,
|
||||
info.CreateBox()))
|
||||
.WillOnce(Return(true));
|
||||
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
|
||||
// OnEncryptionStart() if that is possible. Just matters that it is called by
|
||||
// the time OnMediaStart() returns.
|
||||
EXPECT_CALL(mock_notifier_,
|
||||
NotifyEncryptionUpdate(_, key_id, system_id, iv, pssh_data))
|
||||
EXPECT_CALL(mock_notifier_, NotifyEncryptionUpdate(_, key_id, system_id, iv,
|
||||
info.CreateBox()))
|
||||
.WillOnce(Return(true));
|
||||
listener_.OnEncryptionStart();
|
||||
listener_.OnMediaStart(muxer_options, *video_stream_info, 90000,
|
||||
|
@ -256,13 +267,45 @@ TEST_F(HlsNotifyMuxerListenerTest, OnEncryptionInfoReady) {
|
|||
|
||||
std::vector<uint8_t> iv(16, 0x54);
|
||||
|
||||
EXPECT_CALL(mock_notifier_,
|
||||
NotifyEncryptionUpdate(_, key_id, system_id, iv, pssh_data))
|
||||
EXPECT_CALL(mock_notifier_, NotifyEncryptionUpdate(_, key_id, system_id, iv,
|
||||
info.CreateBox()))
|
||||
.WillOnce(Return(true));
|
||||
listener_.OnEncryptionInfoReady(kInitialEncryptionInfo, FOURCC_cbcs, key_id,
|
||||
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.
|
||||
TEST_F(HlsNotifyMuxerListenerTest, OnSampleDurationReady) {
|
||||
listener_.OnSampleDurationReady(2340);
|
||||
|
|
|
@ -38,7 +38,7 @@ void MpdNotifyMuxerListener::OnEncryptionInfoReady(
|
|||
LOG_IF(WARNING, is_encrypted_)
|
||||
<< "Updating initial encryption information.";
|
||||
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;
|
||||
is_encrypted_ = true;
|
||||
return;
|
||||
|
|
|
@ -74,7 +74,7 @@ class MpdNotifyMuxerListener : public MuxerListener {
|
|||
bool is_encrypted_;
|
||||
// Storage for values passed to OnEncryptionInfoReady().
|
||||
FourCC protection_scheme_;
|
||||
std::string default_key_id_;
|
||||
std::vector<uint8_t> default_key_id_;
|
||||
std::vector<ProtectionSystemSpecificInfo> key_system_info_;
|
||||
|
||||
// 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(
|
||||
FourCC protection_scheme,
|
||||
const std::string& default_key_id,
|
||||
const std::vector<uint8_t>& default_key_id,
|
||||
const std::vector<ProtectionSystemSpecificInfo>& key_system_info,
|
||||
MediaInfo* media_info) {
|
||||
DCHECK(media_info);
|
||||
MediaInfo::ProtectedContent* 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));
|
||||
|
||||
if (!default_key_id.empty())
|
||||
protected_content->set_default_key_id(default_key_id);
|
||||
if (!default_key_id.empty()) {
|
||||
protected_content->set_default_key_id(default_key_id.data(),
|
||||
default_key_id.size());
|
||||
}
|
||||
|
||||
for (const ProtectionSystemSpecificInfo& info : key_system_info) {
|
||||
MediaInfo::ProtectedContent::ContentProtectionEntry* entry =
|
||||
|
|
|
@ -54,7 +54,7 @@ bool SetVodInformation(bool has_init_range,
|
|||
/// cannot be null.
|
||||
void SetContentProtectionFields(
|
||||
FourCC protection_scheme,
|
||||
const std::string& default_key_id,
|
||||
const std::vector<uint8_t>& default_key_id,
|
||||
const std::vector<ProtectionSystemSpecificInfo>& key_system_info,
|
||||
MediaInfo* media_info);
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ void VodMediaInfoDumpMuxerListener::OnEncryptionInfoReady(
|
|||
<< "Updating (non initial) encryption info is not supported by "
|
||||
"this module.";
|
||||
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;
|
||||
is_encrypted_ = true;
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ class VodMediaInfoDumpMuxerListener : public MuxerListener {
|
|||
bool is_encrypted_;
|
||||
// Storage for values passed to OnEncryptionInfoReady().
|
||||
FourCC protection_scheme_;
|
||||
std::string default_key_id_;
|
||||
std::vector<uint8_t> default_key_id_;
|
||||
std::vector<ProtectionSystemSpecificInfo> key_system_info_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(VodMediaInfoDumpMuxerListener);
|
||||
|
|
Loading…
Reference in New Issue