Commit d4655dce authored by John Rummell's avatar John Rummell Committed by Commit Bot

[eme] Enable Clear Key CDM to support 'cbcs' decryption

Now that AesDecryptor supports 'cbcs' decryption, update the
Clear Key CDM to do the same.

BUG=658026,835009
TEST=modified browser_test passes

Change-Id: Ie138d4b638d5d6493cb89368171adae5660486da
Reviewed-on: https://chromium-review.googlesource.com/1053172Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Reviewed-by: default avatarXiaohan Wang <xhwang@chromium.org>
Commit-Queue: John Rummell <jrummell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#557625}
parent 739c2c89
......@@ -803,9 +803,15 @@ IN_PROC_BROWSER_TEST_P(ECKEncryptedMediaTest, Playback_Encryption_CENS) {
}
IN_PROC_BROWSER_TEST_P(ECKEncryptedMediaTest, Playback_Encryption_CBCS) {
// 'cbcs' decryption is only supported on CDM 10 or later as long as
// the appropriate buildflag is enabled.
std::string expected_result =
GetCdmInterfaceVersion() >= 10 && BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
? media::kEnded
: media::kError;
TestMp4EncryptionPlayback(kExternalClearKeyKeySystem,
"bear-640x360-v_frag-cbcs.mp4", kMp4Avc1VideoOnly,
media::kError);
expected_result);
}
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
......
......@@ -567,13 +567,11 @@ void ChromeContentClient::AddContentDecryptionModules(
// Otherwise, it'll be treated as a sub-key-system of normal
// kExternalClearKeyKeySystem. See MultipleCdmTypes test in
// ECKEncryptedMediaTest.
// TODO(crbug.com/835009): Update when ECK supports more encryption
// schemes.
cdms->push_back(content::CdmInfo(
media::kClearKeyCdmDisplayName, media::kClearKeyCdmDifferentGuid,
base::Version("0.1.0.0"), clear_key_cdm_path,
media::kClearKeyCdmFileSystemId, {}, supports_persistent_license,
{media::EncryptionMode::kCenc},
{media::EncryptionMode::kCenc, media::EncryptionMode::kCbcs},
kExternalClearKeyDifferentGuidTestKeySystem, false));
// Supported codecs are hard-coded in ExternalClearKeyProperties.
......@@ -581,7 +579,8 @@ void ChromeContentClient::AddContentDecryptionModules(
media::kClearKeyCdmDisplayName, media::kClearKeyCdmGuid,
base::Version("0.1.0.0"), clear_key_cdm_path,
media::kClearKeyCdmFileSystemId, {}, supports_persistent_license,
{media::EncryptionMode::kCenc}, kExternalClearKeyKeySystem, true));
{media::EncryptionMode::kCenc, media::EncryptionMode::kCbcs},
kExternalClearKeyKeySystem, true));
}
#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS)
}
......
......@@ -21,6 +21,7 @@
#include "media/base/cdm_key_information.h"
#include "media/base/decoder_buffer.h"
#include "media/base/decrypt_config.h"
#include "media/base/encryption_pattern.h"
#include "media/cdm/api/content_decryption_module_ext.h"
#include "media/cdm/json_web_key.h"
#include "media/cdm/library_cdm/cdm_host_proxy.h"
......@@ -95,23 +96,32 @@ static scoped_refptr<media::DecoderBuffer> CopyDecoderBufferFrom(
output_buffer->set_timestamp(
base::TimeDelta::FromMicroseconds(input_buffer.timestamp));
// TODO(crbug.com/658026): Support other schemes.
if (input_buffer.encryption_scheme == cdm::EncryptionScheme::kCenc) {
DCHECK_GT(input_buffer.iv_size, 0u);
DCHECK_GT(input_buffer.key_id_size, 0u);
std::vector<media::SubsampleEntry> subsamples;
for (uint32_t i = 0; i < input_buffer.num_subsamples; ++i) {
subsamples.push_back(
media::SubsampleEntry(input_buffer.subsamples[i].clear_bytes,
input_buffer.subsamples[i].cipher_bytes));
}
if (input_buffer.encryption_scheme == cdm::EncryptionScheme::kUnencrypted)
return output_buffer;
DCHECK_GT(input_buffer.iv_size, 0u);
DCHECK_GT(input_buffer.key_id_size, 0u);
std::vector<media::SubsampleEntry> subsamples;
for (uint32_t i = 0; i < input_buffer.num_subsamples; ++i) {
subsamples.push_back(
media::SubsampleEntry(input_buffer.subsamples[i].clear_bytes,
input_buffer.subsamples[i].cipher_bytes));
}
const std::string key_id_string(
reinterpret_cast<const char*>(input_buffer.key_id),
input_buffer.key_id_size);
const std::string iv_string(reinterpret_cast<const char*>(input_buffer.iv),
input_buffer.iv_size);
if (input_buffer.encryption_scheme == cdm::EncryptionScheme::kCenc) {
output_buffer->set_decrypt_config(media::DecryptConfig::CreateCencConfig(
std::string(reinterpret_cast<const char*>(input_buffer.key_id),
input_buffer.key_id_size),
std::string(reinterpret_cast<const char*>(input_buffer.iv),
input_buffer.iv_size),
subsamples));
key_id_string, iv_string, subsamples));
} else {
DCHECK_EQ(input_buffer.encryption_scheme, cdm::EncryptionScheme::kCbcs);
output_buffer->set_decrypt_config(media::DecryptConfig::CreateCbcsConfig(
key_id_string, iv_string, subsamples,
media::EncryptionPattern(input_buffer.pattern.crypt_byte_block,
input_buffer.pattern.skip_byte_block)));
}
return output_buffer;
......@@ -362,36 +372,6 @@ namespace media {
namespace {
bool IsSupportedConfigEncryptionScheme(cdm::EncryptionScheme scheme) {
// TODO(crbug.com/658026): Support other decryption schemes.
switch (scheme) {
case cdm::EncryptionScheme::kUnencrypted:
case cdm::EncryptionScheme::kCenc:
return true;
case cdm::EncryptionScheme::kCbcs:
return false;
}
NOTREACHED();
return false;
}
bool IsSupportedBufferEncryptionScheme(cdm::EncryptionScheme scheme,
cdm::Pattern pattern) {
// TODO(crbug.com/658026): Support other decryption schemes.
switch (scheme) {
case cdm::EncryptionScheme::kUnencrypted:
return true;
case cdm::EncryptionScheme::kCenc:
return pattern.crypt_byte_block == 0 && pattern.skip_byte_block == 0;
case cdm::EncryptionScheme::kCbcs:
return false;
}
NOTREACHED();
return false;
}
cdm::InputBuffer_2 ToInputBuffer_2(cdm::InputBuffer_1 encrypted_buffer) {
cdm::InputBuffer_2 buffer = {};
buffer.data = encrypted_buffer.data;
......@@ -707,11 +687,6 @@ cdm::Status ClearKeyCdm::InitializeAudioDecoder(
if (key_system_ == kExternalClearKeyDecryptOnlyKeySystem)
return cdm::kInitializationError;
if (!IsSupportedConfigEncryptionScheme(
audio_decoder_config.encryption_scheme)) {
return cdm::kInitializationError;
}
#if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER)
if (!audio_decoder_)
audio_decoder_.reset(
......@@ -744,11 +719,6 @@ cdm::Status ClearKeyCdm::InitializeVideoDecoder(
if (key_system_ == kExternalClearKeyDecryptOnlyKeySystem)
return cdm::kInitializationError;
if (!IsSupportedConfigEncryptionScheme(
video_decoder_config.encryption_scheme)) {
return cdm::kInitializationError;
}
if (video_decoder_ && video_decoder_->is_initialized()) {
DCHECK(!video_decoder_->is_initialized());
return cdm::kInitializationError;
......@@ -894,11 +864,6 @@ cdm::Status ClearKeyCdm::DecryptToMediaDecoderBuffer(
scoped_refptr<DecoderBuffer>* decrypted_buffer) {
DCHECK(decrypted_buffer);
if (!IsSupportedBufferEncryptionScheme(encrypted_buffer.encryption_scheme,
encrypted_buffer.pattern)) {
return cdm::kDecryptError;
}
scoped_refptr<DecoderBuffer> buffer = CopyDecoderBufferFrom(encrypted_buffer);
// EOS and unencrypted streams can be returned as-is.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment