Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(131)

Side by Side Diff: media/base/android/media_source_player.cc

Issue 53413004: Clear any pending surface change prior to checking media crypto in MSP::ConfigureVideoDecoderJob() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add reference from new unit test to http://crbug.com/313860 Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 return clock_.Elapsed(); 224 return clock_.Elapsed();
225 } 225 }
226 226
227 base::TimeDelta MediaSourcePlayer::GetDuration() { 227 base::TimeDelta MediaSourcePlayer::GetDuration() {
228 return duration_; 228 return duration_;
229 } 229 }
230 230
231 void MediaSourcePlayer::Release() { 231 void MediaSourcePlayer::Release() {
232 DVLOG(1) << __FUNCTION__; 232 DVLOG(1) << __FUNCTION__;
233 audio_decoder_job_.reset(); 233 audio_decoder_job_.reset();
234 video_decoder_job_.reset(); 234 ResetVideoDecoderJob();
235 reconfig_audio_decoder_ = false; 235 reconfig_audio_decoder_ = false;
236 reconfig_video_decoder_ = false; 236 reconfig_video_decoder_ = false;
237 playing_ = false; 237 playing_ = false;
238 pending_event_ = NO_EVENT_PENDING; 238 pending_event_ = NO_EVENT_PENDING;
239 decoder_starvation_callback_.Cancel(); 239 decoder_starvation_callback_.Cancel();
240 surface_ = gfx::ScopedJavaSurface(); 240 surface_ = gfx::ScopedJavaSurface();
241 manager()->ReleaseMediaResources(player_id()); 241 manager()->ReleaseMediaResources(player_id());
242 } 242 }
243 243
244 void MediaSourcePlayer::SetVolume(double volume) { 244 void MediaSourcePlayer::SetVolume(double volume) {
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) { 486 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) {
487 DVLOG(1) << __FUNCTION__ << " : Handling CONFIG_CHANGE_EVENT."; 487 DVLOG(1) << __FUNCTION__ << " : Handling CONFIG_CHANGE_EVENT.";
488 DCHECK(reconfig_audio_decoder_ || reconfig_video_decoder_); 488 DCHECK(reconfig_audio_decoder_ || reconfig_video_decoder_);
489 demuxer_->RequestDemuxerConfigs(); 489 demuxer_->RequestDemuxerConfigs();
490 return; 490 return;
491 } 491 }
492 492
493 if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING)) { 493 if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING)) {
494 DVLOG(1) << __FUNCTION__ << " : Handling SURFACE_CHANGE_EVENT."; 494 DVLOG(1) << __FUNCTION__ << " : Handling SURFACE_CHANGE_EVENT.";
495 // Setting a new surface will require a new MediaCodec to be created. 495 // Setting a new surface will require a new MediaCodec to be created.
496 video_decoder_job_.reset(); 496 ResetVideoDecoderJob();
497 ConfigureVideoDecoderJob(); 497 ConfigureVideoDecoderJob();
498 498
499 // Return early if we can't successfully configure a new video decoder job 499 // Return early if we can't successfully configure a new video decoder job
500 // yet, except continue processing other pending events if |surface_| is 500 // yet, except continue processing other pending events if |surface_| is
501 // empty. 501 // empty.
502 if (!video_decoder_job_ && !surface_.IsEmpty()) 502 if (!video_decoder_job_ && !surface_.IsEmpty())
503 return; 503 return;
504 } 504 }
505 505
506 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) { 506 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) {
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 base::Bind(&DemuxerAndroid::RequestDemuxerData, 711 base::Bind(&DemuxerAndroid::RequestDemuxerData,
712 base::Unretained(demuxer_.get()), DemuxerStream::AUDIO))); 712 base::Unretained(demuxer_.get()), DemuxerStream::AUDIO)));
713 713
714 if (audio_decoder_job_) { 714 if (audio_decoder_job_) {
715 SetVolumeInternal(); 715 SetVolumeInternal();
716 audio_decoder_job_->BeginPrerolling(preroll_timestamp_); 716 audio_decoder_job_->BeginPrerolling(preroll_timestamp_);
717 reconfig_audio_decoder_ = false; 717 reconfig_audio_decoder_ = false;
718 } 718 }
719 } 719 }
720 720
721 void MediaSourcePlayer::ResetVideoDecoderJob() {
722 video_decoder_job_.reset();
723
724 // Any eventual video decoder job re-creation will use the current |surface_|.
725 if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING))
726 ClearPendingEvent(SURFACE_CHANGE_EVENT_PENDING);
727 }
728
721 void MediaSourcePlayer::ConfigureVideoDecoderJob() { 729 void MediaSourcePlayer::ConfigureVideoDecoderJob() {
722 if (!HasVideo() || surface_.IsEmpty()) { 730 if (!HasVideo() || surface_.IsEmpty()) {
723 video_decoder_job_.reset(); 731 ResetVideoDecoderJob();
724 if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING))
725 ClearPendingEvent(SURFACE_CHANGE_EVENT_PENDING);
726 return; 732 return;
727 } 733 }
728 734
729 // Create video decoder job only if config changes or we don't have a job. 735 // Create video decoder job only if config changes or we don't have a job.
730 if (video_decoder_job_ && !reconfig_video_decoder_) 736 if (video_decoder_job_ && !reconfig_video_decoder_) {
737 DCHECK(!IsEventPending(SURFACE_CHANGE_EVENT_PENDING));
731 return; 738 return;
739 }
732 740
733 if (reconfig_video_decoder_) { 741 if (reconfig_video_decoder_) {
734 // No hack browser seek should be required. I-Frame must be next. 742 // No hack browser seek should be required. I-Frame must be next.
735 DCHECK(next_video_data_is_iframe_) << "Received video data between " 743 DCHECK(next_video_data_is_iframe_) << "Received video data between "
736 << "detecting video config change and reconfiguring video decoder"; 744 << "detecting video config change and reconfiguring video decoder";
737 } 745 }
738 746
747 DCHECK(!video_decoder_job_ || !video_decoder_job_->is_decoding());
xhwang 2013/10/31 21:37:18 Do we ever call ConfigureVideoDecoderJob() when vi
wolenetz 2013/11/02 00:00:57 Good point. Thanks for chat that helped clarify EM
748
739 // If uncertain that video I-frame data is next and there is no seek already 749 // If uncertain that video I-frame data is next and there is no seek already
740 // in process, request browser demuxer seek so the new decoder will decode 750 // in process, request browser demuxer seek so the new decoder will decode
741 // an I-frame first. Otherwise, the new MediaCodec might crash. See b/8950387. 751 // an I-frame first. Otherwise, the new MediaCodec might crash. See b/8950387.
752 // Eventual OnDemuxerSeekDone() will trigger ProcessPendingEvents() and
753 // continue from here.
742 // TODO(wolenetz): Instead of doing hack browser seek, replay cached data 754 // TODO(wolenetz): Instead of doing hack browser seek, replay cached data
743 // since last keyframe. See http://crbug.com/304234. 755 // since last keyframe. See http://crbug.com/304234.
744 if (!next_video_data_is_iframe_ && !IsEventPending(SEEK_EVENT_PENDING)) { 756 if (!next_video_data_is_iframe_ && !IsEventPending(SEEK_EVENT_PENDING)) {
745 BrowserSeekToCurrentTime(); 757 BrowserSeekToCurrentTime();
746 return; 758 return;
747 } 759 }
748 760
761 // Release the old VideoDecoderJob first so the surface can get released.
762 // Android does not allow 2 MediaCodec instances use the same surface.
763 ResetVideoDecoderJob();
764
749 base::android::ScopedJavaLocalRef<jobject> media_crypto = GetMediaCrypto(); 765 base::android::ScopedJavaLocalRef<jobject> media_crypto = GetMediaCrypto();
750 if (is_video_encrypted_ && media_crypto.is_null()) 766 if (is_video_encrypted_ && media_crypto.is_null())
751 return; 767 return;
752 768
753 DCHECK(!video_decoder_job_ || !video_decoder_job_->is_decoding());
754
755 DVLOG(1) << __FUNCTION__ << " : creating new video decoder job"; 769 DVLOG(1) << __FUNCTION__ << " : creating new video decoder job";
756 770
757 // Release the old VideoDecoderJob first so the surface can get released.
758 // Android does not allow 2 MediaCodec instances use the same surface.
759 video_decoder_job_.reset();
760 // Create the new VideoDecoderJob. 771 // Create the new VideoDecoderJob.
761 bool is_secure = IsProtectedSurfaceRequired(); 772 bool is_secure = IsProtectedSurfaceRequired();
762 video_decoder_job_.reset( 773 video_decoder_job_.reset(
763 VideoDecoderJob::Create(video_codec_, 774 VideoDecoderJob::Create(video_codec_,
764 is_secure, 775 is_secure,
765 gfx::Size(width_, height_), 776 gfx::Size(width_, height_),
766 surface_.j_surface().obj(), 777 surface_.j_surface().obj(),
767 media_crypto.obj(), 778 media_crypto.obj(),
768 base::Bind(&DemuxerAndroid::RequestDemuxerData, 779 base::Bind(&DemuxerAndroid::RequestDemuxerData,
769 base::Unretained(demuxer_.get()), 780 base::Unretained(demuxer_.get()),
770 DemuxerStream::VIDEO))); 781 DemuxerStream::VIDEO)));
771 if (video_decoder_job_) { 782 if (video_decoder_job_) {
acolwell GONE FROM CHROMIUM 2013/10/31 21:45:08 nit: reverse condition and return early.
wolenetz 2013/11/02 00:00:57 Done. This is a pattern I'll start watching for mo
772 video_decoder_job_->BeginPrerolling(preroll_timestamp_); 783 video_decoder_job_->BeginPrerolling(preroll_timestamp_);
773 reconfig_video_decoder_ = false; 784 reconfig_video_decoder_ = false;
785
786 // Inform the fullscreen view the player is ready.
787 // TODO(qinmin): refactor MediaPlayerBridge so that we have a better way
788 // to inform ContentVideoView.
789 manager()->OnMediaMetadataChanged(
790 player_id(), duration_, width_, height_, true);
774 } 791 }
775
776 if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING))
777 ClearPendingEvent(SURFACE_CHANGE_EVENT_PENDING);
778
779 // Inform the fullscreen view the player is ready.
780 // TODO(qinmin): refactor MediaPlayerBridge so that we have a better way
781 // to inform ContentVideoView.
782 manager()->OnMediaMetadataChanged(
783 player_id(), duration_, width_, height_, true);
784 } 792 }
785 793
786 void MediaSourcePlayer::OnDecoderStarved() { 794 void MediaSourcePlayer::OnDecoderStarved() {
787 DVLOG(1) << __FUNCTION__; 795 DVLOG(1) << __FUNCTION__;
788 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); 796 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
789 ProcessPendingEvents(); 797 ProcessPendingEvents();
790 } 798 }
791 799
792 void MediaSourcePlayer::StartStarvationCallback( 800 void MediaSourcePlayer::StartStarvationCallback(
793 const base::TimeDelta& presentation_timestamp) { 801 const base::TimeDelta& presentation_timestamp) {
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 895
888 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) { 896 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) {
889 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")"; 897 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")";
890 DCHECK_NE(event, NO_EVENT_PENDING); 898 DCHECK_NE(event, NO_EVENT_PENDING);
891 DCHECK(IsEventPending(event)) << GetEventName(event); 899 DCHECK(IsEventPending(event)) << GetEventName(event);
892 900
893 pending_event_ &= ~event; 901 pending_event_ &= ~event;
894 } 902 }
895 903
896 } // namespace media 904 } // namespace media
OLDNEW
« no previous file with comments | « media/base/android/media_source_player.h ('k') | media/base/android/media_source_player_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698