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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 |
OLD | NEW |