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/logging.h" | 8 #include "base/logging.h" |
9 #include "base/time.h" | 9 #include "base/time.h" |
10 #include "media/base/audio_decoder_config.h" | 10 #include "media/base/audio_decoder_config.h" |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 DCHECK_EQ(kEmittingSamples, state_); | 85 DCHECK_EQ(kEmittingSamples, state_); |
86 result = EnqueueSample(&audio_buffers, &video_buffers, &err); | 86 result = EnqueueSample(&audio_buffers, &video_buffers, &err); |
87 if (result) { | 87 if (result) { |
88 int64 max_clear = runs_.GetMaxClearOffset() + moof_head_; | 88 int64 max_clear = runs_.GetMaxClearOffset() + moof_head_; |
89 DCHECK(max_clear <= queue_.tail()); | 89 DCHECK(max_clear <= queue_.tail()); |
90 err = !(ReadMDATsUntil(max_clear) && queue_.Trim(max_clear)); | 90 err = !(ReadMDATsUntil(max_clear) && queue_.Trim(max_clear)); |
91 } | 91 } |
92 } | 92 } |
93 } while (result && !err); | 93 } while (result && !err); |
94 | 94 |
| 95 if (!err) |
| 96 err = !FlushSamples(&audio_buffers, &video_buffers); |
| 97 |
95 if (err) { | 98 if (err) { |
96 DLOG(ERROR) << "Unknown error while parsing MP4"; | 99 DLOG(ERROR) << "Error while parsing MP4"; |
97 queue_.Reset(); | 100 queue_.Reset(); |
98 moov_.reset(); | 101 moov_.reset(); |
99 ChangeState(kError); | 102 ChangeState(kError); |
100 return false; | 103 return false; |
101 } | 104 } |
102 | 105 |
103 if (!audio_buffers.empty() && | |
104 (audio_cb_.is_null() || !audio_cb_.Run(audio_buffers))) | |
105 return false; | |
106 if (!video_buffers.empty() && | |
107 (video_cb_.is_null() || !video_cb_.Run(video_buffers))) | |
108 return false; | |
109 | |
110 return true; | 106 return true; |
111 } | 107 } |
112 | 108 |
113 bool MP4StreamParser::ParseBox(bool* err) { | 109 bool MP4StreamParser::ParseBox(bool* err) { |
114 const uint8* buf; | 110 const uint8* buf; |
115 int size; | 111 int size; |
116 queue_.Peek(&buf, &size); | 112 queue_.Peek(&buf, &size); |
117 if (!size) return false; | 113 if (!size) return false; |
118 | 114 |
119 scoped_ptr<BoxReader> reader(BoxReader::ReadTopLevelBox(buf, size, err)); | 115 scoped_ptr<BoxReader> reader(BoxReader::ReadTopLevelBox(buf, size, err)); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 RCHECK(runs_.Init(*moov_, moof)); | 220 RCHECK(runs_.Init(*moov_, moof)); |
225 new_segment_cb_.Run(runs_.GetMinDecodeTimestamp()); | 221 new_segment_cb_.Run(runs_.GetMinDecodeTimestamp()); |
226 ChangeState(kEmittingSamples); | 222 ChangeState(kEmittingSamples); |
227 return true; | 223 return true; |
228 } | 224 } |
229 | 225 |
230 bool MP4StreamParser::EnqueueSample(BufferQueue* audio_buffers, | 226 bool MP4StreamParser::EnqueueSample(BufferQueue* audio_buffers, |
231 BufferQueue* video_buffers, | 227 BufferQueue* video_buffers, |
232 bool* err) { | 228 bool* err) { |
233 if (!runs_.RunValid()) { | 229 if (!runs_.RunValid()) { |
| 230 // Flush any buffers we've gotten in this chunk so that buffers don't |
| 231 // cross NewSegment() calls |
| 232 *err = !FlushSamples(audio_buffers, video_buffers); |
| 233 if (*err) return false; |
234 ChangeState(kParsingBoxes); | 234 ChangeState(kParsingBoxes); |
235 return true; | 235 return true; |
236 } | 236 } |
237 | 237 |
238 if (!runs_.SampleValid()) { | 238 if (!runs_.SampleValid()) { |
239 runs_.AdvanceRun(); | 239 runs_.AdvanceRun(); |
240 return true; | 240 return true; |
241 } | 241 } |
242 | 242 |
243 DCHECK(!(*err)); | 243 DCHECK(!(*err)); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 if (audio) { | 304 if (audio) { |
305 audio_buffers->push_back(stream_buf); | 305 audio_buffers->push_back(stream_buf); |
306 } else { | 306 } else { |
307 video_buffers->push_back(stream_buf); | 307 video_buffers->push_back(stream_buf); |
308 } | 308 } |
309 | 309 |
310 runs_.AdvanceSample(); | 310 runs_.AdvanceSample(); |
311 return true; | 311 return true; |
312 } | 312 } |
313 | 313 |
| 314 bool MP4StreamParser::FlushSamples(BufferQueue* audio_buffers, |
| 315 BufferQueue* video_buffers) { |
| 316 if (!audio_buffers->empty()) { |
| 317 if (audio_cb_.is_null() || !audio_cb_.Run(*audio_buffers)) |
| 318 return false; |
| 319 audio_buffers->clear(); |
| 320 } |
| 321 if (!video_buffers->empty()) { |
| 322 if (video_cb_.is_null() || !video_cb_.Run(*video_buffers)) |
| 323 return false; |
| 324 video_buffers->clear(); |
| 325 } |
| 326 return true; |
| 327 } |
| 328 |
314 bool MP4StreamParser::ReadMDATsUntil(const int64 tgt_offset) { | 329 bool MP4StreamParser::ReadMDATsUntil(const int64 tgt_offset) { |
315 DCHECK(tgt_offset <= queue_.tail()); | 330 DCHECK(tgt_offset <= queue_.tail()); |
316 | 331 |
317 while (mdat_tail_ < tgt_offset) { | 332 while (mdat_tail_ < tgt_offset) { |
318 const uint8* buf; | 333 const uint8* buf; |
319 int size; | 334 int size; |
320 queue_.PeekAt(mdat_tail_, &buf, &size); | 335 queue_.PeekAt(mdat_tail_, &buf, &size); |
321 | 336 |
322 FourCC type; | 337 FourCC type; |
323 int box_sz; | 338 int box_sz; |
(...skipping 12 matching lines...) Expand all Loading... |
336 return true; | 351 return true; |
337 } | 352 } |
338 | 353 |
339 void MP4StreamParser::ChangeState(State new_state) { | 354 void MP4StreamParser::ChangeState(State new_state) { |
340 DVLOG(2) << "Changing state: " << new_state; | 355 DVLOG(2) << "Changing state: " << new_state; |
341 state_ = new_state; | 356 state_ = new_state; |
342 } | 357 } |
343 | 358 |
344 } // namespace mp4 | 359 } // namespace mp4 |
345 } // namespace media | 360 } // namespace media |
OLD | NEW |