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 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 video_decoder_job_.reset(); |
235 | |
236 // Prevent job re-creation attempts in OnDemuxerConfigsAvailable() | |
235 reconfig_audio_decoder_ = false; | 237 reconfig_audio_decoder_ = false; |
236 reconfig_video_decoder_ = false; | 238 reconfig_video_decoder_ = false; |
239 | |
240 // Prevent player restart, including job re-creation attempts. | |
237 playing_ = false; | 241 playing_ = false; |
242 | |
243 // TODO(qinmin/wolenetz): Maintain channel state to not double-request data | |
244 // or drop data received across Release()+Start(). See http://crbug.com/306314 | |
245 // and http://crbug.com/304234. | |
238 pending_event_ = NO_EVENT_PENDING; | 246 pending_event_ = NO_EVENT_PENDING; |
239 decoder_starvation_callback_.Cancel(); | 247 decoder_starvation_callback_.Cancel(); |
240 surface_ = gfx::ScopedJavaSurface(); | 248 surface_ = gfx::ScopedJavaSurface(); |
241 manager()->ReleaseMediaResources(player_id()); | 249 manager()->ReleaseMediaResources(player_id()); |
242 } | 250 } |
243 | 251 |
244 void MediaSourcePlayer::SetVolume(double volume) { | 252 void MediaSourcePlayer::SetVolume(double volume) { |
245 volume_ = volume; | 253 volume_ = volume; |
246 SetVolumeInternal(); | 254 SetVolumeInternal(); |
247 } | 255 } |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
542 "MediaCodecStatus", | 550 "MediaCodecStatus", |
543 base::IntToString(status)); | 551 base::IntToString(status)); |
544 } else { | 552 } else { |
545 TRACE_EVENT_ASYNC_END1("media", | 553 TRACE_EVENT_ASYNC_END1("media", |
546 "MediaSourcePlayer::DecodeMoreVideo", | 554 "MediaSourcePlayer::DecodeMoreVideo", |
547 video_decoder_job_.get(), | 555 video_decoder_job_.get(), |
548 "MediaCodecStatus", | 556 "MediaCodecStatus", |
549 base::IntToString(status)); | 557 base::IntToString(status)); |
550 } | 558 } |
551 | 559 |
560 // Let tests hook the completion of a decode cycle. | |
561 manager()->OnMediaDecoderCallback(); | |
562 | |
552 bool is_clock_manager = is_audio || !HasAudio(); | 563 bool is_clock_manager = is_audio || !HasAudio(); |
553 | 564 |
554 if (is_clock_manager) | 565 if (is_clock_manager) |
555 decoder_starvation_callback_.Cancel(); | 566 decoder_starvation_callback_.Cancel(); |
556 | 567 |
557 if (status == MEDIA_CODEC_ERROR) { | 568 if (status == MEDIA_CODEC_ERROR) { |
569 DVLOG(1) << __FUNCTION__ << " : decode error"; | |
558 Release(); | 570 Release(); |
559 manager()->OnError(player_id(), MEDIA_ERROR_DECODE); | 571 manager()->OnError(player_id(), MEDIA_ERROR_DECODE); |
560 return; | 572 return; |
561 } | 573 } |
562 | 574 |
563 if (pending_event_ != NO_EVENT_PENDING) { | 575 if (pending_event_ != NO_EVENT_PENDING) { |
564 ProcessPendingEvents(); | 576 ProcessPendingEvents(); |
565 return; | 577 return; |
566 } | 578 } |
567 | 579 |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
828 | 840 |
829 bool MediaSourcePlayer::IsProtectedSurfaceRequired() { | 841 bool MediaSourcePlayer::IsProtectedSurfaceRequired() { |
830 return is_video_encrypted_ && | 842 return is_video_encrypted_ && |
831 drm_bridge_ && drm_bridge_->IsProtectedSurfaceRequired(); | 843 drm_bridge_ && drm_bridge_->IsProtectedSurfaceRequired(); |
832 } | 844 } |
833 | 845 |
834 void MediaSourcePlayer::OnPrefetchDone() { | 846 void MediaSourcePlayer::OnPrefetchDone() { |
835 DVLOG(1) << __FUNCTION__; | 847 DVLOG(1) << __FUNCTION__; |
836 DCHECK(!audio_decoder_job_ || !audio_decoder_job_->is_decoding()); | 848 DCHECK(!audio_decoder_job_ || !audio_decoder_job_->is_decoding()); |
837 DCHECK(!video_decoder_job_ || !video_decoder_job_->is_decoding()); | 849 DCHECK(!video_decoder_job_ || !video_decoder_job_->is_decoding()); |
838 DCHECK(IsEventPending(PREFETCH_DONE_EVENT_PENDING)); | 850 |
851 // A previously posted OnPrefetchDone() could race against a Release(). If | |
852 // Release() won the race, we should no longer have decoder jobs and should | |
853 // just process any other pending events. | |
854 // TODO(qinmin/wolenetz): Maintain channel state to not double-request data | |
855 // or drop data received across Release()+Start(). See http://crbug.com/306314 | |
856 // and http://crbug.com/304234. | |
857 if (!IsEventPending(PREFETCH_DONE_EVENT_PENDING)) { | |
858 DVLOG(1) << __FUNCTION__ << " : aborting"; | |
859 DCHECK(!audio_decoder_job_ && !video_decoder_job_); | |
860 if (pending_event_ != NO_EVENT_PENDING) | |
861 ProcessPendingEvents(); | |
qinmin
2013/10/29 23:49:34
Do we really need to process the pending events? i
wolenetz
2013/10/30 00:06:45
Suppose we had prefetch done pending when those ot
qinmin
2013/10/30 00:14:40
But release() will clear the pending_event_, so th
| |
862 return; | |
863 } | |
839 | 864 |
840 ClearPendingEvent(PREFETCH_DONE_EVENT_PENDING); | 865 ClearPendingEvent(PREFETCH_DONE_EVENT_PENDING); |
841 | 866 |
842 if (pending_event_ != NO_EVENT_PENDING) { | 867 if (pending_event_ != NO_EVENT_PENDING) { |
843 ProcessPendingEvents(); | 868 ProcessPendingEvents(); |
844 return; | 869 return; |
845 } | 870 } |
846 | 871 |
847 start_time_ticks_ = base::TimeTicks::Now(); | 872 start_time_ticks_ = base::TimeTicks::Now(); |
848 start_presentation_timestamp_ = GetCurrentTime(); | 873 start_presentation_timestamp_ = GetCurrentTime(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
887 | 912 |
888 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) { | 913 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) { |
889 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")"; | 914 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")"; |
890 DCHECK_NE(event, NO_EVENT_PENDING); | 915 DCHECK_NE(event, NO_EVENT_PENDING); |
891 DCHECK(IsEventPending(event)) << GetEventName(event); | 916 DCHECK(IsEventPending(event)) << GetEventName(event); |
892 | 917 |
893 pending_event_ &= ~event; | 918 pending_event_ &= ~event; |
894 } | 919 } |
895 | 920 |
896 } // namespace media | 921 } // namespace media |
OLD | NEW |