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 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 return true; | 257 return true; |
255 } | 258 } |
256 | 259 |
257 bool MP4StreamParser::EnqueueSample(BufferQueue* audio_buffers, | 260 bool MP4StreamParser::EnqueueSample(BufferQueue* audio_buffers, |
258 BufferQueue* video_buffers, | 261 BufferQueue* video_buffers, |
259 bool* err) { | 262 bool* err) { |
260 if (!runs_->RunIsValid()) { | 263 if (!runs_->RunIsValid()) { |
261 // Flush any buffers we've gotten in this chunk so that buffers don't | 264 // Flush any buffers we've gotten in this chunk so that buffers don't |
262 // cross NewSegment() calls | 265 // cross NewSegment() calls |
263 *err = !SendAndFlushSamples(audio_buffers, video_buffers); | 266 *err = !SendAndFlushSamples(audio_buffers, video_buffers); |
264 if (*err) return false; | 267 if (*err) |
| 268 return false; |
| 269 |
265 ChangeState(kParsingBoxes); | 270 ChangeState(kParsingBoxes); |
| 271 end_of_segment_cb_.Run(); |
266 return true; | 272 return true; |
267 } | 273 } |
268 | 274 |
269 if (!runs_->SampleIsValid()) { | 275 if (!runs_->SampleIsValid()) { |
270 runs_->AdvanceRun(); | 276 runs_->AdvanceRun(); |
271 return true; | 277 return true; |
272 } | 278 } |
273 | 279 |
274 DCHECK(!(*err)); | 280 DCHECK(!(*err)); |
275 | 281 |
276 const uint8* buf; | 282 const uint8* buf; |
277 int size; | 283 int size; |
278 queue_.Peek(&buf, &size); | 284 queue_.Peek(&buf, &size); |
279 if (!size) return false; | 285 if (!size) |
| 286 return false; |
280 | 287 |
281 bool audio = has_audio_ && audio_track_id_ == runs_->track_id(); | 288 bool audio = has_audio_ && audio_track_id_ == runs_->track_id(); |
282 bool video = has_video_ && video_track_id_ == runs_->track_id(); | 289 bool video = has_video_ && video_track_id_ == runs_->track_id(); |
283 | 290 |
284 // Skip this entire track if it's not one we're interested in | 291 // Skip this entire track if it's not one we're interested in |
285 if (!audio && !video) runs_->AdvanceRun(); | 292 if (!audio && !video) |
| 293 runs_->AdvanceRun(); |
286 | 294 |
287 queue_.PeekAt(runs_->sample_offset() + moof_head_, &buf, &size); | 295 queue_.PeekAt(runs_->sample_offset() + moof_head_, &buf, &size); |
288 if (size < runs_->sample_size()) return false; | 296 if (size < runs_->sample_size()) |
| 297 return false; |
289 | 298 |
290 std::vector<uint8> frame_buf(buf, buf + runs_->sample_size()); | 299 std::vector<uint8> frame_buf(buf, buf + runs_->sample_size()); |
291 if (video) { | 300 if (video) { |
292 const AVCDecoderConfigurationRecord& avc_config = | 301 const AVCDecoderConfigurationRecord& avc_config = |
293 runs_->video_description().avcc; | 302 runs_->video_description().avcc; |
294 RCHECK(AVC::ConvertToAnnexB(avc_config.length_size, &frame_buf)); | 303 RCHECK(AVC::ConvertToAnnexB(avc_config.length_size, &frame_buf)); |
295 if (runs_->is_keyframe()) | 304 if (runs_->is_keyframe()) |
296 RCHECK(AVC::InsertParameterSets(avc_config, &frame_buf)); | 305 RCHECK(AVC::InsertParameterSets(avc_config, &frame_buf)); |
297 } | 306 } |
298 | 307 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 return true; | 375 return true; |
367 } | 376 } |
368 | 377 |
369 void MP4StreamParser::ChangeState(State new_state) { | 378 void MP4StreamParser::ChangeState(State new_state) { |
370 DVLOG(2) << "Changing state: " << new_state; | 379 DVLOG(2) << "Changing state: " << new_state; |
371 state_ = new_state; | 380 state_ = new_state; |
372 } | 381 } |
373 | 382 |
374 } // namespace mp4 | 383 } // namespace mp4 |
375 } // namespace media | 384 } // namespace media |
OLD | NEW |