This repository has been archived by the owner on Apr 3, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 211
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge 317490 "Handle 'cenc' Initialization Data Type in Clear Key."
> Handle 'cenc' Initialization Data Type in Clear Key. > > Initialization data is provided as concatentated PSSH boxes. Parse the > PSSH boxes and extract the keys, if present. Only process the PSSH > boxes that contain the Clear Key SystemID, all other PSSH boxes are > skipped. > > This handles both version 0 and version 1 PSSH boxes. > > BUG=459850 > TEST=new tests pass > > Review URL: https://codereview.chromium.org/936953005 Cr-Commit-Position: refs/heads/master@{#317490} (cherry picked from commit 0961c42) [email protected] Review URL: https://codereview.chromium.org/958183003 Cr-Commit-Position: refs/branch-heads/2311@{#45} Cr-Branched-From: 09b7de5-refs/heads/master@{#317474}
- Loading branch information
1 parent
16e8996
commit e078ba0
Showing
11 changed files
with
637 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
// Copyright 2015 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "media/cdm/cenc_utils.h" | ||
|
||
#include "media/base/bit_reader.h" | ||
|
||
namespace media { | ||
|
||
// The initialization data for encrypted media files using the ISO Common | ||
// Encryption ('cenc') protection scheme may contain one or more protection | ||
// system specific header ('pssh') boxes. | ||
// ref: https://w3c.github.io/encrypted-media/cenc-format.html | ||
// | ||
// The format of a 'pssh' box is as follows: | ||
// unsigned int(32) size; | ||
// unsigned int(32) type = "pssh"; | ||
// if (size==1) { | ||
// unsigned int(64) largesize; | ||
// } else if (size==0) { | ||
// -- box extends to end of file | ||
// } | ||
// unsigned int(8) version; | ||
// bit(24) flags; | ||
// unsigned int(8)[16] SystemID; | ||
// if (version > 0) | ||
// { | ||
// unsigned int(32) KID_count; | ||
// { | ||
// unsigned int(8)[16] KID; | ||
// } [KID_count] | ||
// } | ||
// unsigned int(32) DataSize; | ||
// unsigned int(8)[DataSize] Data; | ||
|
||
// Minimum size of a 'pssh' box includes all the required fields (size, type, | ||
// version, flags, SystemID, DataSize). | ||
const int kMinimumBoxSizeInBytes = 32; | ||
|
||
// SystemID for the Common System. | ||
// https://w3c.github.io/encrypted-media/cenc-format.html#common-system | ||
const uint8 kCommonSystemId[] = { 0x10, 0x77, 0xef, 0xec, | ||
0xc0, 0xb2, 0x4d, 0x02, | ||
0xac, 0xe3, 0x3c, 0x1e, | ||
0x52, 0xe2, 0xfb, 0x4b }; | ||
|
||
#define RCHECK(x) \ | ||
do { \ | ||
if (!(x)) \ | ||
return false; \ | ||
} while (0) | ||
|
||
// Helper function to read up to 32 bits from a bit stream. | ||
static uint32 ReadBits(BitReader* reader, int num_bits) { | ||
DCHECK_GE(reader->bits_available(), num_bits); | ||
DCHECK((num_bits > 0) && (num_bits <= 32)); | ||
uint32 value; | ||
reader->ReadBits(num_bits, &value); | ||
return value; | ||
} | ||
|
||
// Checks whether the next 16 bytes matches the Common SystemID. | ||
// Assumes |reader| has enough data. | ||
static bool IsCommonSystemID(BitReader* reader) { | ||
for (uint32 i = 0; i < arraysize(kCommonSystemId); ++i) { | ||
if (ReadBits(reader, 8) != kCommonSystemId[i]) | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
bool GetKeyIdsForCommonSystemId(const uint8* input, | ||
int input_length, | ||
std::vector<std::vector<uint8>>* key_ids) { | ||
int offset = 0; | ||
std::vector<std::vector<uint8>> result; | ||
|
||
while (offset < input_length) { | ||
BitReader reader(input + offset, input_length - offset); | ||
|
||
// Enough data for a miniumum size 'pssh' box? | ||
RCHECK(reader.bits_available() >= kMinimumBoxSizeInBytes * 8); | ||
|
||
uint32 size = ReadBits(&reader, 32); | ||
|
||
// Must be a 'pssh' box or else fail. | ||
RCHECK(ReadBits(&reader, 8) == 'p'); | ||
RCHECK(ReadBits(&reader, 8) == 's'); | ||
RCHECK(ReadBits(&reader, 8) == 's'); | ||
RCHECK(ReadBits(&reader, 8) == 'h'); | ||
|
||
if (size == 1) { | ||
// If largesize > 2**32 it is too big. | ||
RCHECK(ReadBits(&reader, 32) == 0); | ||
size = ReadBits(&reader, 32); | ||
} else if (size == 0) { | ||
size = input_length - offset; | ||
} | ||
|
||
// Check that the buffer contains at least size bytes. | ||
RCHECK(static_cast<uint32>(input_length - offset) >= size); | ||
|
||
// Update offset to point at the next 'pssh' box (may not be one). | ||
offset += size; | ||
|
||
// Check the version, as KIDs only available if version > 0. | ||
uint8 version = ReadBits(&reader, 8); | ||
if (version == 0) | ||
continue; | ||
|
||
// flags must be 0. If not, assume incorrect 'pssh' box and move to the | ||
// next one. | ||
if (ReadBits(&reader, 24) != 0) | ||
continue; | ||
|
||
// Validate SystemID | ||
RCHECK(static_cast<uint32>(reader.bits_available()) >= | ||
arraysize(kCommonSystemId) * 8); | ||
if (!IsCommonSystemID(&reader)) | ||
continue; // Not Common System, so try the next pssh box. | ||
|
||
// Since version > 0, next field is the KID_count. | ||
RCHECK(static_cast<uint32>(reader.bits_available()) >= sizeof(uint32) * 8); | ||
uint32 count = ReadBits(&reader, 32); | ||
|
||
if (count == 0) | ||
continue; | ||
|
||
// Make sure there is enough data for all the KIDs specified, and then | ||
// extract them. | ||
RCHECK(static_cast<uint32>(reader.bits_available()) > count * 16 * 8); | ||
while (count > 0) { | ||
std::vector<uint8> key; | ||
key.reserve(16); | ||
for (int i = 0; i < 16; ++i) { | ||
key.push_back(ReadBits(&reader, 8)); | ||
} | ||
result.push_back(key); | ||
--count; | ||
} | ||
|
||
// Don't bother checking DataSize and Data. | ||
} | ||
|
||
key_ids->swap(result); | ||
|
||
// TODO(jrummell): This should return true only if there was at least one | ||
// key ID present. However, numerous test files don't contain the 'pssh' box | ||
// for Common Format, so no keys are found. http://crbug.com/460308 | ||
return true; | ||
} | ||
|
||
} // namespace media |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// Copyright 2015 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef MEDIA_CDM_CENC_UTILS_H_ | ||
#define MEDIA_CDM_CENC_UTILS_H_ | ||
|
||
#include <vector> | ||
|
||
#include "base/basictypes.h" | ||
#include "media/base/media_export.h" | ||
|
||
namespace media { | ||
|
||
// Gets the Key Ids from a 'pssh' box for the Common SystemID among one or | ||
// more concatenated 'pssh' boxes. If |input| looks valid, then true is | ||
// returned and |key_ids| is updated to contain the values found. Otherwise | ||
// return false. | ||
// TODO(jrummell): This returns true if no Common SystemID 'pssh' boxes are | ||
// found, or are included but don't contain any key IDs. This should be | ||
// fixed once the test files are updated to include correct 'pssh' boxes. | ||
// http://crbug.com/460308 | ||
MEDIA_EXPORT bool GetKeyIdsForCommonSystemId( | ||
const uint8* input, | ||
int input_length, | ||
std::vector<std::vector<uint8>>* key_ids); | ||
|
||
} // namespace media | ||
|
||
#endif // MEDIA_CDM_CENC_UTILS_H_ |
Oops, something went wrong.