Support Latest Version of EME Spec Init Data Specification

(This is a merge of
https://widevine-internal-review.googlesource.com/9711 from the
Widevine CDM repo.)

This change updates the CDM's handling of init data types, previously
known as MIME types, to comply with the latest version of the EME
spec.

Following this change, in addition to accepting the deprecated MIME
types "video/mp4", "audio/mp4", "video/webm", and "audio/webm", the
CDM will accept the new standard: Init data types "cenc" and "webm".

Furthermore, this removes the non-PSSH-parsing path from the CDM. All
platforms have unified on the CDM being responsible for parsing the
concatenated PSSH box list, as outlined in the latest EME spec.

As Android has shipped code that expects pre-unwrapped PSSH boxes and
must maintain backwards-compatibility, code has been inserted on that
platform to detect pre-unwrapped data and re-wrap it with a PSSH
header before sending it to the CDM.

There are some small changes to unit tests because of this change:

1) The CDM Engine unit test now no longer needs to unwrap the PSSH on
   any platforms when testing ISO-BMFF. It now pre-caches the
   unwrapped key ID for use when testing WebM.

2) Several substantially-similar unit tests in the Android code have
   been rolled into one test.

Bug: 13564917
Bug: 13570595
Bug: 9465346
Bug: 13570288
Change-Id: I7f27b16b8503f24a26746b5dce71fb61b6fd1bb2
This commit is contained in:
John "Juce" Bruce
2014-04-09 17:51:42 -07:00
committed by John Bruce
parent de6f6f6324
commit 951f08c2da
13 changed files with 166 additions and 213 deletions

View File

@@ -29,7 +29,8 @@ const int kHttpOk = 200;
// Default license server, can be configured using --server command line option
// Default key id (pssh), can be configured using --keyid command line option
std::string g_client_auth;
wvcdm::KeyId g_key_id;
wvcdm::KeyId g_key_id_pssh;
wvcdm::KeyId g_key_id_unwrapped;
wvcdm::CdmKeySystem g_key_system;
std::string g_license_server;
std::string g_port;
@@ -112,16 +113,7 @@ class WvCdmEngineTest : public testing::Test {
std::string server_url;
CdmKeySetId key_set_id;
// TODO(rfrias): Temporary change till b/9465346 is addressed
CdmInitData extracted_init_data = key_id;
InitializationData init_data_type(init_data_type_string);
if (!Properties::extract_pssh_data() || !init_data_type.is_cenc()) {
EXPECT_TRUE(InitializationData::ExtractWidevinePssh(
key_id,
&extracted_init_data));
}
InitializationData init_data(init_data_type_string, extracted_init_data);
InitializationData init_data(init_data_type_string, key_id);
EXPECT_EQ(KEY_MESSAGE,
cdm_engine_.GenerateKeyRequest(session_id_,
@@ -207,13 +199,13 @@ TEST(WvCdmProvisioningTest, ProvisioningTest) {
}
TEST_F(WvCdmEngineTest, BaseIsoBmffMessageTest) {
GenerateKeyRequest(g_key_id, kCencMimeType);
GenerateKeyRequest(g_key_id_pssh, kCencMimeType);
GetKeyRequestResponse(g_license_server, g_client_auth);
}
// TODO(juce): Set up with correct test data.
TEST_F(WvCdmEngineTest, DISABLED_BaseWebmMessageTest) {
GenerateKeyRequest(g_key_id, kWebmMimeType);
GenerateKeyRequest(g_key_id_unwrapped, kWebmMimeType);
GetKeyRequestResponse(g_license_server, g_client_auth);
}
@@ -227,18 +219,18 @@ TEST_F(WvCdmEngineTest, WrongMessageTest) {
}
TEST_F(WvCdmEngineTest, NormalDecryptionIsoBmff) {
GenerateKeyRequest(g_key_id, kCencMimeType);
GenerateKeyRequest(g_key_id_pssh, kCencMimeType);
VerifyNewKeyResponse(g_license_server, g_client_auth);
}
// TODO(juce): Set up with correct test data.
TEST_F(WvCdmEngineTest, DISABLED_NormalDecryptionWebm) {
GenerateKeyRequest(g_key_id, kWebmMimeType);
GenerateKeyRequest(g_key_id_unwrapped, kWebmMimeType);
VerifyNewKeyResponse(g_license_server, g_client_auth);
}
TEST_F(WvCdmEngineTest, LicenseRenewal) {
GenerateKeyRequest(g_key_id, kCencMimeType);
GenerateKeyRequest(g_key_id_pssh, kCencMimeType);
VerifyNewKeyResponse(g_license_server, g_client_auth);
GenerateRenewalRequest();
@@ -259,7 +251,7 @@ int main(int argc, char **argv) {
// The following variables are configurable through command line options.
g_license_server.assign(config.license_server());
g_key_id.assign(config.key_id());
g_key_id_pssh.assign(config.key_id());
g_port.assign(config.port());
std::string license_server(g_license_server);
@@ -279,8 +271,8 @@ int main(int argc, char **argv) {
while ((opt = getopt_long(argc, argv, "k:p:s:u", long_options, &option_index)) != -1) {
switch (opt) {
case 'k': {
g_key_id.clear();
g_key_id.assign(optarg);
g_key_id_pssh.clear();
g_key_id_pssh.assign(optarg);
break;
}
case 'p': {
@@ -323,7 +315,7 @@ int main(int argc, char **argv) {
std::cout << std::setw(30) << std::left << " --keyid=<key_id>";
std::cout << "configure the key id or pssh, in hex format" << std::endl;
std::cout << std::setw(30) << std::left << " default keyid:";
std::cout << g_key_id << std::endl;
std::cout << g_key_id_pssh << std::endl;
std::cout << std::setw(30) << std::left << " --use_full_path";
std::cout << "specify server url is not a proxy server" << std::endl;
@@ -334,12 +326,17 @@ int main(int argc, char **argv) {
std::cout << std::endl;
std::cout << "Server: " << g_license_server << std::endl;
std::cout << "Port: " << g_port << std::endl;
std::cout << "KeyID: " << g_key_id << std::endl << std::endl;
std::cout << "KeyID: " << g_key_id_pssh << std::endl << std::endl;
g_key_id = wvcdm::a2bs_hex(g_key_id);
g_key_id_pssh = wvcdm::a2bs_hex(g_key_id_pssh);
config.set_license_server(g_license_server);
config.set_port(g_port);
config.set_key_id(g_key_id);
config.set_key_id(g_key_id_pssh);
// Extract the key ID from the PSSH box.
wvcdm::InitializationData extractor(wvcdm::CENC_INIT_DATA_FORMAT,
g_key_id_pssh);
g_key_id_unwrapped = extractor.data();
#if defined(CHROMIUM_BUILD)
base::AtExitManager exit;