Support Dual PSSHs

Merge from Widevine repo of http://go/wvgerrit/48842

In order to work around a limitation of some versions of OEMCrypto,
the packager is going to start generating files with multiple Widevine
PSSH boxes. For backwards-compatibility, the first PSSH will be a
SINGLE-type PSSH while the ENTITLED_KEYS-type PSSH (if any) will come
later. In order to use entitlement licenses, then, the CDM needs to
change how it selects PSSHs from the init data blob.

Previously, the CDM always took the first Widevine PSSH it found. Now,
it must find all the Widevine PSSHs and select the appropriate PSSH
for the OEMCrypto implementation. ENTITLTED_KEYS will be used on OEC
v14 and later, if available, while SINGLE will be preferred on earlier
OEMCrypto versions.

As a side-effect of this, the CDM is now stricter about what PSSH
payloads it will accept. Previously, it would blindly accept the
payload of any PSSH where the wrapper was not malformed. Now, it
sometimes has to actually parse the payload, and therefore PSSHs that
have corrupted payloads will be rejected. This affected a few unit
tests which used PSSHs that were malformed. These tests have been
updated to use PSSHs that do not fail to parse.

Bug: 78142219
Test: CE CDM Unit Tests
Test: Android Unit Tests
Test: Android Google Play & Netflix
Test: tested as part of http://go/ag/4674759
Change-Id: Ia70d627a914299bfbae84b4cb46f100dc5c7a501
This commit is contained in:
Fred Gylys-Colwell
2018-06-30 23:38:38 -07:00
parent a242a32bba
commit 08c57e7a8e
4 changed files with 406 additions and 136 deletions

View File

@@ -17,7 +17,8 @@ class WvCdmEngineTest;
class InitializationData {
public:
InitializationData(const std::string& type = std::string(),
const CdmInitData& data = CdmInitData());
const CdmInitData& data = CdmInitData(),
const std::string& oec_version = std::string());
bool is_supported() const { return is_cenc_ || is_webm_ || is_hls_; }
bool is_cenc() const { return is_cenc_; }
@@ -36,9 +37,15 @@ class InitializationData {
std::vector<video_widevine::WrappedKey> ExtractWrappedKeys() const;
private:
// Parse a blob of multiple concatenated PSSH atoms to extract the first
// Widevine PSSH.
bool ExtractWidevinePssh(const CdmInitData& init_data, CdmInitData* output);
bool SelectWidevinePssh(const CdmInitData& init_data,
bool prefer_entitlements,
CdmInitData* output);
// Helpers used by SelectWidevinePssh().
bool ExtractWidevinePsshs(const CdmInitData& init_data,
std::vector<CdmInitData>* psshs);
bool ExtractWidevinePsshData(const uint8_t* data,
size_t length,
CdmInitData* output);
bool ExtractHlsAttributes(const std::string& attribute_list,
CdmHlsMethod* method, std::vector<uint8_t>* iv,
@@ -58,6 +65,9 @@ class InitializationData {
static std::vector<std::string> ExtractKeyFormatVersions(
const std::string& key_format_versions);
static bool DetectEntitlementPreference(
const std::string& oec_version_string);
// For testing only:
#if defined(UNIT_TEST)
FRIEND_TEST(HlsAttributeExtractionTest, ExtractAttribute);