OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/base/android/media_source_player.h" | 5 #include "media/base/android/media_source_player.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "base/android/jni_android.h" | 9 #include "base/android/jni_android.h" |
10 #include "base/android/jni_string.h" | 10 #include "base/android/jni_string.h" |
(...skipping 26 matching lines...) Expand all Loading... |
37 pending_event_(NO_EVENT_PENDING), | 37 pending_event_(NO_EVENT_PENDING), |
38 playing_(false), | 38 playing_(false), |
39 interpolator_(&default_tick_clock_), | 39 interpolator_(&default_tick_clock_), |
40 doing_browser_seek_(false), | 40 doing_browser_seek_(false), |
41 pending_seek_(false), | 41 pending_seek_(false), |
42 drm_bridge_(NULL), | 42 drm_bridge_(NULL), |
43 cdm_registration_id_(0), | 43 cdm_registration_id_(0), |
44 is_waiting_for_key_(false), | 44 is_waiting_for_key_(false), |
45 is_waiting_for_audio_decoder_(false), | 45 is_waiting_for_audio_decoder_(false), |
46 is_waiting_for_video_decoder_(false), | 46 is_waiting_for_video_decoder_(false), |
| 47 prerolling_(false), |
47 weak_factory_(this) { | 48 weak_factory_(this) { |
48 audio_decoder_job_.reset(new AudioDecoderJob( | 49 audio_decoder_job_.reset(new AudioDecoderJob( |
49 base::Bind(&DemuxerAndroid::RequestDemuxerData, | 50 base::Bind(&DemuxerAndroid::RequestDemuxerData, |
50 base::Unretained(demuxer_.get()), | 51 base::Unretained(demuxer_.get()), |
51 DemuxerStream::AUDIO), | 52 DemuxerStream::AUDIO), |
52 base::Bind(&MediaSourcePlayer::OnDemuxerConfigsChanged, | 53 base::Bind(&MediaSourcePlayer::OnDemuxerConfigsChanged, |
53 weak_factory_.GetWeakPtr()))); | 54 weak_factory_.GetWeakPtr()))); |
54 video_decoder_job_.reset(new VideoDecoderJob( | 55 video_decoder_job_.reset(new VideoDecoderJob( |
55 base::Bind(&DemuxerAndroid::RequestDemuxerData, | 56 base::Bind(&DemuxerAndroid::RequestDemuxerData, |
56 base::Unretained(demuxer_.get()), | 57 base::Unretained(demuxer_.get()), |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 base::TimeDelta current_time = GetCurrentTime(); | 340 base::TimeDelta current_time = GetCurrentTime(); |
340 // TODO(qinmin): Simplify the logic by using |start_presentation_timestamp_| | 341 // TODO(qinmin): Simplify the logic by using |start_presentation_timestamp_| |
341 // to preroll media decoder jobs. Currently |start_presentation_timestamp_| | 342 // to preroll media decoder jobs. Currently |start_presentation_timestamp_| |
342 // is calculated from decoder output, while preroll relies on the access | 343 // is calculated from decoder output, while preroll relies on the access |
343 // unit's timestamp. There are some differences between the two. | 344 // unit's timestamp. There are some differences between the two. |
344 preroll_timestamp_ = current_time; | 345 preroll_timestamp_ = current_time; |
345 if (HasAudio()) | 346 if (HasAudio()) |
346 audio_decoder_job_->BeginPrerolling(preroll_timestamp_); | 347 audio_decoder_job_->BeginPrerolling(preroll_timestamp_); |
347 if (HasVideo()) | 348 if (HasVideo()) |
348 video_decoder_job_->BeginPrerolling(preroll_timestamp_); | 349 video_decoder_job_->BeginPrerolling(preroll_timestamp_); |
| 350 prerolling_ = true; |
349 | 351 |
350 if (!doing_browser_seek_) | 352 if (!doing_browser_seek_) |
351 manager()->OnSeekComplete(player_id(), current_time); | 353 manager()->OnSeekComplete(player_id(), current_time); |
352 | 354 |
353 ProcessPendingEvents(); | 355 ProcessPendingEvents(); |
354 } | 356 } |
355 | 357 |
356 void MediaSourcePlayer::UpdateTimestamps( | 358 void MediaSourcePlayer::UpdateTimestamps( |
357 base::TimeDelta current_presentation_timestamp, | 359 base::TimeDelta current_presentation_timestamp, |
358 base::TimeDelta max_presentation_timestamp) { | 360 base::TimeDelta max_presentation_timestamp) { |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 is_waiting_for_key_ = true; | 504 is_waiting_for_key_ = true; |
503 return; | 505 return; |
504 } | 506 } |
505 | 507 |
506 // If the status is MEDIA_CODEC_STOPPED, stop decoding new data. The player is | 508 // If the status is MEDIA_CODEC_STOPPED, stop decoding new data. The player is |
507 // in the middle of a seek or stop event and needs to wait for the IPCs to | 509 // in the middle of a seek or stop event and needs to wait for the IPCs to |
508 // come. | 510 // come. |
509 if (status == MEDIA_CODEC_STOPPED) | 511 if (status == MEDIA_CODEC_STOPPED) |
510 return; | 512 return; |
511 | 513 |
| 514 if (prerolling_ && IsPrerollFinished(is_audio)) { |
| 515 if (IsPrerollFinished(!is_audio)) { |
| 516 prerolling_ = false; |
| 517 StartInternal(); |
| 518 } |
| 519 return; |
| 520 } |
| 521 |
512 if (is_clock_manager) { | 522 if (is_clock_manager) { |
513 // If we have a valid timestamp, start the starvation callback. Otherwise, | 523 // If we have a valid timestamp, start the starvation callback. Otherwise, |
514 // reset the |start_time_ticks_| so that the next frame will not suffer | 524 // reset the |start_time_ticks_| so that the next frame will not suffer |
515 // from the decoding delay caused by the current frame. | 525 // from the decoding delay caused by the current frame. |
516 if (current_presentation_timestamp != kNoTimestamp()) | 526 if (current_presentation_timestamp != kNoTimestamp()) |
517 StartStarvationCallback(current_presentation_timestamp, | 527 StartStarvationCallback(current_presentation_timestamp, |
518 max_presentation_timestamp); | 528 max_presentation_timestamp); |
519 else | 529 else |
520 start_time_ticks_ = base::TimeTicks::Now(); | 530 start_time_ticks_ = base::TimeTicks::Now(); |
521 } | 531 } |
522 | 532 |
523 if (is_audio) | 533 if (is_audio) |
524 DecodeMoreAudio(); | 534 DecodeMoreAudio(); |
525 else | 535 else |
526 DecodeMoreVideo(); | 536 DecodeMoreVideo(); |
527 } | 537 } |
528 | 538 |
| 539 bool MediaSourcePlayer::IsPrerollFinished(bool is_audio) const { |
| 540 if (is_audio) |
| 541 return !HasAudio() || !audio_decoder_job_->prerolling(); |
| 542 return !HasVideo() || !video_decoder_job_->prerolling(); |
| 543 } |
| 544 |
529 void MediaSourcePlayer::DecodeMoreAudio() { | 545 void MediaSourcePlayer::DecodeMoreAudio() { |
530 DVLOG(1) << __FUNCTION__; | 546 DVLOG(1) << __FUNCTION__; |
531 DCHECK(!audio_decoder_job_->is_decoding()); | 547 DCHECK(!audio_decoder_job_->is_decoding()); |
532 DCHECK(!AudioFinished()); | 548 DCHECK(!AudioFinished()); |
533 | 549 |
534 if (audio_decoder_job_->Decode( | 550 if (audio_decoder_job_->Decode( |
535 start_time_ticks_, | 551 start_time_ticks_, |
536 start_presentation_timestamp_, | 552 start_presentation_timestamp_, |
537 base::Bind(&MediaSourcePlayer::MediaDecoderCallback, weak_this_, true))) { | 553 base::Bind(&MediaSourcePlayer::MediaDecoderCallback, weak_this_, true))) { |
538 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio", | 554 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio", |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 } | 598 } |
583 } | 599 } |
584 | 600 |
585 void MediaSourcePlayer::ClearDecodingData() { | 601 void MediaSourcePlayer::ClearDecodingData() { |
586 DVLOG(1) << __FUNCTION__; | 602 DVLOG(1) << __FUNCTION__; |
587 audio_decoder_job_->Flush(); | 603 audio_decoder_job_->Flush(); |
588 video_decoder_job_->Flush(); | 604 video_decoder_job_->Flush(); |
589 start_time_ticks_ = base::TimeTicks(); | 605 start_time_ticks_ = base::TimeTicks(); |
590 } | 606 } |
591 | 607 |
592 bool MediaSourcePlayer::HasVideo() { | 608 bool MediaSourcePlayer::HasVideo() const { |
593 return video_decoder_job_->HasStream(); | 609 return video_decoder_job_->HasStream(); |
594 } | 610 } |
595 | 611 |
596 bool MediaSourcePlayer::HasAudio() { | 612 bool MediaSourcePlayer::HasAudio() const { |
597 return audio_decoder_job_->HasStream(); | 613 return audio_decoder_job_->HasStream(); |
598 } | 614 } |
599 | 615 |
600 bool MediaSourcePlayer::AudioFinished() { | 616 bool MediaSourcePlayer::AudioFinished() { |
601 return audio_decoder_job_->OutputEOSReached() || !HasAudio(); | 617 return audio_decoder_job_->OutputEOSReached() || !HasAudio(); |
602 } | 618 } |
603 | 619 |
604 bool MediaSourcePlayer::VideoFinished() { | 620 bool MediaSourcePlayer::VideoFinished() { |
605 return video_decoder_job_->OutputEOSReached() || !HasVideo(); | 621 return video_decoder_job_->OutputEOSReached() || !HasVideo(); |
606 } | 622 } |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
755 // support setMediaKeys(0) (see http://crbug.com/330324), or when we release | 771 // support setMediaKeys(0) (see http://crbug.com/330324), or when we release |
756 // MediaDrm when the video is paused, or when the device goes to sleep (see | 772 // MediaDrm when the video is paused, or when the device goes to sleep (see |
757 // http://crbug.com/272421). | 773 // http://crbug.com/272421). |
758 audio_decoder_job_->SetDrmBridge(NULL); | 774 audio_decoder_job_->SetDrmBridge(NULL); |
759 video_decoder_job_->SetDrmBridge(NULL); | 775 video_decoder_job_->SetDrmBridge(NULL); |
760 cdm_registration_id_ = 0; | 776 cdm_registration_id_ = 0; |
761 drm_bridge_ = NULL; | 777 drm_bridge_ = NULL; |
762 } | 778 } |
763 | 779 |
764 } // namespace media | 780 } // namespace media |
OLD | NEW |