Index: media/formats/webm/webm_stream_parser.cc |
diff --git a/media/formats/webm/webm_stream_parser.cc b/media/formats/webm/webm_stream_parser.cc |
index a90a623a2bdf9aa729206e66cc53574d6453b95e..06ee499360549fd33ac4f6bb36beae248b155106 100644 |
--- a/media/formats/webm/webm_stream_parser.cc |
+++ b/media/formats/webm/webm_stream_parser.cc |
@@ -242,61 +242,86 @@ int WebMStreamParser::ParseCluster(const uint8* data, int size) { |
if (!cluster_parser_) |
return -1; |
- int id; |
- int64 element_size; |
- int result = WebMParseElementHeader(data, size, &id, &element_size); |
- |
- if (result <= 0) |
- return result; |
- |
- // TODO(matthewjheaney): implement support for chapters |
- if (id == kWebMIdCues || id == kWebMIdChapters) { |
- // TODO(wolenetz): Handle unknown-sized cluster parse completion correctly. |
- // See http://crbug.com/335676. |
- if (size < (result + element_size)) { |
- // We don't have the whole element yet. Signal we need more data. |
- return 0; |
+ int result = 0; |
+ int bytes_parsed; |
+ bool cluster_ended; |
+ do { |
+ cluster_ended = false; |
+ |
+ // If we are not parsing a cluster then handle the case when the next |
+ // element is not a cluster. |
+ if (!parsing_cluster_) { |
+ int id; |
+ int64 element_size; |
+ bytes_parsed = WebMParseElementHeader(data, size, &id, &element_size); |
+ |
+ if (bytes_parsed < 0) |
+ return bytes_parsed; |
+ |
+ if (bytes_parsed == 0) |
+ return result; |
+ |
+ switch (id) { |
+ // Cues and Chapters are skipped. |
+ // TODO(matthewjheaney): Implement support for chapters. |
+ case kWebMIdCues: |
+ case kWebMIdChapters: |
+ if (size < (bytes_parsed + element_size)) { |
+ // We don't have the whole element yet. Signal we need more data. |
+ return result; |
+ } |
+ |
+ // Skip the element. |
+ bytes_parsed += element_size; |
+ result += bytes_parsed; |
+ data += bytes_parsed; |
+ size -= bytes_parsed; |
+ continue; |
+ |
+ case kWebMIdEBMLHeader: |
+ ChangeState(kParsingHeaders); |
+ return result; |
+ } |
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.
|
} |
- // Skip the element. |
- return result + element_size; |
- } |
- if (id == kWebMIdEBMLHeader) { |
- // TODO(wolenetz): Handle unknown-sized cluster parse completion correctly. |
- // See http://crbug.com/335676. |
- ChangeState(kParsingHeaders); |
- return 0; |
- } |
+ bytes_parsed = cluster_parser_->Parse(data, size); |
- int bytes_parsed = cluster_parser_->Parse(data, size); |
+ if (bytes_parsed < 0) |
+ return bytes_parsed; |
- if (bytes_parsed <= 0) |
- return bytes_parsed; |
+ // If cluster detected, immediately notify new segment if we have not |
+ // already done this. |
+ if (!parsing_cluster_ && bytes_parsed > 0) { |
+ parsing_cluster_ = true; |
+ new_segment_cb_.Run(); |
+ } |
- // If cluster detected, immediately notify new segment if we have not already |
- // done this. |
- if (id == kWebMIdCluster && !parsing_cluster_) { |
- parsing_cluster_ = true; |
- new_segment_cb_.Run(); |
- } |
+ const BufferQueue& audio_buffers = cluster_parser_->GetAudioBuffers(); |
+ const BufferQueue& video_buffers = cluster_parser_->GetVideoBuffers(); |
+ const TextBufferQueueMap& text_map = cluster_parser_->GetTextBuffers(); |
- const BufferQueue& audio_buffers = cluster_parser_->GetAudioBuffers(); |
- const BufferQueue& video_buffers = cluster_parser_->GetVideoBuffers(); |
- const TextBufferQueueMap& text_map = cluster_parser_->GetTextBuffers(); |
+ cluster_ended = cluster_parser_->cluster_ended(); |
- bool cluster_ended = cluster_parser_->cluster_ended(); |
+ if ((!audio_buffers.empty() || !video_buffers.empty() || |
+ !text_map.empty()) && |
+ !new_buffers_cb_.Run(audio_buffers, video_buffers, text_map)) { |
+ return -1; |
+ } |
- if ((!audio_buffers.empty() || !video_buffers.empty() || !text_map.empty()) && |
- !new_buffers_cb_.Run(audio_buffers, video_buffers, text_map)) { |
- return -1; |
- } |
+ if (cluster_ended) { |
+ parsing_cluster_ = false; |
+ end_of_segment_cb_.Run(); |
+ } |
- if (cluster_ended) { |
- parsing_cluster_ = false; |
- end_of_segment_cb_.Run(); |
- } |
+ result += bytes_parsed; |
+ data += bytes_parsed; |
+ size -= bytes_parsed; |
- return bytes_parsed; |
+ // WebMClusterParser returns 0 if |data| starts with a beginning of a new |
+ // 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.
|
+ } while (size > 0 && (bytes_parsed > 0 || cluster_ended)); |
+ |
+ return result; |
} |
void WebMStreamParser::FireNeedKey(const std::string& key_id) { |