Add Support for WebM Back
Adds support for WebM to the CDM. Decryption remains untouched, however the initialization data is passed differently for WebM. The previous version of this change broke playback for certain apps that were being allowed to pass invalid MIME types before this change was made. This version maintains backwards-compatiblity for these apps for now by rewriting their MIME types as "video/mp4". Merge of https://widevine-internal-review.googlesource.com/9225/ and https://widevine-internal-review.googlesource.com/9611/ from the Widevine cdm repo. Bug: 10638562 Change-Id: Ib37e838d08363f07b34b3a2e79a3f80a1f43e9ad
This commit is contained in:
@@ -124,6 +124,7 @@ CdmResponseType CdmEngine::CloseKeySetSession(const CdmKeySetId& key_set_id) {
|
||||
CdmResponseType CdmEngine::GenerateKeyRequest(
|
||||
const CdmSessionId& session_id,
|
||||
const CdmKeySetId& key_set_id,
|
||||
const std::string& mime_type,
|
||||
const CdmInitData& init_data,
|
||||
const CdmLicenseType license_type,
|
||||
CdmAppParameterMap& app_parameters,
|
||||
@@ -179,7 +180,7 @@ CdmResponseType CdmEngine::GenerateKeyRequest(
|
||||
}
|
||||
}
|
||||
|
||||
sts = iter->second->GenerateKeyRequest(init_data, license_type,
|
||||
sts = iter->second->GenerateKeyRequest(mime_type, init_data, license_type,
|
||||
app_parameters, key_request,
|
||||
server_url);
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ CdmResponseType CdmSession::RestoreOfflineSession(
|
||||
|
||||
DeviceFiles::LicenseState license_state;
|
||||
|
||||
if (!handle.RetrieveLicense(key_set_id, &license_state, &offline_pssh_data_,
|
||||
if (!handle.RetrieveLicense(key_set_id, &license_state, &offline_init_data_,
|
||||
&offline_key_request_, &offline_key_response_,
|
||||
&offline_key_renewal_request_,
|
||||
&offline_key_renewal_response_,
|
||||
@@ -119,9 +119,9 @@ bool CdmSession::VerifySession(const CdmKeySystem& key_system,
|
||||
}
|
||||
|
||||
CdmResponseType CdmSession::GenerateKeyRequest(
|
||||
const CdmInitData& init_data, const CdmLicenseType license_type,
|
||||
const CdmAppParameterMap& app_parameters, CdmKeyMessage* key_request,
|
||||
std::string* server_url) {
|
||||
const std::string& mime_type, const CdmInitData& init_data,
|
||||
const CdmLicenseType license_type, const CdmAppParameterMap& app_parameters,
|
||||
CdmKeyMessage* key_request, std::string* server_url) {
|
||||
if (reinitialize_session_) {
|
||||
CdmResponseType sts = Init();
|
||||
if (sts != NO_ERROR) {
|
||||
@@ -149,14 +149,18 @@ CdmResponseType CdmSession::GenerateKeyRequest(
|
||||
? UNKNOWN_ERROR
|
||||
: GenerateRenewalRequest(key_request, server_url);
|
||||
} else {
|
||||
if (mime_type != ISO_BMFF_MIME_TYPE && mime_type != WEBM_MIME_TYPE) {
|
||||
LOGW("CdmSession::GenerateKeyRequest: unknown MIME type");
|
||||
return KEY_ERROR;
|
||||
}
|
||||
if (init_data.empty() && !license_parser_.HasInitData()) {
|
||||
LOGW("CdmSession::GenerateKeyRequest: init data absent");
|
||||
return KEY_ERROR;
|
||||
}
|
||||
|
||||
CdmInitData pssh_data = init_data;
|
||||
if (Properties::extract_pssh_data()) {
|
||||
if (!CdmEngine::ExtractWidevinePssh(init_data, &pssh_data)) {
|
||||
CdmInitData extracted_init_data = init_data;
|
||||
if (Properties::extract_pssh_data() && mime_type == ISO_BMFF_MIME_TYPE) {
|
||||
if (!CdmEngine::ExtractWidevinePssh(init_data, &extracted_init_data)) {
|
||||
return KEY_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -172,14 +176,15 @@ CdmResponseType CdmSession::GenerateKeyRequest(
|
||||
}
|
||||
}
|
||||
|
||||
if (!license_parser_.PrepareKeyRequest(pssh_data, license_type,
|
||||
app_parameters, session_id_,
|
||||
key_request, server_url)) {
|
||||
if (!license_parser_.PrepareKeyRequest(mime_type, extracted_init_data,
|
||||
license_type, app_parameters,
|
||||
session_id_, key_request,
|
||||
server_url)) {
|
||||
return KEY_ERROR;
|
||||
}
|
||||
|
||||
if (license_type_ == kLicenseTypeOffline) {
|
||||
offline_pssh_data_ = pssh_data;
|
||||
offline_init_data_ = extracted_init_data;
|
||||
offline_key_request_ = *key_request;
|
||||
offline_release_server_url_ = *server_url;
|
||||
}
|
||||
@@ -410,7 +415,7 @@ bool CdmSession::StoreLicense(DeviceFiles::LicenseState state) {
|
||||
return false;
|
||||
|
||||
return handle.StoreLicense(
|
||||
key_set_id_, state, offline_pssh_data_, offline_key_request_,
|
||||
key_set_id_, state, offline_init_data_, offline_key_request_,
|
||||
offline_key_response_, offline_key_renewal_request_,
|
||||
offline_key_renewal_response_, offline_release_server_url_);
|
||||
}
|
||||
|
||||
@@ -84,6 +84,7 @@ using video_widevine_server::sdk::EncryptedClientIdentification;
|
||||
using video_widevine_server::sdk::LicenseRequest;
|
||||
using video_widevine_server::sdk::LicenseRequest_ContentIdentification;
|
||||
using video_widevine_server::sdk::LicenseRequest_ContentIdentification_CENC;
|
||||
using video_widevine_server::sdk::LicenseRequest_ContentIdentification_WebM;
|
||||
using video_widevine_server::sdk::
|
||||
LicenseRequest_ContentIdentification_ExistingLicense;
|
||||
using video_widevine_server::sdk::License;
|
||||
@@ -157,7 +158,8 @@ bool CdmLicense::Init(const std::string& token, CryptoSession* session,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CdmLicense::PrepareKeyRequest(const CdmInitData& init_data,
|
||||
bool CdmLicense::PrepareKeyRequest(const std::string& mime_type,
|
||||
const CdmInitData& init_data,
|
||||
const CdmLicenseType license_type,
|
||||
const CdmAppParameterMap& app_parameters,
|
||||
const CdmSessionId& session_id,
|
||||
@@ -167,7 +169,12 @@ bool CdmLicense::PrepareKeyRequest(const CdmInitData& init_data,
|
||||
LOGE("CdmLicense::PrepareKeyRequest: not initialized");
|
||||
return false;
|
||||
}
|
||||
if (init_data.empty() && init_data_.empty()) {
|
||||
if (mime_type != ISO_BMFF_MIME_TYPE && mime_type != WEBM_MIME_TYPE) {
|
||||
LOGE("CdmLicense::PrepareKeyRequest: unsupported MIME type %s",
|
||||
mime_type.c_str());
|
||||
return false;
|
||||
}
|
||||
if (init_data.empty() && stored_init_data_.empty()) {
|
||||
LOGE("CdmLicense::PrepareKeyRequest: empty init data provided");
|
||||
return false;
|
||||
}
|
||||
@@ -192,7 +199,7 @@ bool CdmLicense::PrepareKeyRequest(const CdmInitData& init_data,
|
||||
serialized_service_certificate = service_certificate_;
|
||||
|
||||
if (privacy_mode_enabled && serialized_service_certificate.empty()) {
|
||||
init_data_ = init_data;
|
||||
stored_init_data_ = init_data;
|
||||
return PrepareServiceCertificateRequest(signed_request, server_url);
|
||||
}
|
||||
|
||||
@@ -308,33 +315,44 @@ bool CdmLicense::PrepareKeyRequest(const CdmInitData& init_data,
|
||||
LicenseRequest_ContentIdentification* content_id =
|
||||
license_request.mutable_content_id();
|
||||
|
||||
LicenseRequest_ContentIdentification_CENC* cenc_content_id =
|
||||
content_id->mutable_cenc_id();
|
||||
if (mime_type == ISO_BMFF_MIME_TYPE) {
|
||||
LicenseRequest_ContentIdentification_CENC* cenc_content_id =
|
||||
content_id->mutable_cenc_id();
|
||||
|
||||
if (!init_data.empty()) {
|
||||
cenc_content_id->add_pssh(init_data);
|
||||
} else if (privacy_mode_enabled && !init_data_.empty()) {
|
||||
cenc_content_id->add_pssh(init_data_);
|
||||
if (!init_data.empty()) {
|
||||
cenc_content_id->add_pssh(init_data);
|
||||
} else if (privacy_mode_enabled && !stored_init_data_.empty()) {
|
||||
cenc_content_id->add_pssh(stored_init_data_);
|
||||
} else {
|
||||
LOGE("CdmLicense::PrepareKeyRequest: ISO-CENC init data not available");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!PrepareContentId(license_type, request_id, cenc_content_id)) {
|
||||
return false;
|
||||
}
|
||||
} else if (mime_type == WEBM_MIME_TYPE) {
|
||||
LicenseRequest_ContentIdentification_WebM* webm_content_id =
|
||||
content_id->mutable_webm_id();
|
||||
|
||||
if (!init_data.empty()) {
|
||||
webm_content_id->set_header(init_data);
|
||||
} else if (privacy_mode_enabled && !stored_init_data_.empty()) {
|
||||
webm_content_id->set_header(stored_init_data_);
|
||||
} else {
|
||||
LOGE("CdmLicense::PrepareKeyRequest: WebM init data not available");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!PrepareContentId(license_type, request_id, webm_content_id)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
LOGD("CdmLicense::PrepareKeyRequest: init data not available");
|
||||
LOGE("CdmLicense::PrepareKeyRequest: no support for MIME type %s",
|
||||
mime_type.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (license_type) {
|
||||
case kLicenseTypeOffline:
|
||||
cenc_content_id->set_license_type(video_widevine_server::sdk::OFFLINE);
|
||||
break;
|
||||
case kLicenseTypeStreaming:
|
||||
cenc_content_id->set_license_type(video_widevine_server::sdk::STREAMING);
|
||||
break;
|
||||
default:
|
||||
LOGD("CdmLicense::PrepareKeyRequest: Unknown license type = %d",
|
||||
license_type);
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
cenc_content_id->set_request_id(request_id);
|
||||
|
||||
// TODO(jfore): The time field will be updated once the cdm wrapper
|
||||
// has been updated to pass us in the time.
|
||||
license_request.set_request_time(0);
|
||||
@@ -766,6 +784,28 @@ CdmResponseType CdmLicense::HandleKeyErrorResponse(
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool CdmLicense::PrepareContentId(const CdmLicenseType license_type,
|
||||
const std::string& request_id,
|
||||
T* content_id) {
|
||||
switch (license_type) {
|
||||
case kLicenseTypeOffline:
|
||||
content_id->set_license_type(video_widevine_server::sdk::OFFLINE);
|
||||
break;
|
||||
case kLicenseTypeStreaming:
|
||||
content_id->set_license_type(
|
||||
video_widevine_server::sdk::STREAMING);
|
||||
break;
|
||||
default:
|
||||
LOGD("CdmLicense::PrepareKeyRequest: Unknown license type = %d",
|
||||
license_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
content_id->set_request_id(request_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CdmLicense::IsKeyLoaded(const KeyId& key_id) {
|
||||
return loaded_keys_.find(key_id) != loaded_keys_.end();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user