Chromium Code Reviews| 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 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 316 audio_timestamp_helper_->SetBaseTimestamp(GetCurrentTime()); | 316 audio_timestamp_helper_->SetBaseTimestamp(GetCurrentTime()); |
| 317 } else { | 317 } else { |
| 318 audio_timestamp_helper_.reset(); | 318 audio_timestamp_helper_.reset(); |
| 319 } | 319 } |
| 320 | 320 |
| 321 video_codec_ = configs.video_codec; | 321 video_codec_ = configs.video_codec; |
| 322 width_ = configs.video_size.width(); | 322 width_ = configs.video_size.width(); |
| 323 height_ = configs.video_size.height(); | 323 height_ = configs.video_size.height(); |
| 324 is_video_encrypted_ = configs.is_video_encrypted; | 324 is_video_encrypted_ = configs.is_video_encrypted; |
| 325 | 325 |
| 326 manager()->OnMediaMetadataChanged( | 326 manager()->OnMediaMetadataChanged( |
|
wolenetz
2013/10/31 20:34:24
Note, this already occurs prior to |video_decoder_
| |
| 327 player_id(), duration_, width_, height_, true); | 327 player_id(), duration_, width_, height_, true); |
| 328 | 328 |
| 329 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) { | 329 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) { |
| 330 if (reconfig_audio_decoder_) | 330 if (reconfig_audio_decoder_) |
| 331 ConfigureAudioDecoderJob(); | 331 ConfigureAudioDecoderJob(); |
| 332 | 332 |
| 333 if (reconfig_video_decoder_) | 333 if (reconfig_video_decoder_) |
| 334 ConfigureVideoDecoderJob(); | 334 ConfigureVideoDecoderJob(); |
| 335 | 335 |
| 336 ClearPendingEvent(CONFIG_CHANGE_EVENT_PENDING); | 336 ClearPendingEvent(CONFIG_CHANGE_EVENT_PENDING); |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 720 | 720 |
| 721 void MediaSourcePlayer::ConfigureVideoDecoderJob() { | 721 void MediaSourcePlayer::ConfigureVideoDecoderJob() { |
| 722 if (!HasVideo() || surface_.IsEmpty()) { | 722 if (!HasVideo() || surface_.IsEmpty()) { |
| 723 video_decoder_job_.reset(); | 723 video_decoder_job_.reset(); |
| 724 if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING)) | 724 if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING)) |
| 725 ClearPendingEvent(SURFACE_CHANGE_EVENT_PENDING); | 725 ClearPendingEvent(SURFACE_CHANGE_EVENT_PENDING); |
| 726 return; | 726 return; |
| 727 } | 727 } |
| 728 | 728 |
| 729 // Create video decoder job only if config changes or we don't have a job. | 729 // Create video decoder job only if config changes or we don't have a job. |
| 730 if (video_decoder_job_ && !reconfig_video_decoder_) | 730 if (video_decoder_job_ && !reconfig_video_decoder_) { |
| 731 DCHECK(!IsEventPending(SURFACE_CHANGE_EVENT_PENDING)); | |
| 731 return; | 732 return; |
| 733 } | |
| 732 | 734 |
| 733 if (reconfig_video_decoder_) { | 735 if (reconfig_video_decoder_) { |
| 734 // No hack browser seek should be required. I-Frame must be next. | 736 // No hack browser seek should be required. I-Frame must be next. |
| 735 DCHECK(next_video_data_is_iframe_) << "Received video data between " | 737 DCHECK(next_video_data_is_iframe_) << "Received video data between " |
| 736 << "detecting video config change and reconfiguring video decoder"; | 738 << "detecting video config change and reconfiguring video decoder"; |
| 737 } | 739 } |
| 738 | 740 |
| 741 DCHECK(!video_decoder_job_ || !video_decoder_job_->is_decoding()); | |
| 742 | |
| 739 // If uncertain that video I-frame data is next and there is no seek already | 743 // 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 | 744 // 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. | 745 // an I-frame first. Otherwise, the new MediaCodec might crash. See b/8950387. |
| 746 // Eventual OnDemuxerSeekDone() will trigger ProcessPendingEvents() and | |
| 747 // continue from here. | |
| 742 // TODO(wolenetz): Instead of doing hack browser seek, replay cached data | 748 // TODO(wolenetz): Instead of doing hack browser seek, replay cached data |
| 743 // since last keyframe. See http://crbug.com/304234. | 749 // since last keyframe. See http://crbug.com/304234. |
| 744 if (!next_video_data_is_iframe_ && !IsEventPending(SEEK_EVENT_PENDING)) { | 750 if (!next_video_data_is_iframe_ && !IsEventPending(SEEK_EVENT_PENDING)) { |
| 745 BrowserSeekToCurrentTime(); | 751 BrowserSeekToCurrentTime(); |
| 746 return; | 752 return; |
| 747 } | 753 } |
| 748 | 754 |
| 755 // Release the old VideoDecoderJob first so the surface can get released. | |
| 756 // Android does not allow 2 MediaCodec instances use the same surface. | |
| 757 video_decoder_job_.reset(); | |
| 758 | |
| 759 // Now that we have ensured the job is reset, clear any pending surface change | |
| 760 // event. If there was such an event, eventual job re-creation, below, will | |
| 761 // use the current |surface_|. | |
| 762 if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING)) | |
| 763 ClearPendingEvent(SURFACE_CHANGE_EVENT_PENDING); | |
| 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_) { |
| 772 video_decoder_job_->BeginPrerolling(preroll_timestamp_); | 783 video_decoder_job_->BeginPrerolling(preroll_timestamp_); |
| 773 reconfig_video_decoder_ = false; | 784 reconfig_video_decoder_ = false; |
| 774 } | 785 } |
| 775 | 786 |
| 776 if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING)) | |
| 777 ClearPendingEvent(SURFACE_CHANGE_EVENT_PENDING); | |
| 778 | |
| 779 // Inform the fullscreen view the player is ready. | 787 // Inform the fullscreen view the player is ready. |
| 780 // TODO(qinmin): refactor MediaPlayerBridge so that we have a better way | 788 // TODO(qinmin): refactor MediaPlayerBridge so that we have a better way |
| 781 // to inform ContentVideoView. | 789 // to inform ContentVideoView. |
| 782 manager()->OnMediaMetadataChanged( | 790 manager()->OnMediaMetadataChanged( |
| 783 player_id(), duration_, width_, height_, true); | 791 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); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 |
| OLD | NEW |