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( |
ddorwin
2015/06/25 21:18:12
Document this function. For example, returns true
jrummell
2015/06/25 22:35:58
Done.
| |
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 |
35 // 'pssh' boxes and nothing else. | 28 // 'pssh' boxes and nothing else. |
(...skipping 27 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, |
ddorwin
2015/06/25 21:18:12
It's fine to have this generic implementation inte
jrummell
2015/06/25 22:35:58
Added in case some future implementation wants to
ddorwin
2015/06/25 22:49:23
I think this adds the risk of YAGNI and misuse, bo
jrummell
2015/06/30 00:49:12
Done.
| |
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 |