Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(172)

Side by Side Diff: media/formats/webm/webm_stream_parser.cc

Issue 328653002: Fix WebMStreamParser to continue parsing after a cluster end (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/formats/webm/cluster_builder.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 if (result <= 0) 136 if (result <= 0)
137 return result; 137 return result;
138 138
139 switch (id) { 139 switch (id) {
140 case kWebMIdEBMLHeader: 140 case kWebMIdEBMLHeader:
141 case kWebMIdSeekHead: 141 case kWebMIdSeekHead:
142 case kWebMIdVoid: 142 case kWebMIdVoid:
143 case kWebMIdCRC32: 143 case kWebMIdCRC32:
144 case kWebMIdCues: 144 case kWebMIdCues:
145 case kWebMIdChapters: 145 case kWebMIdChapters:
146 // TODO(matthewjheaney): Implement support for chapters.
146 if (cur_size < (result + element_size)) { 147 if (cur_size < (result + element_size)) {
147 // We don't have the whole element yet. Signal we need more data. 148 // We don't have the whole element yet. Signal we need more data.
148 return 0; 149 return 0;
149 } 150 }
150 // Skip the element. 151 // Skip the element.
151 return result + element_size; 152 return result + element_size;
152 break; 153 break;
153 case kWebMIdSegment: 154 case kWebMIdSegment:
154 // Segment of unknown size indicates live stream. 155 // Segment of unknown size indicates live stream.
155 if (element_size == kWebMUnknownSize) 156 if (element_size == kWebMUnknownSize)
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 if (!init_cb_.is_null()) 236 if (!init_cb_.is_null())
236 base::ResetAndReturn(&init_cb_).Run(true, params); 237 base::ResetAndReturn(&init_cb_).Run(true, params);
237 238
238 return bytes_parsed; 239 return bytes_parsed;
239 } 240 }
240 241
241 int WebMStreamParser::ParseCluster(const uint8* data, int size) { 242 int WebMStreamParser::ParseCluster(const uint8* data, int size) {
242 if (!cluster_parser_) 243 if (!cluster_parser_)
243 return -1; 244 return -1;
244 245
245 int id; 246 int result = 0;
246 int64 element_size; 247 int bytes_parsed;
247 int result = WebMParseElementHeader(data, size, &id, &element_size); 248 bool cluster_ended;
249 do {
250 cluster_ended = false;
248 251
249 if (result <= 0) 252 // If we are not parsing a cluster then handle the case when the next
250 return result; 253 // element is not a cluster.
254 if (!parsing_cluster_) {
255 int id;
256 int64 element_size;
257 bytes_parsed = WebMParseElementHeader(data, size, &id, &element_size);
251 258
252 // TODO(matthewjheaney): implement support for chapters 259 if (bytes_parsed < 0)
253 if (id == kWebMIdCues || id == kWebMIdChapters) { 260 return bytes_parsed;
254 // TODO(wolenetz): Handle unknown-sized cluster parse completion correctly. 261
255 // See http://crbug.com/335676. 262 if (bytes_parsed == 0)
256 if (size < (result + element_size)) { 263 return result;
257 // We don't have the whole element yet. Signal we need more data. 264
258 return 0; 265 if (id != kWebMIdCluster) {
266 ChangeState(kParsingHeaders);
267 return result;
268 }
259 } 269 }
260 // Skip the element.
261 return result + element_size;
262 }
263 270
264 if (id == kWebMIdEBMLHeader) { 271 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 272
271 int bytes_parsed = cluster_parser_->Parse(data, size); 273 if (bytes_parsed < 0)
274 return bytes_parsed;
272 275
273 if (bytes_parsed <= 0) 276 // If cluster detected, immediately notify new segment if we have not
274 return bytes_parsed; 277 // already done this.
278 if (!parsing_cluster_ && bytes_parsed > 0) {
279 parsing_cluster_ = true;
280 new_segment_cb_.Run();
281 }
275 282
276 // If cluster detected, immediately notify new segment if we have not already 283 const BufferQueue& audio_buffers = cluster_parser_->GetAudioBuffers();
277 // done this. 284 const BufferQueue& video_buffers = cluster_parser_->GetVideoBuffers();
278 if (id == kWebMIdCluster && !parsing_cluster_) { 285 const TextBufferQueueMap& text_map = cluster_parser_->GetTextBuffers();
279 parsing_cluster_ = true;
280 new_segment_cb_.Run();
281 }
282 286
283 const BufferQueue& audio_buffers = cluster_parser_->GetAudioBuffers(); 287 cluster_ended = cluster_parser_->cluster_ended();
284 const BufferQueue& video_buffers = cluster_parser_->GetVideoBuffers();
285 const TextBufferQueueMap& text_map = cluster_parser_->GetTextBuffers();
286 288
287 bool cluster_ended = cluster_parser_->cluster_ended(); 289 if ((!audio_buffers.empty() || !video_buffers.empty() ||
290 !text_map.empty()) &&
291 !new_buffers_cb_.Run(audio_buffers, video_buffers, text_map)) {
292 return -1;
293 }
288 294
289 if ((!audio_buffers.empty() || !video_buffers.empty() || !text_map.empty()) && 295 if (cluster_ended) {
290 !new_buffers_cb_.Run(audio_buffers, video_buffers, text_map)) { 296 parsing_cluster_ = false;
291 return -1; 297 end_of_segment_cb_.Run();
292 } 298 }
293 299
294 if (cluster_ended) { 300 result += bytes_parsed;
295 parsing_cluster_ = false; 301 data += bytes_parsed;
296 end_of_segment_cb_.Run(); 302 size -= bytes_parsed;
297 }
298 303
299 return bytes_parsed; 304 // WebMClusterParser returns 0 and |cluster_ended| is true if previously
305 // parsing an unknown-size cluster and |data| does not continue that
306 // cluster. Try parsing again in that case.
307 } while (size > 0 && (bytes_parsed > 0 || cluster_ended));
308
309 return result;
300 } 310 }
301 311
302 void WebMStreamParser::FireNeedKey(const std::string& key_id) { 312 void WebMStreamParser::FireNeedKey(const std::string& key_id) {
303 std::vector<uint8> key_id_vector(key_id.begin(), key_id.end()); 313 std::vector<uint8> key_id_vector(key_id.begin(), key_id.end());
304 need_key_cb_.Run(kWebMEncryptInitDataType, key_id_vector); 314 need_key_cb_.Run(kWebMEncryptInitDataType, key_id_vector);
305 } 315 }
306 316
307 } // namespace media 317 } // namespace media
OLDNEW
« no previous file with comments | « media/formats/webm/cluster_builder.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698