| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/cdm/cenc_utils.h" | 5 #include "media/cdm/cenc_utils.h" |
| 6 | 6 |
| 7 #include "base/stl_util.h" | 7 #include "base/stl_util.h" |
| 8 #include "media/formats/mp4/box_definitions.h" | 8 #include "media/formats/mp4/box_definitions.h" |
| 9 #include "media/formats/mp4/box_reader.h" | 9 #include "media/formats/mp4/box_reader.h" |
| 10 | 10 |
| 11 namespace media { | 11 namespace media { |
| 12 | 12 |
| 13 // The initialization data for encrypted media files using the ISO Common | 13 // The initialization data for encrypted media files using the ISO Common |
| 14 // Encryption ('cenc') protection scheme may contain one or more protection | 14 // Encryption ('cenc') protection scheme may contain one or more protection |
| 15 // system specific header ('pssh') boxes. | 15 // system specific header ('pssh') boxes. |
| 16 // ref: https://w3c.github.io/encrypted-media/cenc-format.html | 16 // ref: https://w3c.github.io/encrypted-media/cenc-format.html |
| 17 | 17 |
| 18 // SystemID for the Common System. | |
| 19 // https://w3c.github.io/encrypted-media/cenc-format.html#common-system | |
| 20 const uint8_t kCommonSystemId[] = { 0x10, 0x77, 0xef, 0xec, | |
| 21 0xc0, 0xb2, 0x4d, 0x02, | |
| 22 0xac, 0xe3, 0x3c, 0x1e, | |
| 23 0x52, 0xe2, 0xfb, 0x4b }; | |
| 24 | |
| 25 static bool ReadAllPsshBoxes( | 18 static bool ReadAllPsshBoxes( |
| 26 const std::vector<uint8_t>& input, | 19 const std::vector<uint8_t>& input, |
| 27 std::vector<mp4::FullProtectionSystemSpecificHeader>* pssh_boxes) { | 20 std::vector<mp4::FullProtectionSystemSpecificHeader>* pssh_boxes) { |
| 28 DCHECK(!input.empty()); | 21 DCHECK(!input.empty()); |
| 29 | 22 |
| 30 // Verify that |input| contains only 'pssh' boxes. ReadAllChildren() is | 23 // Verify that |input| contains only 'pssh' boxes. ReadAllChildren() is |
| 31 // templated, so it checks that each box in |input| matches the box type of | 24 // templated, so it checks that each box in |input| matches the box type of |
| 32 // the parameter (in this case mp4::ProtectionSystemSpecificHeader is a | 25 // the parameter (in this case mp4::ProtectionSystemSpecificHeader is a |
| 33 // 'pssh' box). mp4::ProtectionSystemSpecificHeader doesn't validate the | 26 // 'pssh' box). mp4::ProtectionSystemSpecificHeader doesn't validate the |
| 34 // 'pssh' contents, so this simply verifies that |input| only contains | 27 // 'pssh' contents, so this simply verifies that |input| only contains |
| (...skipping 28 matching lines...) Expand all Loading... |
| 63 | 56 |
| 64 bool ValidatePsshInput(const std::vector<uint8_t>& input) { | 57 bool ValidatePsshInput(const std::vector<uint8_t>& input) { |
| 65 // No 'pssh' boxes is considered valid. | 58 // No 'pssh' boxes is considered valid. |
| 66 if (input.empty()) | 59 if (input.empty()) |
| 67 return true; | 60 return true; |
| 68 | 61 |
| 69 std::vector<mp4::FullProtectionSystemSpecificHeader> children; | 62 std::vector<mp4::FullProtectionSystemSpecificHeader> children; |
| 70 return ReadAllPsshBoxes(input, &children); | 63 return ReadAllPsshBoxes(input, &children); |
| 71 } | 64 } |
| 72 | 65 |
| 73 bool GetKeyIdsForCommonSystemId(const std::vector<uint8_t>& input, | 66 bool GetKeyIds(const std::vector<uint8_t>& input, |
| 74 KeyIdList* key_ids) { | 67 const std::vector<uint8_t>& system_id, |
| 68 KeyIdList* key_ids) { |
| 69 // If there are no 'pssh' boxes then no key IDs found. |
| 70 if (input.empty()) |
| 71 return false; |
| 72 |
| 73 std::vector<mp4::FullProtectionSystemSpecificHeader> children; |
| 74 if (!ReadAllPsshBoxes(input, &children)) |
| 75 return false; |
| 76 |
| 77 // Check all children for an appropriate 'pssh' box, returning the |
| 78 // key IDs found. |
| 75 KeyIdList result; | 79 KeyIdList result; |
| 76 std::vector<uint8_t> common_system_id( | 80 for (const auto& child : children) { |
| 77 kCommonSystemId, kCommonSystemId + arraysize(kCommonSystemId)); | 81 if (child.system_id == system_id) { |
| 78 | 82 key_ids->assign(child.key_ids.begin(), child.key_ids.end()); |
| 79 if (!input.empty()) { | 83 return key_ids->size() > 0; |
| 80 std::vector<mp4::FullProtectionSystemSpecificHeader> children; | |
| 81 if (!ReadAllPsshBoxes(input, &children)) | |
| 82 return false; | |
| 83 | |
| 84 // Check all children for an appropriate 'pssh' box, concatenating any | |
| 85 // key IDs found. | |
| 86 for (const auto& child : children) { | |
| 87 if (child.system_id == common_system_id && child.key_ids.size() > 0) | |
| 88 result.insert(result.end(), child.key_ids.begin(), child.key_ids.end()); | |
| 89 } | 84 } |
| 90 } | 85 } |
| 91 | 86 |
| 92 key_ids->swap(result); | 87 // No matching 'pssh' box found. |
| 93 return key_ids->size() > 0; | 88 return false; |
| 94 } | 89 } |
| 95 | 90 |
| 96 bool GetPsshData(const std::vector<uint8_t>& input, | 91 bool GetPsshData(const std::vector<uint8_t>& input, |
| 97 const std::vector<uint8_t>& system_id, | 92 const std::vector<uint8_t>& system_id, |
| 98 std::vector<uint8_t>* pssh_data) { | 93 std::vector<uint8_t>* pssh_data) { |
| 99 if (input.empty()) | 94 if (input.empty()) |
| 100 return false; | 95 return false; |
| 101 | 96 |
| 102 std::vector<mp4::FullProtectionSystemSpecificHeader> children; | 97 std::vector<mp4::FullProtectionSystemSpecificHeader> children; |
| 103 if (!ReadAllPsshBoxes(input, &children)) | 98 if (!ReadAllPsshBoxes(input, &children)) |
| 104 return false; | 99 return false; |
| 105 | 100 |
| 106 // Check all children for an appropriate 'pssh' box, returning |data| from | 101 // Check all children for an appropriate 'pssh' box, returning |data| from |
| 107 // the first one found. | 102 // the first one found. |
| 108 for (const auto& child : children) { | 103 for (const auto& child : children) { |
| 109 if (child.system_id == system_id) { | 104 if (child.system_id == system_id) { |
| 110 pssh_data->assign(child.data.begin(), child.data.end()); | 105 pssh_data->assign(child.data.begin(), child.data.end()); |
| 111 return true; | 106 return true; |
| 112 } | 107 } |
| 113 } | 108 } |
| 114 | 109 |
| 115 // No matching 'pssh' box found. | 110 // No matching 'pssh' box found. |
| 116 return false; | 111 return false; |
| 117 } | 112 } |
| 118 | 113 |
| 119 } // namespace media | 114 } // namespace media |
| OLD | NEW |