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 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 |