OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "base/logging.h" | 5 #include "base/logging.h" |
6 #include "base/memory/scoped_ptr.h" | 6 #include "base/memory/scoped_ptr.h" |
7 #include "base/stl_util.h" | 7 #include "base/stl_util.h" |
8 | 8 |
9 #include "media/base/decrypt_config.h" | 9 #include "media/base/decrypt_config.h" |
10 #include "media/filters/h264_parser.h" | 10 #include "media/filters/h264_parser.h" |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 STLDeleteValues(&active_SPSes_); | 126 STLDeleteValues(&active_SPSes_); |
127 STLDeleteValues(&active_PPSes_); | 127 STLDeleteValues(&active_PPSes_); |
128 } | 128 } |
129 | 129 |
130 void H264Parser::Reset() { | 130 void H264Parser::Reset() { |
131 stream_ = NULL; | 131 stream_ = NULL; |
132 bytes_left_ = 0; | 132 bytes_left_ = 0; |
133 encrypted_ranges_.clear(); | 133 encrypted_ranges_.clear(); |
134 } | 134 } |
135 | 135 |
136 void H264Parser::SetStream(const uint8* stream, off_t stream_size) { | 136 void H264Parser::SetStream(const uint8_t* stream, off_t stream_size) { |
137 std::vector<SubsampleEntry> subsamples; | 137 std::vector<SubsampleEntry> subsamples; |
138 SetEncryptedStream(stream, stream_size, subsamples); | 138 SetEncryptedStream(stream, stream_size, subsamples); |
139 } | 139 } |
140 | 140 |
141 void H264Parser::SetEncryptedStream( | 141 void H264Parser::SetEncryptedStream( |
142 const uint8* stream, off_t stream_size, | 142 const uint8_t* stream, |
| 143 off_t stream_size, |
143 const std::vector<SubsampleEntry>& subsamples) { | 144 const std::vector<SubsampleEntry>& subsamples) { |
144 DCHECK(stream); | 145 DCHECK(stream); |
145 DCHECK_GT(stream_size, 0); | 146 DCHECK_GT(stream_size, 0); |
146 | 147 |
147 stream_ = stream; | 148 stream_ = stream; |
148 bytes_left_ = stream_size; | 149 bytes_left_ = stream_size; |
149 | 150 |
150 encrypted_ranges_.clear(); | 151 encrypted_ranges_.clear(); |
151 const uint8* start = stream; | 152 const uint8_t* start = stream; |
152 const uint8* stream_end = stream_ + bytes_left_; | 153 const uint8_t* stream_end = stream_ + bytes_left_; |
153 for (size_t i = 0; i < subsamples.size() && start < stream_end; ++i) { | 154 for (size_t i = 0; i < subsamples.size() && start < stream_end; ++i) { |
154 start += subsamples[i].clear_bytes; | 155 start += subsamples[i].clear_bytes; |
155 | 156 |
156 const uint8* end = std::min(start + subsamples[i].cypher_bytes, stream_end); | 157 const uint8_t* end = |
| 158 std::min(start + subsamples[i].cypher_bytes, stream_end); |
157 encrypted_ranges_.Add(start, end); | 159 encrypted_ranges_.Add(start, end); |
158 start = end; | 160 start = end; |
159 } | 161 } |
160 } | 162 } |
161 | 163 |
162 const H264PPS* H264Parser::GetPPS(int pps_id) const { | 164 const H264PPS* H264Parser::GetPPS(int pps_id) const { |
163 auto it = active_PPSes_.find(pps_id); | 165 auto it = active_PPSes_.find(pps_id); |
164 if (it == active_PPSes_.end()) { | 166 if (it == active_PPSes_.end()) { |
165 DVLOG(1) << "Requested a nonexistent PPS id " << pps_id; | 167 DVLOG(1) << "Requested a nonexistent PPS id " << pps_id; |
166 return nullptr; | 168 return nullptr; |
167 } | 169 } |
168 | 170 |
169 return it->second; | 171 return it->second; |
170 } | 172 } |
171 | 173 |
172 const H264SPS* H264Parser::GetSPS(int sps_id) const { | 174 const H264SPS* H264Parser::GetSPS(int sps_id) const { |
173 auto it = active_SPSes_.find(sps_id); | 175 auto it = active_SPSes_.find(sps_id); |
174 if (it == active_SPSes_.end()) { | 176 if (it == active_SPSes_.end()) { |
175 DVLOG(1) << "Requested a nonexistent SPS id " << sps_id; | 177 DVLOG(1) << "Requested a nonexistent SPS id " << sps_id; |
176 return nullptr; | 178 return nullptr; |
177 } | 179 } |
178 | 180 |
179 return it->second; | 181 return it->second; |
180 } | 182 } |
181 | 183 |
182 static inline bool IsStartCode(const uint8* data) { | 184 static inline bool IsStartCode(const uint8_t* data) { |
183 return data[0] == 0x00 && data[1] == 0x00 && data[2] == 0x01; | 185 return data[0] == 0x00 && data[1] == 0x00 && data[2] == 0x01; |
184 } | 186 } |
185 | 187 |
186 // static | 188 // static |
187 bool H264Parser::FindStartCode(const uint8* data, off_t data_size, | 189 bool H264Parser::FindStartCode(const uint8_t* data, |
188 off_t* offset, off_t* start_code_size) { | 190 off_t data_size, |
| 191 off_t* offset, |
| 192 off_t* start_code_size) { |
189 DCHECK_GE(data_size, 0); | 193 DCHECK_GE(data_size, 0); |
190 off_t bytes_left = data_size; | 194 off_t bytes_left = data_size; |
191 | 195 |
192 while (bytes_left >= 3) { | 196 while (bytes_left >= 3) { |
193 if (IsStartCode(data)) { | 197 if (IsStartCode(data)) { |
194 // Found three-byte start code, set pointer at its beginning. | 198 // Found three-byte start code, set pointer at its beginning. |
195 *offset = data_size - bytes_left; | 199 *offset = data_size - bytes_left; |
196 *start_code_size = 3; | 200 *start_code_size = 3; |
197 | 201 |
198 // If there is a zero byte before this start code, | 202 // If there is a zero byte before this start code, |
(...skipping 29 matching lines...) Expand all Loading... |
228 encrypted_ranges_, | 232 encrypted_ranges_, |
229 &nalu_start_off, &annexb_start_code_size)) { | 233 &nalu_start_off, &annexb_start_code_size)) { |
230 DVLOG(4) << "Could not find start code, end of stream?"; | 234 DVLOG(4) << "Could not find start code, end of stream?"; |
231 return false; | 235 return false; |
232 } | 236 } |
233 | 237 |
234 // Move the stream to the beginning of the NALU (pointing at the start code). | 238 // Move the stream to the beginning of the NALU (pointing at the start code). |
235 stream_ += nalu_start_off; | 239 stream_ += nalu_start_off; |
236 bytes_left_ -= nalu_start_off; | 240 bytes_left_ -= nalu_start_off; |
237 | 241 |
238 const uint8* nalu_data = stream_ + annexb_start_code_size; | 242 const uint8_t* nalu_data = stream_ + annexb_start_code_size; |
239 off_t max_nalu_data_size = bytes_left_ - annexb_start_code_size; | 243 off_t max_nalu_data_size = bytes_left_ - annexb_start_code_size; |
240 if (max_nalu_data_size <= 0) { | 244 if (max_nalu_data_size <= 0) { |
241 DVLOG(3) << "End of stream"; | 245 DVLOG(3) << "End of stream"; |
242 return false; | 246 return false; |
243 } | 247 } |
244 | 248 |
245 // Find the start code of next NALU; | 249 // Find the start code of next NALU; |
246 // if successful, |nalu_size_without_start_code| is the number of bytes from | 250 // if successful, |nalu_size_without_start_code| is the number of bytes from |
247 // after previous start code to before this one; | 251 // after previous start code to before this one; |
248 // if next start code is not found, it is still a valid NALU since there | 252 // if next start code is not found, it is still a valid NALU since there |
249 // are some bytes left after the first start code: all the remaining bytes | 253 // are some bytes left after the first start code: all the remaining bytes |
250 // belong to the current NALU. | 254 // belong to the current NALU. |
251 off_t next_start_code_size = 0; | 255 off_t next_start_code_size = 0; |
252 off_t nalu_size_without_start_code = 0; | 256 off_t nalu_size_without_start_code = 0; |
253 if (!FindStartCodeInClearRanges(nalu_data, max_nalu_data_size, | 257 if (!FindStartCodeInClearRanges(nalu_data, max_nalu_data_size, |
254 encrypted_ranges_, | 258 encrypted_ranges_, |
255 &nalu_size_without_start_code, | 259 &nalu_size_without_start_code, |
256 &next_start_code_size)) { | 260 &next_start_code_size)) { |
257 nalu_size_without_start_code = max_nalu_data_size; | 261 nalu_size_without_start_code = max_nalu_data_size; |
258 } | 262 } |
259 *nalu_size = nalu_size_without_start_code + annexb_start_code_size; | 263 *nalu_size = nalu_size_without_start_code + annexb_start_code_size; |
260 *start_code_size = annexb_start_code_size; | 264 *start_code_size = annexb_start_code_size; |
261 return true; | 265 return true; |
262 } | 266 } |
263 | 267 |
264 bool H264Parser::FindStartCodeInClearRanges( | 268 bool H264Parser::FindStartCodeInClearRanges( |
265 const uint8* data, | 269 const uint8_t* data, |
266 off_t data_size, | 270 off_t data_size, |
267 const Ranges<const uint8*>& encrypted_ranges, | 271 const Ranges<const uint8_t*>& encrypted_ranges, |
268 off_t* offset, | 272 off_t* offset, |
269 off_t* start_code_size) { | 273 off_t* start_code_size) { |
270 if (encrypted_ranges.size() == 0) | 274 if (encrypted_ranges.size() == 0) |
271 return FindStartCode(data, data_size, offset, start_code_size); | 275 return FindStartCode(data, data_size, offset, start_code_size); |
272 | 276 |
273 DCHECK_GE(data_size, 0); | 277 DCHECK_GE(data_size, 0); |
274 const uint8* start = data; | 278 const uint8_t* start = data; |
275 do { | 279 do { |
276 off_t bytes_left = data_size - (start - data); | 280 off_t bytes_left = data_size - (start - data); |
277 | 281 |
278 if (!FindStartCode(start, bytes_left, offset, start_code_size)) | 282 if (!FindStartCode(start, bytes_left, offset, start_code_size)) |
279 return false; | 283 return false; |
280 | 284 |
281 // Construct a Ranges object that represents the region occupied | 285 // Construct a Ranges object that represents the region occupied |
282 // by the start code and the 1 byte needed to read the NAL unit type. | 286 // by the start code and the 1 byte needed to read the NAL unit type. |
283 const uint8* start_code = start + *offset; | 287 const uint8_t* start_code = start + *offset; |
284 const uint8* start_code_end = start_code + *start_code_size; | 288 const uint8_t* start_code_end = start_code + *start_code_size; |
285 Ranges<const uint8*> start_code_range; | 289 Ranges<const uint8_t*> start_code_range; |
286 start_code_range.Add(start_code, start_code_end + 1); | 290 start_code_range.Add(start_code, start_code_end + 1); |
287 | 291 |
288 if (encrypted_ranges.IntersectionWith(start_code_range).size() > 0) { | 292 if (encrypted_ranges.IntersectionWith(start_code_range).size() > 0) { |
289 // The start code is inside an encrypted section so we need to scan | 293 // The start code is inside an encrypted section so we need to scan |
290 // for another start code. | 294 // for another start code. |
291 *start_code_size = 0; | 295 *start_code_size = 0; |
292 start += std::min(*offset + 1, bytes_left); | 296 start += std::min(*offset + 1, bytes_left); |
293 } | 297 } |
294 } while (*start_code_size == 0); | 298 } while (*start_code_size == 0); |
295 | 299 |
(...skipping 1037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1333 | 1337 |
1334 default: | 1338 default: |
1335 DVLOG(4) << "Unsupported SEI message"; | 1339 DVLOG(4) << "Unsupported SEI message"; |
1336 break; | 1340 break; |
1337 } | 1341 } |
1338 | 1342 |
1339 return kOk; | 1343 return kOk; |
1340 } | 1344 } |
1341 | 1345 |
1342 } // namespace media | 1346 } // namespace media |
OLD | NEW |