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

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: rebase 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 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 // and http://crbug.com/304234. 241 // and http://crbug.com/304234.
242 bool process_pending_events = false; 242 bool process_pending_events = false;
243 process_pending_events = IsEventPending(PREFETCH_DONE_EVENT_PENDING) || 243 process_pending_events = IsEventPending(PREFETCH_DONE_EVENT_PENDING) ||
244 (audio_decoder_job_ && audio_decoder_job_->is_decoding()) || 244 (audio_decoder_job_ && audio_decoder_job_->is_decoding()) ||
245 (video_decoder_job_ && video_decoder_job_->is_decoding()); 245 (video_decoder_job_ && video_decoder_job_->is_decoding());
246 246
247 // Clear all the pending events except seeks and config changes. 247 // Clear all the pending events except seeks and config changes.
248 pending_event_ &= (SEEK_EVENT_PENDING | CONFIG_CHANGE_EVENT_PENDING); 248 pending_event_ &= (SEEK_EVENT_PENDING | CONFIG_CHANGE_EVENT_PENDING);
249 249
250 audio_decoder_job_.reset(); 250 audio_decoder_job_.reset();
251 video_decoder_job_.reset(); 251 ResetVideoDecoderJob();
252 252
253 // Prevent job re-creation attempts in OnDemuxerConfigsAvailable() 253 // Prevent job re-creation attempts in OnDemuxerConfigsAvailable()
254 reconfig_audio_decoder_ = false; 254 reconfig_audio_decoder_ = false;
255 reconfig_video_decoder_ = false; 255 reconfig_video_decoder_ = false;
256 256
257 // Prevent player restart, including job re-creation attempts. 257 // Prevent player restart, including job re-creation attempts.
258 playing_ = false; 258 playing_ = false;
259 259
260 decoder_starvation_callback_.Cancel(); 260 decoder_starvation_callback_.Cancel();
261 surface_ = gfx::ScopedJavaSurface(); 261 surface_ = gfx::ScopedJavaSurface();
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) { 511 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) {
512 DVLOG(1) << __FUNCTION__ << " : Handling CONFIG_CHANGE_EVENT."; 512 DVLOG(1) << __FUNCTION__ << " : Handling CONFIG_CHANGE_EVENT.";
513 DCHECK(reconfig_audio_decoder_ || reconfig_video_decoder_); 513 DCHECK(reconfig_audio_decoder_ || reconfig_video_decoder_);
514 demuxer_->RequestDemuxerConfigs(); 514 demuxer_->RequestDemuxerConfigs();
515 return; 515 return;
516 } 516 }
517 517
518 if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING)) { 518 if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING)) {
519 DVLOG(1) << __FUNCTION__ << " : Handling SURFACE_CHANGE_EVENT."; 519 DVLOG(1) << __FUNCTION__ << " : Handling SURFACE_CHANGE_EVENT.";
520 // Setting a new surface will require a new MediaCodec to be created. 520 // Setting a new surface will require a new MediaCodec to be created.
521 video_decoder_job_.reset(); 521 ResetVideoDecoderJob();
522 ConfigureVideoDecoderJob(); 522 ConfigureVideoDecoderJob();
523 523
524 // Return early if we can't successfully configure a new video decoder job 524 // Return early if we can't successfully configure a new video decoder job
525 // yet, except continue processing other pending events if |surface_| is 525 // yet, except continue processing other pending events if |surface_| is
526 // empty. 526 // empty.
527 if (!video_decoder_job_ && !surface_.IsEmpty()) 527 if (!video_decoder_job_ && !surface_.IsEmpty())
528 return; 528 return;
529 } 529 }
530 530
531 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) { 531 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) {
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 base::Bind(&DemuxerAndroid::RequestDemuxerData, 741 base::Bind(&DemuxerAndroid::RequestDemuxerData,
742 base::Unretained(demuxer_.get()), DemuxerStream::AUDIO))); 742 base::Unretained(demuxer_.get()), DemuxerStream::AUDIO)));
743 743
744 if (audio_decoder_job_) { 744 if (audio_decoder_job_) {
745 SetVolumeInternal(); 745 SetVolumeInternal();
746 audio_decoder_job_->BeginPrerolling(preroll_timestamp_); 746 audio_decoder_job_->BeginPrerolling(preroll_timestamp_);
747 reconfig_audio_decoder_ = false; 747 reconfig_audio_decoder_ = false;
748 } 748 }
749 } 749 }
750 750
751 void MediaSourcePlayer::ResetVideoDecoderJob() {
752 video_decoder_job_.reset();
753
754 // Any eventual video decoder job re-creation will use the current |surface_|.
755 if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING))
756 ClearPendingEvent(SURFACE_CHANGE_EVENT_PENDING);
757 }
758
751 void MediaSourcePlayer::ConfigureVideoDecoderJob() { 759 void MediaSourcePlayer::ConfigureVideoDecoderJob() {
752 if (!HasVideo() || surface_.IsEmpty()) { 760 if (!HasVideo() || surface_.IsEmpty()) {
753 video_decoder_job_.reset(); 761 ResetVideoDecoderJob();
754 if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING))
755 ClearPendingEvent(SURFACE_CHANGE_EVENT_PENDING);
756 return; 762 return;
757 } 763 }
758 764
759 // Create video decoder job only if config changes or we don't have a job. 765 // Create video decoder job only if config changes or we don't have a job.
760 if (video_decoder_job_ && !reconfig_video_decoder_) 766 if (video_decoder_job_ && !reconfig_video_decoder_) {
767 DCHECK(!IsEventPending(SURFACE_CHANGE_EVENT_PENDING));
761 return; 768 return;
769 }
770
771 DCHECK(!video_decoder_job_ || !video_decoder_job_->is_decoding());
762 772
763 if (reconfig_video_decoder_) { 773 if (reconfig_video_decoder_) {
764 // No hack browser seek should be required. I-Frame must be next. 774 // No hack browser seek should be required. I-Frame must be next.
765 DCHECK(next_video_data_is_iframe_) << "Received video data between " 775 DCHECK(next_video_data_is_iframe_) << "Received video data between "
766 << "detecting video config change and reconfiguring video decoder"; 776 << "detecting video config change and reconfiguring video decoder";
767 } 777 }
768 778
769 // If uncertain that video I-frame data is next and there is no seek already 779 // If uncertain that video I-frame data is next and there is no seek already
770 // in process, request browser demuxer seek so the new decoder will decode 780 // in process, request browser demuxer seek so the new decoder will decode
771 // an I-frame first. Otherwise, the new MediaCodec might crash. See b/8950387. 781 // an I-frame first. Otherwise, the new MediaCodec might crash. See b/8950387.
782 // Eventual OnDemuxerSeekDone() will trigger ProcessPendingEvents() and
783 // continue from here.
772 // TODO(wolenetz): Instead of doing hack browser seek, replay cached data 784 // TODO(wolenetz): Instead of doing hack browser seek, replay cached data
773 // since last keyframe. See http://crbug.com/304234. 785 // since last keyframe. See http://crbug.com/304234.
774 if (!next_video_data_is_iframe_ && !IsEventPending(SEEK_EVENT_PENDING)) { 786 if (!next_video_data_is_iframe_ && !IsEventPending(SEEK_EVENT_PENDING)) {
775 BrowserSeekToCurrentTime(); 787 BrowserSeekToCurrentTime();
776 return; 788 return;
777 } 789 }
778 790
791 // Release the old VideoDecoderJob first so the surface can get released.
792 // Android does not allow 2 MediaCodec instances use the same surface.
793 ResetVideoDecoderJob();
794
779 base::android::ScopedJavaLocalRef<jobject> media_crypto = GetMediaCrypto(); 795 base::android::ScopedJavaLocalRef<jobject> media_crypto = GetMediaCrypto();
780 if (is_video_encrypted_ && media_crypto.is_null()) 796 if (is_video_encrypted_ && media_crypto.is_null())
781 return; 797 return;
782 798
783 DCHECK(!video_decoder_job_ || !video_decoder_job_->is_decoding());
784
785 DVLOG(1) << __FUNCTION__ << " : creating new video decoder job"; 799 DVLOG(1) << __FUNCTION__ << " : creating new video decoder job";
786 800
787 // Release the old VideoDecoderJob first so the surface can get released.
788 // Android does not allow 2 MediaCodec instances use the same surface.
789 video_decoder_job_.reset();
790 // Create the new VideoDecoderJob. 801 // Create the new VideoDecoderJob.
791 bool is_secure = IsProtectedSurfaceRequired(); 802 bool is_secure = IsProtectedSurfaceRequired();
792 video_decoder_job_.reset( 803 video_decoder_job_.reset(
793 VideoDecoderJob::Create(video_codec_, 804 VideoDecoderJob::Create(video_codec_,
794 is_secure, 805 is_secure,
795 gfx::Size(width_, height_), 806 gfx::Size(width_, height_),
796 surface_.j_surface().obj(), 807 surface_.j_surface().obj(),
797 media_crypto.obj(), 808 media_crypto.obj(),
798 base::Bind(&DemuxerAndroid::RequestDemuxerData, 809 base::Bind(&DemuxerAndroid::RequestDemuxerData,
799 base::Unretained(demuxer_.get()), 810 base::Unretained(demuxer_.get()),
800 DemuxerStream::VIDEO))); 811 DemuxerStream::VIDEO)));
801 if (video_decoder_job_) { 812 if (!video_decoder_job_)
802 video_decoder_job_->BeginPrerolling(preroll_timestamp_); 813 return;
803 reconfig_video_decoder_ = false;
804 }
805 814
806 if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING)) 815 video_decoder_job_->BeginPrerolling(preroll_timestamp_);
807 ClearPendingEvent(SURFACE_CHANGE_EVENT_PENDING); 816 reconfig_video_decoder_ = false;
808 817
809 // Inform the fullscreen view the player is ready. 818 // Inform the fullscreen view the player is ready.
810 // TODO(qinmin): refactor MediaPlayerBridge so that we have a better way 819 // TODO(qinmin): refactor MediaPlayerBridge so that we have a better way
811 // to inform ContentVideoView. 820 // to inform ContentVideoView.
812 manager()->OnMediaMetadataChanged( 821 manager()->OnMediaMetadataChanged(
813 player_id(), duration_, width_, height_, true); 822 player_id(), duration_, width_, height_, true);
814 } 823 }
815 824
816 void MediaSourcePlayer::OnDecoderStarved() { 825 void MediaSourcePlayer::OnDecoderStarved() {
817 DVLOG(1) << __FUNCTION__; 826 DVLOG(1) << __FUNCTION__;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
927 936
928 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) { 937 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) {
929 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")"; 938 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")";
930 DCHECK_NE(event, NO_EVENT_PENDING); 939 DCHECK_NE(event, NO_EVENT_PENDING);
931 DCHECK(IsEventPending(event)) << GetEventName(event); 940 DCHECK(IsEventPending(event)) << GetEventName(event);
932 941
933 pending_event_ &= ~event; 942 pending_event_ &= ~event;
934 } 943 }
935 944
936 } // namespace media 945 } // 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