| 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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 | 59 |
| 60 return true; | 60 return true; |
| 61 } | 61 } |
| 62 | 62 |
| 63 MediaSourcePlayer::MediaSourcePlayer( | 63 MediaSourcePlayer::MediaSourcePlayer( |
| 64 int player_id, | 64 int player_id, |
| 65 MediaPlayerManager* manager, | 65 MediaPlayerManager* manager, |
| 66 const RequestMediaResourcesCB& request_media_resources_cb, | 66 const RequestMediaResourcesCB& request_media_resources_cb, |
| 67 const ReleaseMediaResourcesCB& release_media_resources_cb, | 67 const ReleaseMediaResourcesCB& release_media_resources_cb, |
| 68 scoped_ptr<DemuxerAndroid> demuxer) | 68 scoped_ptr<DemuxerAndroid> demuxer) |
| 69 : MediaPlayerAndroid(player_id, manager, request_media_resources_cb, | 69 : MediaPlayerAndroid(player_id, |
| 70 manager, |
| 71 request_media_resources_cb, |
| 70 release_media_resources_cb), | 72 release_media_resources_cb), |
| 71 demuxer_(demuxer.Pass()), | 73 demuxer_(demuxer.Pass()), |
| 72 pending_event_(NO_EVENT_PENDING), | 74 pending_event_(NO_EVENT_PENDING), |
| 73 width_(0), | 75 width_(0), |
| 74 height_(0), | 76 height_(0), |
| 75 audio_codec_(kUnknownAudioCodec), | 77 audio_codec_(kUnknownAudioCodec), |
| 76 video_codec_(kUnknownVideoCodec), | 78 video_codec_(kUnknownVideoCodec), |
| 77 num_channels_(0), | 79 num_channels_(0), |
| 78 sampling_rate_(0), | 80 sampling_rate_(0), |
| 79 reached_audio_eos_(false), | 81 reached_audio_eos_(false), |
| 80 reached_video_eos_(false), | 82 reached_video_eos_(false), |
| 81 playing_(false), | 83 playing_(false), |
| 82 is_audio_encrypted_(false), | 84 is_audio_encrypted_(false), |
| 83 is_video_encrypted_(false), | 85 is_video_encrypted_(false), |
| 84 volume_(-1.0), | 86 volume_(-1.0), |
| 85 clock_(&default_tick_clock_), | 87 clock_(&default_tick_clock_), |
| 86 next_video_data_is_iframe_(true), | 88 next_video_data_is_iframe_(true), |
| 87 doing_browser_seek_(false), | 89 doing_browser_seek_(false), |
| 88 pending_seek_(false), | 90 pending_seek_(false), |
| 89 reconfig_audio_decoder_(false), | 91 reconfig_audio_decoder_(false), |
| 90 reconfig_video_decoder_(false), | 92 reconfig_video_decoder_(false), |
| 91 weak_this_(this), | |
| 92 drm_bridge_(NULL), | 93 drm_bridge_(NULL), |
| 93 is_waiting_for_key_(false) { | 94 is_waiting_for_key_(false), |
| 95 weak_factory_(this) { |
| 94 demuxer_->Initialize(this); | 96 demuxer_->Initialize(this); |
| 95 clock_.SetMaxTime(base::TimeDelta()); | 97 clock_.SetMaxTime(base::TimeDelta()); |
| 96 } | 98 } |
| 97 | 99 |
| 98 MediaSourcePlayer::~MediaSourcePlayer() { | 100 MediaSourcePlayer::~MediaSourcePlayer() { |
| 99 Release(); | 101 Release(); |
| 100 } | 102 } |
| 101 | 103 |
| 102 void MediaSourcePlayer::SetVideoSurface(gfx::ScopedJavaSurface surface) { | 104 void MediaSourcePlayer::SetVideoSurface(gfx::ScopedJavaSurface surface) { |
| 103 // For an empty surface, always pass it to the decoder job so that it | 105 // For an empty surface, always pass it to the decoder job so that it |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 // http://crbug.com/253792. | 412 // http://crbug.com/253792. |
| 411 if (GetCurrentTime() > base::TimeDelta()) { | 413 if (GetCurrentTime() > base::TimeDelta()) { |
| 412 VLOG(0) << "Setting DRM bridge after playback has started. " | 414 VLOG(0) << "Setting DRM bridge after playback has started. " |
| 413 << "This is not well supported!"; | 415 << "This is not well supported!"; |
| 414 } | 416 } |
| 415 | 417 |
| 416 drm_bridge_ = drm_bridge; | 418 drm_bridge_ = drm_bridge; |
| 417 | 419 |
| 418 if (drm_bridge_->GetMediaCrypto().is_null()) { | 420 if (drm_bridge_->GetMediaCrypto().is_null()) { |
| 419 drm_bridge_->SetMediaCryptoReadyCB(base::Bind( | 421 drm_bridge_->SetMediaCryptoReadyCB(base::Bind( |
| 420 &MediaSourcePlayer::OnMediaCryptoReady, weak_this_.GetWeakPtr())); | 422 &MediaSourcePlayer::OnMediaCryptoReady, weak_factory_.GetWeakPtr())); |
| 421 return; | 423 return; |
| 422 } | 424 } |
| 423 | 425 |
| 424 if (playing_) | 426 if (playing_) |
| 425 StartInternal(); | 427 StartInternal(); |
| 426 } | 428 } |
| 427 | 429 |
| 428 void MediaSourcePlayer::OnDemuxerSeekDone( | 430 void MediaSourcePlayer::OnDemuxerSeekDone( |
| 429 const base::TimeDelta& actual_browser_seek_time) { | 431 const base::TimeDelta& actual_browser_seek_time) { |
| 430 DVLOG(1) << __FUNCTION__; | 432 DVLOG(1) << __FUNCTION__; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 545 int count = (AudioFinished() ? 0 : 1) + (VideoFinished() ? 0 : 1); | 547 int count = (AudioFinished() ? 0 : 1) + (VideoFinished() ? 0 : 1); |
| 546 | 548 |
| 547 // It is possible that all streams have finished decode, yet starvation | 549 // It is possible that all streams have finished decode, yet starvation |
| 548 // occurred during the last stream's EOS decode. In this case, prefetch is a | 550 // occurred during the last stream's EOS decode. In this case, prefetch is a |
| 549 // no-op. | 551 // no-op. |
| 550 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); | 552 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); |
| 551 if (count == 0) | 553 if (count == 0) |
| 552 return; | 554 return; |
| 553 | 555 |
| 554 SetPendingEvent(PREFETCH_DONE_EVENT_PENDING); | 556 SetPendingEvent(PREFETCH_DONE_EVENT_PENDING); |
| 555 base::Closure barrier = BarrierClosure(count, base::Bind( | 557 base::Closure barrier = |
| 556 &MediaSourcePlayer::OnPrefetchDone, weak_this_.GetWeakPtr())); | 558 BarrierClosure(count, |
| 559 base::Bind(&MediaSourcePlayer::OnPrefetchDone, |
| 560 weak_factory_.GetWeakPtr())); |
| 557 | 561 |
| 558 if (!AudioFinished()) | 562 if (!AudioFinished()) |
| 559 audio_decoder_job_->Prefetch(barrier); | 563 audio_decoder_job_->Prefetch(barrier); |
| 560 | 564 |
| 561 if (!VideoFinished()) | 565 if (!VideoFinished()) |
| 562 video_decoder_job_->Prefetch(barrier); | 566 video_decoder_job_->Prefetch(barrier); |
| 563 | 567 |
| 564 return; | 568 return; |
| 565 } | 569 } |
| 566 | 570 |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 | 672 |
| 669 DecodeMoreVideo(); | 673 DecodeMoreVideo(); |
| 670 } | 674 } |
| 671 | 675 |
| 672 void MediaSourcePlayer::DecodeMoreAudio() { | 676 void MediaSourcePlayer::DecodeMoreAudio() { |
| 673 DVLOG(1) << __FUNCTION__; | 677 DVLOG(1) << __FUNCTION__; |
| 674 DCHECK(!audio_decoder_job_->is_decoding()); | 678 DCHECK(!audio_decoder_job_->is_decoding()); |
| 675 DCHECK(!AudioFinished()); | 679 DCHECK(!AudioFinished()); |
| 676 | 680 |
| 677 if (audio_decoder_job_->Decode( | 681 if (audio_decoder_job_->Decode( |
| 678 start_time_ticks_, start_presentation_timestamp_, base::Bind( | 682 start_time_ticks_, |
| 679 &MediaSourcePlayer::MediaDecoderCallback, | 683 start_presentation_timestamp_, |
| 680 weak_this_.GetWeakPtr(), true))) { | 684 base::Bind(&MediaSourcePlayer::MediaDecoderCallback, |
| 685 weak_factory_.GetWeakPtr(), |
| 686 true))) { |
| 681 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio", | 687 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio", |
| 682 audio_decoder_job_.get()); | 688 audio_decoder_job_.get()); |
| 683 return; | 689 return; |
| 684 } | 690 } |
| 685 | 691 |
| 686 // Failed to start the next decode. | 692 // Failed to start the next decode. |
| 687 // Wait for demuxer ready message. | 693 // Wait for demuxer ready message. |
| 688 DCHECK(!reconfig_audio_decoder_); | 694 DCHECK(!reconfig_audio_decoder_); |
| 689 reconfig_audio_decoder_ = true; | 695 reconfig_audio_decoder_ = true; |
| 690 | 696 |
| 691 // Config change may have just been detected on the other stream. If so, | 697 // Config change may have just been detected on the other stream. If so, |
| 692 // don't send a duplicate demuxer config request. | 698 // don't send a duplicate demuxer config request. |
| 693 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) { | 699 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) { |
| 694 DCHECK(reconfig_video_decoder_); | 700 DCHECK(reconfig_video_decoder_); |
| 695 return; | 701 return; |
| 696 } | 702 } |
| 697 | 703 |
| 698 SetPendingEvent(CONFIG_CHANGE_EVENT_PENDING); | 704 SetPendingEvent(CONFIG_CHANGE_EVENT_PENDING); |
| 699 ProcessPendingEvents(); | 705 ProcessPendingEvents(); |
| 700 } | 706 } |
| 701 | 707 |
| 702 void MediaSourcePlayer::DecodeMoreVideo() { | 708 void MediaSourcePlayer::DecodeMoreVideo() { |
| 703 DVLOG(1) << __FUNCTION__; | 709 DVLOG(1) << __FUNCTION__; |
| 704 DCHECK(!video_decoder_job_->is_decoding()); | 710 DCHECK(!video_decoder_job_->is_decoding()); |
| 705 DCHECK(!VideoFinished()); | 711 DCHECK(!VideoFinished()); |
| 706 | 712 |
| 707 if (video_decoder_job_->Decode( | 713 if (video_decoder_job_->Decode( |
| 708 start_time_ticks_, start_presentation_timestamp_, base::Bind( | 714 start_time_ticks_, |
| 709 &MediaSourcePlayer::MediaDecoderCallback, | 715 start_presentation_timestamp_, |
| 710 weak_this_.GetWeakPtr(), false))) { | 716 base::Bind(&MediaSourcePlayer::MediaDecoderCallback, |
| 717 weak_factory_.GetWeakPtr(), |
| 718 false))) { |
| 711 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreVideo", | 719 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreVideo", |
| 712 video_decoder_job_.get()); | 720 video_decoder_job_.get()); |
| 713 return; | 721 return; |
| 714 } | 722 } |
| 715 | 723 |
| 716 // Failed to start the next decode. | 724 // Failed to start the next decode. |
| 717 // Wait for demuxer ready message. | 725 // Wait for demuxer ready message. |
| 718 | 726 |
| 719 // After this detection of video config change, next video data received | 727 // After this detection of video config change, next video data received |
| 720 // will begin with I-frame. | 728 // will begin with I-frame. |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 906 // For video only streams, fps can be estimated from the difference | 914 // For video only streams, fps can be estimated from the difference |
| 907 // between the previous and current presentation timestamps. The | 915 // between the previous and current presentation timestamps. The |
| 908 // previous presentation timestamp is equal to current_timestamp. | 916 // previous presentation timestamp is equal to current_timestamp. |
| 909 // TODO(qinmin): determine whether 2 is a good coefficient for estimating | 917 // TODO(qinmin): determine whether 2 is a good coefficient for estimating |
| 910 // video frame timeout. | 918 // video frame timeout. |
| 911 timeout = 2 * (presentation_timestamp - current_timestamp); | 919 timeout = 2 * (presentation_timestamp - current_timestamp); |
| 912 } | 920 } |
| 913 | 921 |
| 914 timeout = std::max(timeout, kMinStarvationTimeout); | 922 timeout = std::max(timeout, kMinStarvationTimeout); |
| 915 | 923 |
| 916 decoder_starvation_callback_.Reset( | 924 decoder_starvation_callback_.Reset(base::Bind( |
| 917 base::Bind(&MediaSourcePlayer::OnDecoderStarved, | 925 &MediaSourcePlayer::OnDecoderStarved, weak_factory_.GetWeakPtr())); |
| 918 weak_this_.GetWeakPtr())); | |
| 919 base::MessageLoop::current()->PostDelayedTask( | 926 base::MessageLoop::current()->PostDelayedTask( |
| 920 FROM_HERE, decoder_starvation_callback_.callback(), timeout); | 927 FROM_HERE, decoder_starvation_callback_.callback(), timeout); |
| 921 } | 928 } |
| 922 | 929 |
| 923 void MediaSourcePlayer::SetVolumeInternal() { | 930 void MediaSourcePlayer::SetVolumeInternal() { |
| 924 if (audio_decoder_job_ && volume_ >= 0) | 931 if (audio_decoder_job_ && volume_ >= 0) |
| 925 audio_decoder_job_->SetVolume(volume_); | 932 audio_decoder_job_->SetVolume(volume_); |
| 926 } | 933 } |
| 927 | 934 |
| 928 bool MediaSourcePlayer::IsProtectedSurfaceRequired() { | 935 bool MediaSourcePlayer::IsProtectedSurfaceRequired() { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 997 | 1004 |
| 998 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) { | 1005 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) { |
| 999 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")"; | 1006 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")"; |
| 1000 DCHECK_NE(event, NO_EVENT_PENDING); | 1007 DCHECK_NE(event, NO_EVENT_PENDING); |
| 1001 DCHECK(IsEventPending(event)) << GetEventName(event); | 1008 DCHECK(IsEventPending(event)) << GetEventName(event); |
| 1002 | 1009 |
| 1003 pending_event_ &= ~event; | 1010 pending_event_ &= ~event; |
| 1004 } | 1011 } |
| 1005 | 1012 |
| 1006 } // namespace media | 1013 } // namespace media |
| OLD | NEW |