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 "media/formats/webm/webm_stream_parser.h" | 5 #include "media/formats/webm/webm_stream_parser.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/callback.h" | 9 #include "base/callback.h" |
10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
235 if (!init_cb_.is_null()) | 235 if (!init_cb_.is_null()) |
236 base::ResetAndReturn(&init_cb_).Run(true, params); | 236 base::ResetAndReturn(&init_cb_).Run(true, params); |
237 | 237 |
238 return bytes_parsed; | 238 return bytes_parsed; |
239 } | 239 } |
240 | 240 |
241 int WebMStreamParser::ParseCluster(const uint8* data, int size) { | 241 int WebMStreamParser::ParseCluster(const uint8* data, int size) { |
242 if (!cluster_parser_) | 242 if (!cluster_parser_) |
243 return -1; | 243 return -1; |
244 | 244 |
245 int id; | 245 int result = 0; |
246 int64 element_size; | 246 int bytes_parsed; |
247 int result = WebMParseElementHeader(data, size, &id, &element_size); | 247 bool cluster_ended; |
248 do { | |
249 cluster_ended = false; | |
248 | 250 |
249 if (result <= 0) | 251 // If we are not parsing a cluster then handle the case when the next |
250 return result; | 252 // element is not a cluster. |
253 if (!parsing_cluster_) { | |
254 int id; | |
255 int64 element_size; | |
256 bytes_parsed = WebMParseElementHeader(data, size, &id, &element_size); | |
251 | 257 |
252 // TODO(matthewjheaney): implement support for chapters | 258 if (bytes_parsed < 0) |
253 if (id == kWebMIdCues || id == kWebMIdChapters) { | 259 return bytes_parsed; |
254 // TODO(wolenetz): Handle unknown-sized cluster parse completion correctly. | 260 |
255 // See http://crbug.com/335676. | 261 if (bytes_parsed == 0) |
256 if (size < (result + element_size)) { | 262 return result; |
257 // We don't have the whole element yet. Signal we need more data. | 263 |
258 return 0; | 264 switch (id) { |
265 // Cues and Chapters are skipped. | |
266 // TODO(matthewjheaney): Implement support for chapters. | |
267 case kWebMIdCues: | |
268 case kWebMIdChapters: | |
269 if (size < (bytes_parsed + element_size)) { | |
270 // We don't have the whole element yet. Signal we need more data. | |
271 return result; | |
272 } | |
273 | |
274 // Skip the element. | |
275 bytes_parsed += element_size; | |
276 result += bytes_parsed; | |
277 data += bytes_parsed; | |
278 size -= bytes_parsed; | |
279 continue; | |
280 | |
281 case kWebMIdEBMLHeader: | |
282 ChangeState(kParsingHeaders); | |
283 return result; | |
284 } | |
wolenetz
2014/06/16 18:39:35
Switch should have default case if not on enum. Al
Sergey Ulanov
2014/06/16 22:17:41
Done.
| |
259 } | 285 } |
260 // Skip the element. | |
261 return result + element_size; | |
262 } | |
263 | 286 |
264 if (id == kWebMIdEBMLHeader) { | 287 bytes_parsed = cluster_parser_->Parse(data, size); |
265 // TODO(wolenetz): Handle unknown-sized cluster parse completion correctly. | |
266 // See http://crbug.com/335676. | |
267 ChangeState(kParsingHeaders); | |
268 return 0; | |
269 } | |
270 | 288 |
271 int bytes_parsed = cluster_parser_->Parse(data, size); | 289 if (bytes_parsed < 0) |
290 return bytes_parsed; | |
272 | 291 |
273 if (bytes_parsed <= 0) | 292 // If cluster detected, immediately notify new segment if we have not |
274 return bytes_parsed; | 293 // already done this. |
294 if (!parsing_cluster_ && bytes_parsed > 0) { | |
295 parsing_cluster_ = true; | |
296 new_segment_cb_.Run(); | |
297 } | |
275 | 298 |
276 // If cluster detected, immediately notify new segment if we have not already | 299 const BufferQueue& audio_buffers = cluster_parser_->GetAudioBuffers(); |
277 // done this. | 300 const BufferQueue& video_buffers = cluster_parser_->GetVideoBuffers(); |
278 if (id == kWebMIdCluster && !parsing_cluster_) { | 301 const TextBufferQueueMap& text_map = cluster_parser_->GetTextBuffers(); |
279 parsing_cluster_ = true; | |
280 new_segment_cb_.Run(); | |
281 } | |
282 | 302 |
283 const BufferQueue& audio_buffers = cluster_parser_->GetAudioBuffers(); | 303 cluster_ended = cluster_parser_->cluster_ended(); |
284 const BufferQueue& video_buffers = cluster_parser_->GetVideoBuffers(); | |
285 const TextBufferQueueMap& text_map = cluster_parser_->GetTextBuffers(); | |
286 | 304 |
287 bool cluster_ended = cluster_parser_->cluster_ended(); | 305 if ((!audio_buffers.empty() || !video_buffers.empty() || |
306 !text_map.empty()) && | |
307 !new_buffers_cb_.Run(audio_buffers, video_buffers, text_map)) { | |
308 return -1; | |
309 } | |
288 | 310 |
289 if ((!audio_buffers.empty() || !video_buffers.empty() || !text_map.empty()) && | 311 if (cluster_ended) { |
290 !new_buffers_cb_.Run(audio_buffers, video_buffers, text_map)) { | 312 parsing_cluster_ = false; |
291 return -1; | 313 end_of_segment_cb_.Run(); |
292 } | 314 } |
293 | 315 |
294 if (cluster_ended) { | 316 result += bytes_parsed; |
295 parsing_cluster_ = false; | 317 data += bytes_parsed; |
296 end_of_segment_cb_.Run(); | 318 size -= bytes_parsed; |
297 } | |
298 | 319 |
299 return bytes_parsed; | 320 // WebMClusterParser returns 0 if |data| starts with a beginning of a new |
321 // cluster. Try parsing again in that case. | |
wolenetz
2014/06/16 18:39:35
nit: s/"returns 0"..."cluster."/"returns 0 and |cl
Sergey Ulanov
2014/06/16 22:17:41
Done.
| |
322 } while (size > 0 && (bytes_parsed > 0 || cluster_ended)); | |
323 | |
324 return result; | |
300 } | 325 } |
301 | 326 |
302 void WebMStreamParser::FireNeedKey(const std::string& key_id) { | 327 void WebMStreamParser::FireNeedKey(const std::string& key_id) { |
303 std::vector<uint8> key_id_vector(key_id.begin(), key_id.end()); | 328 std::vector<uint8> key_id_vector(key_id.begin(), key_id.end()); |
304 need_key_cb_.Run(kWebMEncryptInitDataType, key_id_vector); | 329 need_key_cb_.Run(kWebMEncryptInitDataType, key_id_vector); |
305 } | 330 } |
306 | 331 |
307 } // namespace media | 332 } // namespace media |
OLD | NEW |