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 "components/cdm/browser/widevine_drm_delegate_android.h" | 5 #include "components/cdm/browser/widevine_drm_delegate_android.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/numerics/safe_conversions.h" | 8 #include "base/numerics/safe_conversions.h" |
9 | 9 |
10 namespace cdm { | 10 namespace cdm { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 // uint8[DataSize] Data | 44 // uint8[DataSize] Data |
45 // } | 45 // } |
46 const int kBoxHeaderSize = 8; // Box's header contains Size and Type. | 46 const int kBoxHeaderSize = 8; // Box's header contains Size and Type. |
47 const int kBoxLargeSizeSize = 8; | 47 const int kBoxLargeSizeSize = 8; |
48 const int kPsshVersionFlagSize = 4; | 48 const int kPsshVersionFlagSize = 4; |
49 const uint32_t k24BitMask = 0x00ffffff; | 49 const uint32_t k24BitMask = 0x00ffffff; |
50 const int kPsshSystemIdSize = 16; | 50 const int kPsshSystemIdSize = 16; |
51 const int kPsshKidCountSize = 4; | 51 const int kPsshKidCountSize = 4; |
52 const int kPsshKidSize = 16; | 52 const int kPsshKidSize = 16; |
53 const int kPsshDataSizeSize = 4; | 53 const int kPsshDataSizeSize = 4; |
54 const uint32_t kTencType = 0x74656e63; | |
55 const uint32_t kPsshType = 0x70737368; | 54 const uint32_t kPsshType = 0x70737368; |
56 | 55 |
57 const uint8_t kWidevineUuid[16] = { | 56 const uint8_t kWidevineUuid[16] = { |
58 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE, | 57 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE, |
59 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED }; | 58 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED }; |
60 | 59 |
61 // Tries to find a PSSH box with the Widevine UUID, parses the | 60 // Tries to find a PSSH box with the Widevine UUID, parses the |
62 // "Data" of the box and put it in |pssh_data|. Returns true if such a box is | 61 // "Data" of the box and put it in |pssh_data|. Returns true if such a box is |
63 // found and successfully parsed. Returns false otherwise. | 62 // found and successfully parsed. Returns false otherwise. |
64 // Notes: | 63 // Notes: |
65 // 1, If multiple PSSH boxes are found,the "Data" of the first matching PSSH box | 64 // 1, If multiple PSSH boxes are found,the "Data" of the first matching PSSH box |
66 // will be set in |pssh_data|. | 65 // will be set in |pssh_data|. |
67 // 2, Only PSSH and TENC boxes are allowed in |data|. TENC boxes are skipped. | 66 // 2, Only PSSH boxes are allowed in |data|. |
68 bool GetPsshData(const std::vector<uint8_t>& data, | 67 bool GetPsshData(const std::vector<uint8_t>& data, |
69 std::vector<uint8_t>* pssh_data) { | 68 std::vector<uint8_t>* pssh_data) { |
70 int bytes_left = base::checked_cast<int>(data.size()); | 69 int bytes_left = base::checked_cast<int>(data.size()); |
71 const uint8_t* cur = &data[0]; | 70 const uint8_t* cur = &data[0]; |
72 const uint8_t* data_end = cur + bytes_left; | 71 const uint8_t* data_end = cur + bytes_left; |
73 | 72 |
74 while (bytes_left > 0) { | 73 while (bytes_left > 0) { |
75 const uint8_t* box_head = cur; | 74 const uint8_t* box_head = cur; |
76 | 75 |
77 if (bytes_left < kBoxHeaderSize) | 76 if (bytes_left < kBoxHeaderSize) |
(...skipping 12 matching lines...) Expand all Loading... |
90 cur += kBoxLargeSizeSize; | 89 cur += kBoxLargeSizeSize; |
91 bytes_left -= kBoxLargeSizeSize; | 90 bytes_left -= kBoxLargeSizeSize; |
92 } else if (box_size == 0) { | 91 } else if (box_size == 0) { |
93 box_size = bytes_left + kBoxHeaderSize; | 92 box_size = bytes_left + kBoxHeaderSize; |
94 } | 93 } |
95 | 94 |
96 const uint8_t* box_end = box_head + box_size; | 95 const uint8_t* box_end = box_head + box_size; |
97 if (data_end < box_end) | 96 if (data_end < box_end) |
98 return false; | 97 return false; |
99 | 98 |
100 if (type == kTencType) { | 99 if (type != kPsshType) |
101 // Skip 'tenc' box. | |
102 cur = box_end; | |
103 bytes_left = data_end - cur; | |
104 continue; | |
105 } else if (type != kPsshType) { | |
106 return false; | 100 return false; |
107 } | |
108 | 101 |
109 const int kPsshBoxMinimumSize = | 102 const int kPsshBoxMinimumSize = |
110 kPsshVersionFlagSize + kPsshSystemIdSize + kPsshDataSizeSize; | 103 kPsshVersionFlagSize + kPsshSystemIdSize + kPsshDataSizeSize; |
111 if (box_end < cur + kPsshBoxMinimumSize) | 104 if (box_end < cur + kPsshBoxMinimumSize) |
112 return false; | 105 return false; |
113 | 106 |
114 uint8_t version = cur[0]; | 107 uint8_t version = cur[0]; |
115 uint32_t flags = ReadUint32(cur) & k24BitMask; | 108 uint32_t flags = ReadUint32(cur) & k24BitMask; |
116 cur += kPsshVersionFlagSize; | 109 cur += kPsshVersionFlagSize; |
117 bytes_left -= kPsshVersionFlagSize; | 110 bytes_left -= kPsshVersionFlagSize; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 std::vector<std::string>* /* optional_parameters_out */) { | 168 std::vector<std::string>* /* optional_parameters_out */) { |
176 if (init_data_type != media::EmeInitDataType::CENC) | 169 if (init_data_type != media::EmeInitDataType::CENC) |
177 return true; | 170 return true; |
178 | 171 |
179 // Widevine MediaDrm plugin only accepts the "data" part of the PSSH box as | 172 // Widevine MediaDrm plugin only accepts the "data" part of the PSSH box as |
180 // the init data when using MP4 container. | 173 // the init data when using MP4 container. |
181 return GetPsshData(init_data, init_data_out); | 174 return GetPsshData(init_data, init_data_out); |
182 } | 175 } |
183 | 176 |
184 } // namespace cdm | 177 } // namespace cdm |
OLD | NEW |