OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/mp4/mp4_stream_parser.h" | 5 #include "media/mp4/mp4_stream_parser.h" |
6 | 6 |
7 #include "base/callback.h" | 7 #include "base/callback.h" |
8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/time.h" | 10 #include "base/time.h" |
(...skipping 19 matching lines...) Expand all Loading... |
30 has_sbr_(has_sbr) { | 30 has_sbr_(has_sbr) { |
31 } | 31 } |
32 | 32 |
33 MP4StreamParser::~MP4StreamParser() {} | 33 MP4StreamParser::~MP4StreamParser() {} |
34 | 34 |
35 void MP4StreamParser::Init(const InitCB& init_cb, | 35 void MP4StreamParser::Init(const InitCB& init_cb, |
36 const NewConfigCB& config_cb, | 36 const NewConfigCB& config_cb, |
37 const NewBuffersCB& audio_cb, | 37 const NewBuffersCB& audio_cb, |
38 const NewBuffersCB& video_cb, | 38 const NewBuffersCB& video_cb, |
39 const NeedKeyCB& need_key_cb, | 39 const NeedKeyCB& need_key_cb, |
40 const NewMediaSegmentCB& new_segment_cb) { | 40 const NewMediaSegmentCB& new_segment_cb, |
| 41 const base::Closure& end_of_segment_cb) { |
41 DCHECK_EQ(state_, kWaitingForInit); | 42 DCHECK_EQ(state_, kWaitingForInit); |
42 DCHECK(init_cb_.is_null()); | 43 DCHECK(init_cb_.is_null()); |
43 DCHECK(!init_cb.is_null()); | 44 DCHECK(!init_cb.is_null()); |
44 DCHECK(!config_cb.is_null()); | 45 DCHECK(!config_cb.is_null()); |
45 DCHECK(!audio_cb.is_null() || !video_cb.is_null()); | 46 DCHECK(!audio_cb.is_null() || !video_cb.is_null()); |
46 DCHECK(!need_key_cb.is_null()); | 47 DCHECK(!need_key_cb.is_null()); |
| 48 DCHECK(!end_of_segment_cb.is_null()); |
47 | 49 |
48 ChangeState(kParsingBoxes); | 50 ChangeState(kParsingBoxes); |
49 init_cb_ = init_cb; | 51 init_cb_ = init_cb; |
50 config_cb_ = config_cb; | 52 config_cb_ = config_cb; |
51 audio_cb_ = audio_cb; | 53 audio_cb_ = audio_cb; |
52 video_cb_ = video_cb; | 54 video_cb_ = video_cb; |
53 need_key_cb_ = need_key_cb; | 55 need_key_cb_ = need_key_cb; |
54 new_segment_cb_ = new_segment_cb; | 56 new_segment_cb_ = new_segment_cb; |
| 57 end_of_segment_cb_ = end_of_segment_cb; |
55 } | 58 } |
56 | 59 |
57 void MP4StreamParser::Flush() { | 60 void MP4StreamParser::Flush() { |
58 DCHECK_NE(state_, kWaitingForInit); | 61 DCHECK_NE(state_, kWaitingForInit); |
59 | 62 |
60 queue_.Reset(); | 63 queue_.Reset(); |
61 moof_head_ = 0; | 64 moof_head_ = 0; |
62 mdat_tail_ = 0; | 65 mdat_tail_ = 0; |
63 } | 66 } |
64 | 67 |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 return true; | 312 return true; |
310 } | 313 } |
311 | 314 |
312 bool MP4StreamParser::EnqueueSample(BufferQueue* audio_buffers, | 315 bool MP4StreamParser::EnqueueSample(BufferQueue* audio_buffers, |
313 BufferQueue* video_buffers, | 316 BufferQueue* video_buffers, |
314 bool* err) { | 317 bool* err) { |
315 if (!runs_->IsRunValid()) { | 318 if (!runs_->IsRunValid()) { |
316 // Flush any buffers we've gotten in this chunk so that buffers don't | 319 // Flush any buffers we've gotten in this chunk so that buffers don't |
317 // cross NewSegment() calls | 320 // cross NewSegment() calls |
318 *err = !SendAndFlushSamples(audio_buffers, video_buffers); | 321 *err = !SendAndFlushSamples(audio_buffers, video_buffers); |
319 if (*err) return false; | 322 if (*err) |
| 323 return false; |
| 324 |
320 ChangeState(kParsingBoxes); | 325 ChangeState(kParsingBoxes); |
| 326 end_of_segment_cb_.Run(); |
321 return true; | 327 return true; |
322 } | 328 } |
323 | 329 |
324 if (!runs_->IsSampleValid()) { | 330 if (!runs_->IsSampleValid()) { |
325 runs_->AdvanceRun(); | 331 runs_->AdvanceRun(); |
326 return true; | 332 return true; |
327 } | 333 } |
328 | 334 |
329 DCHECK(!(*err)); | 335 DCHECK(!(*err)); |
330 | 336 |
331 const uint8* buf; | 337 const uint8* buf; |
332 int buf_size; | 338 int buf_size; |
333 queue_.Peek(&buf, &buf_size); | 339 queue_.Peek(&buf, &buf_size); |
334 if (!buf_size) return false; | 340 if (!buf_size) return false; |
335 | 341 |
336 bool audio = has_audio_ && audio_track_id_ == runs_->track_id(); | 342 bool audio = has_audio_ && audio_track_id_ == runs_->track_id(); |
337 bool video = has_video_ && video_track_id_ == runs_->track_id(); | 343 bool video = has_video_ && video_track_id_ == runs_->track_id(); |
338 | 344 |
339 // Skip this entire track if it's not one we're interested in | 345 // Skip this entire track if it's not one we're interested in |
340 if (!audio && !video) runs_->AdvanceRun(); | 346 if (!audio && !video) |
| 347 runs_->AdvanceRun(); |
341 | 348 |
342 // Attempt to cache the auxiliary information first. Aux info is usually | 349 // Attempt to cache the auxiliary information first. Aux info is usually |
343 // placed in a contiguous block before the sample data, rather than being | 350 // placed in a contiguous block before the sample data, rather than being |
344 // interleaved. If we didn't cache it, this would require that we retain the | 351 // interleaved. If we didn't cache it, this would require that we retain the |
345 // start of the segment buffer while reading samples. Aux info is typically | 352 // start of the segment buffer while reading samples. Aux info is typically |
346 // quite small compared to sample data, so this pattern is useful on | 353 // quite small compared to sample data, so this pattern is useful on |
347 // memory-constrained devices where the source buffer consumes a substantial | 354 // memory-constrained devices where the source buffer consumes a substantial |
348 // portion of the total system memory. | 355 // portion of the total system memory. |
349 if (runs_->AuxInfoNeedsToBeCached()) { | 356 if (runs_->AuxInfoNeedsToBeCached()) { |
350 queue_.PeekAt(runs_->aux_info_offset() + moof_head_, &buf, &buf_size); | 357 queue_.PeekAt(runs_->aux_info_offset() + moof_head_, &buf, &buf_size); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 return true; | 456 return true; |
450 } | 457 } |
451 | 458 |
452 void MP4StreamParser::ChangeState(State new_state) { | 459 void MP4StreamParser::ChangeState(State new_state) { |
453 DVLOG(2) << "Changing state: " << new_state; | 460 DVLOG(2) << "Changing state: " << new_state; |
454 state_ = new_state; | 461 state_ = new_state; |
455 } | 462 } |
456 | 463 |
457 } // namespace mp4 | 464 } // namespace mp4 |
458 } // namespace media | 465 } // namespace media |
OLD | NEW |