Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(677)

Unified Diff: media/cdm/cenc_utils.cc

Issue 1145853002: DONT REVIEW: Move GetPsshData() into cenc_utils (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/cdm/cenc_utils.h ('k') | media/cdm/cenc_utils_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/cdm/cenc_utils.cc
diff --git a/media/cdm/cenc_utils.cc b/media/cdm/cenc_utils.cc
index 86779b2174092ce5d0e3b5f5dca6a9c2f965c912..b184bd259631e50c83365cd4b752f7603512e9b0 100644
--- a/media/cdm/cenc_utils.cc
+++ b/media/cdm/cenc_utils.cc
@@ -33,10 +33,18 @@ namespace media {
// }
// unsigned int(32) DataSize;
// unsigned int(8)[DataSize] Data;
+// Only versions 0 and 1 of the 'pssh' boxes are supported. Any other versions
+// are ignored.
// Minimum size of a 'pssh' box includes all the required fields (size, type,
// version, flags, SystemID, DataSize).
-const int kMinimumBoxSizeInBytes = 32;
+const uint32_t kMinimumBoxSizeInBytes = 32;
+
+// Size of a SystemID field in bytes.
+const uint32_t kSystemIDSizeInBytes = 16;
+
+// Size of a KID field in bytes.
+const uint32_t kKIDSizeInBytes = 16;
// SystemID for the Common System.
// https://w3c.github.io/encrypted-media/cenc-format.html#common-system
@@ -60,11 +68,17 @@ static uint32_t ReadBits(BitReader* reader, int num_bits) {
return value;
}
-// Checks whether the next 16 bytes matches the Common SystemID.
-// Assumes |reader| has enough data.
-static bool IsCommonSystemID(BitReader* reader) {
- for (uint32_t i = 0; i < arraysize(kCommonSystemId); ++i) {
- if (ReadBits(reader, 8) != kCommonSystemId[i])
+// Return the number of bytes available in |reader|.
+static uint32_t BytesAvailable(BitReader* reader) {
+ return reader->bits_available() / 8;
+}
+
+// Checks whether the next bytes in |reader| match the specified |system_id|.
+static bool MatchSystemID(BitReader* reader,
+ const std::vector<uint8_t>& system_id) {
+ RCHECK(BytesAvailable(reader) >= system_id.size());
+ for (const auto& data : system_id) {
+ if (ReadBits(reader, 8) != data)
return false;
}
return true;
@@ -75,9 +89,9 @@ static bool IsCommonSystemID(BitReader* reader) {
// if the header looks valid and |reader| contains enough data for the size of
// header. |size| is updated as the computed size of the box header. Otherwise
// false is returned.
-static bool ValidBoxHeader(BitReader* reader, uint32* size) {
+static bool ValidBoxHeader(BitReader* reader, uint32_t* size) {
// Enough data for a miniumum size 'pssh' box?
- uint32 available_bytes = reader->bits_available() / 8;
+ uint32_t available_bytes = BytesAvailable(reader);
RCHECK(available_bytes >= kMinimumBoxSizeInBytes);
*size = ReadBits(reader, 32);
@@ -105,7 +119,7 @@ bool ValidatePsshInput(const std::vector<uint8_t>& input) {
while (offset < input.size()) {
// Create a BitReader over the remaining part of the buffer.
BitReader reader(&input[offset], input.size() - offset);
- uint32 size;
+ uint32_t size;
RCHECK(ValidBoxHeader(&reader, &size));
// Update offset to point at the next 'pssh' box (may not be one).
@@ -120,18 +134,21 @@ bool GetKeyIdsForCommonSystemId(const std::vector<uint8_t>& input,
KeyIdList* key_ids) {
size_t offset = 0;
KeyIdList result;
+ std::vector<uint8_t> common_system_id(
+ kCommonSystemId, kCommonSystemId + arraysize(kCommonSystemId));
while (offset < input.size()) {
BitReader reader(&input[offset], input.size() - offset);
- uint32 size;
+ uint32_t size;
RCHECK(ValidBoxHeader(&reader, &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.
+ // Check the version. Only version 0 and 1 'pssh' boxes are supported.
+ // However, KIDs only available if version > 0, so skip if version != 1.
uint8_t version = ReadBits(&reader, 8);
- if (version == 0)
+ if (version != 1)
continue;
// flags must be 0. If not, assume incorrect 'pssh' box and move to the
@@ -140,14 +157,11 @@ bool GetKeyIdsForCommonSystemId(const std::vector<uint8_t>& input,
continue;
// Validate SystemID
- RCHECK(static_cast<uint32_t>(reader.bits_available()) >=
- arraysize(kCommonSystemId) * 8);
- if (!IsCommonSystemID(&reader))
+ if (!MatchSystemID(&reader, common_system_id))
continue; // Not Common System, so try the next pssh box.
// Since version > 0, next field is the KID_count.
- RCHECK(static_cast<uint32_t>(reader.bits_available()) >=
- sizeof(uint32_t) * 8);
+ RCHECK(BytesAvailable(&reader) >= sizeof(uint32_t));
uint32_t count = ReadBits(&reader, 32);
if (count == 0)
@@ -155,11 +169,11 @@ bool GetKeyIdsForCommonSystemId(const std::vector<uint8_t>& input,
// Make sure there is enough data for all the KIDs specified, and then
// extract them.
- RCHECK(static_cast<uint32_t>(reader.bits_available()) > count * 16 * 8);
+ RCHECK(BytesAvailable(&reader) > count * kKIDSizeInBytes);
while (count > 0) {
std::vector<uint8_t> key;
- key.reserve(16);
- for (int i = 0; i < 16; ++i) {
+ key.reserve(kKIDSizeInBytes);
+ for (uint32_t i = 0; i < kKIDSizeInBytes; ++i) {
key.push_back(ReadBits(&reader, 8));
}
result.push_back(key);
@@ -177,4 +191,58 @@ bool GetKeyIdsForCommonSystemId(const std::vector<uint8_t>& input,
return true;
}
+bool GetPsshData(const std::vector<uint8_t>& input,
+ const std::vector<uint8_t>& system_id,
+ std::vector<uint8_t>* pssh_data) {
+ DCHECK_EQ(system_id.size(), kSystemIDSizeInBytes);
+ size_t offset = 0;
+
+ while (offset < input.size()) {
+ // Create a BitReader over the remaining part of the buffer.
+ BitReader reader(&input[offset], input.size() - offset);
+ uint32_t size;
+ RCHECK(ValidBoxHeader(&reader, &size));
+
+ // Update offset to point at the next 'pssh' box (may not be one).
+ offset += size;
+
+ // Check the version. Only version 0 and 1 'pssh' boxes are supported.
+ // Other versions are skipped.
+ uint8_t version = ReadBits(&reader, 8);
+ if (version > 1)
+ 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. If not, try the next 'pssh' box.
+ if (!MatchSystemID(&reader, system_id))
+ continue;
+
+ // If version > 0, next field is the KID_count. Skip any KIDs in the
+ // 'pssh' box.
+ if (version > 0) {
+ RCHECK(BytesAvailable(&reader) >= sizeof(uint32_t));
+ uint32_t count = ReadBits(&reader, 32);
+ RCHECK(reader.SkipBits(count * kKIDSizeInBytes * 8));
+ }
+
+ // Now get the datasize.
+ RCHECK(BytesAvailable(&reader) >= sizeof(uint32_t));
+ uint32_t datasize = ReadBits(&reader, 32);
+
+ // Now get the data and return it.
+ RCHECK(BytesAvailable(&reader) >= datasize);
+ for (uint32_t i = 0; i < datasize; ++i) {
+ pssh_data->push_back(ReadBits(&reader, 8));
+ }
+ return true;
+ }
+
+ // No matching 'pssh' box found, so fail.
+ return false;
+}
+
} // namespace media
« no previous file with comments | « media/cdm/cenc_utils.h ('k') | media/cdm/cenc_utils_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698