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

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

Issue 51613002: Abort MSP::OnPrefetchDone() if just after MSP::Release(). Let seek and config change survive. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments and nits from PS7 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"
11 #include "base/barrier_closure.h" 11 #include "base/barrier_closure.h"
12 #include "base/basictypes.h" 12 #include "base/basictypes.h"
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/callback_helpers.h"
14 #include "base/debug/trace_event.h" 15 #include "base/debug/trace_event.h"
15 #include "base/logging.h" 16 #include "base/logging.h"
16 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
17 #include "media/base/android/audio_decoder_job.h" 18 #include "media/base/android/audio_decoder_job.h"
18 #include "media/base/android/media_drm_bridge.h" 19 #include "media/base/android/media_drm_bridge.h"
19 #include "media/base/android/media_player_manager.h" 20 #include "media/base/android/media_player_manager.h"
20 #include "media/base/android/video_decoder_job.h" 21 #include "media/base/android/video_decoder_job.h"
21 #include "media/base/audio_timestamp_helper.h" 22 #include "media/base/audio_timestamp_helper.h"
22 #include "media/base/buffers.h" 23 #include "media/base/buffers.h"
23 24
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 base::TimeDelta MediaSourcePlayer::GetCurrentTime() { 224 base::TimeDelta MediaSourcePlayer::GetCurrentTime() {
224 return clock_.Elapsed(); 225 return clock_.Elapsed();
225 } 226 }
226 227
227 base::TimeDelta MediaSourcePlayer::GetDuration() { 228 base::TimeDelta MediaSourcePlayer::GetDuration() {
228 return duration_; 229 return duration_;
229 } 230 }
230 231
231 void MediaSourcePlayer::Release() { 232 void MediaSourcePlayer::Release() {
232 DVLOG(1) << __FUNCTION__; 233 DVLOG(1) << __FUNCTION__;
234
235 // Allow pending seeks and config changes to survive this Release().
236 // If previously pending a prefetch done event, or a job was still decoding,
237 // then at end of Release() we need to ProcessPendingEvents() to process any
238 // seek or config change that was blocked by the prefetch or decode.
239 // TODO(qinmin/wolenetz): Maintain channel state to not double-request data
240 // or drop data received across Release()+Start(). See http://crbug.com/306314
241 // and http://crbug.com/304234.
242 bool process_pending_events = false;
243 process_pending_events = IsEventPending(PREFETCH_DONE_EVENT_PENDING) ||
244 (audio_decoder_job_ && audio_decoder_job_->is_decoding()) ||
245 (video_decoder_job_ && video_decoder_job_->is_decoding());
246
247 // Clear all the pending events except seeks and config changes.
248 pending_event_ &= (SEEK_EVENT_PENDING | CONFIG_CHANGE_EVENT_PENDING);
249
233 audio_decoder_job_.reset(); 250 audio_decoder_job_.reset();
234 video_decoder_job_.reset(); 251 video_decoder_job_.reset();
252
253 // Prevent job re-creation attempts in OnDemuxerConfigsAvailable()
235 reconfig_audio_decoder_ = false; 254 reconfig_audio_decoder_ = false;
236 reconfig_video_decoder_ = false; 255 reconfig_video_decoder_ = false;
256
257 // Prevent player restart, including job re-creation attempts.
237 playing_ = false; 258 playing_ = false;
238 pending_event_ = NO_EVENT_PENDING; 259
239 decoder_starvation_callback_.Cancel(); 260 decoder_starvation_callback_.Cancel();
240 surface_ = gfx::ScopedJavaSurface(); 261 surface_ = gfx::ScopedJavaSurface();
241 manager()->ReleaseMediaResources(player_id()); 262 manager()->ReleaseMediaResources(player_id());
263 if (process_pending_events) {
264 DVLOG(1) << __FUNCTION__ << " : Resuming seek or config change processing";
265 ProcessPendingEvents();
266 }
242 } 267 }
243 268
244 void MediaSourcePlayer::SetVolume(double volume) { 269 void MediaSourcePlayer::SetVolume(double volume) {
245 volume_ = volume; 270 volume_ = volume;
246 SetVolumeInternal(); 271 SetVolumeInternal();
247 } 272 }
248 273
249 void MediaSourcePlayer::OnKeyAdded() { 274 void MediaSourcePlayer::OnKeyAdded() {
250 DVLOG(1) << __FUNCTION__; 275 DVLOG(1) << __FUNCTION__;
251 if (!is_waiting_for_key_) 276 if (!is_waiting_for_key_)
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 "MediaCodecStatus", 567 "MediaCodecStatus",
543 base::IntToString(status)); 568 base::IntToString(status));
544 } else { 569 } else {
545 TRACE_EVENT_ASYNC_END1("media", 570 TRACE_EVENT_ASYNC_END1("media",
546 "MediaSourcePlayer::DecodeMoreVideo", 571 "MediaSourcePlayer::DecodeMoreVideo",
547 video_decoder_job_.get(), 572 video_decoder_job_.get(),
548 "MediaCodecStatus", 573 "MediaCodecStatus",
549 base::IntToString(status)); 574 base::IntToString(status));
550 } 575 }
551 576
577 // Let tests hook the completion of this decode cycle.
578 if (!decode_callback_for_testing_.is_null())
579 base::ResetAndReturn(&decode_callback_for_testing_).Run();
580
552 bool is_clock_manager = is_audio || !HasAudio(); 581 bool is_clock_manager = is_audio || !HasAudio();
553 582
554 if (is_clock_manager) 583 if (is_clock_manager)
555 decoder_starvation_callback_.Cancel(); 584 decoder_starvation_callback_.Cancel();
556 585
557 if (status == MEDIA_CODEC_ERROR) { 586 if (status == MEDIA_CODEC_ERROR) {
587 DVLOG(1) << __FUNCTION__ << " : decode error";
558 Release(); 588 Release();
559 manager()->OnError(player_id(), MEDIA_ERROR_DECODE); 589 manager()->OnError(player_id(), MEDIA_ERROR_DECODE);
560 return; 590 return;
561 } 591 }
562 592
563 if (pending_event_ != NO_EVENT_PENDING) { 593 if (pending_event_ != NO_EVENT_PENDING) {
564 ProcessPendingEvents(); 594 ProcessPendingEvents();
565 return; 595 return;
566 } 596 }
567 597
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 858
829 bool MediaSourcePlayer::IsProtectedSurfaceRequired() { 859 bool MediaSourcePlayer::IsProtectedSurfaceRequired() {
830 return is_video_encrypted_ && 860 return is_video_encrypted_ &&
831 drm_bridge_ && drm_bridge_->IsProtectedSurfaceRequired(); 861 drm_bridge_ && drm_bridge_->IsProtectedSurfaceRequired();
832 } 862 }
833 863
834 void MediaSourcePlayer::OnPrefetchDone() { 864 void MediaSourcePlayer::OnPrefetchDone() {
835 DVLOG(1) << __FUNCTION__; 865 DVLOG(1) << __FUNCTION__;
836 DCHECK(!audio_decoder_job_ || !audio_decoder_job_->is_decoding()); 866 DCHECK(!audio_decoder_job_ || !audio_decoder_job_->is_decoding());
837 DCHECK(!video_decoder_job_ || !video_decoder_job_->is_decoding()); 867 DCHECK(!video_decoder_job_ || !video_decoder_job_->is_decoding());
838 DCHECK(IsEventPending(PREFETCH_DONE_EVENT_PENDING)); 868
869 // A previously posted OnPrefetchDone() could race against a Release(). If
870 // Release() won the race, we should no longer have decoder jobs.
871 // TODO(qinmin/wolenetz): Maintain channel state to not double-request data
872 // or drop data received across Release()+Start(). See http://crbug.com/306314
873 // and http://crbug.com/304234.
874 if (!IsEventPending(PREFETCH_DONE_EVENT_PENDING)) {
875 DVLOG(1) << __FUNCTION__ << " : aborting";
876 DCHECK(!audio_decoder_job_ && !video_decoder_job_);
877 return;
878 }
839 879
840 ClearPendingEvent(PREFETCH_DONE_EVENT_PENDING); 880 ClearPendingEvent(PREFETCH_DONE_EVENT_PENDING);
841 881
842 if (pending_event_ != NO_EVENT_PENDING) { 882 if (pending_event_ != NO_EVENT_PENDING) {
843 ProcessPendingEvents(); 883 ProcessPendingEvents();
844 return; 884 return;
845 } 885 }
846 886
847 start_time_ticks_ = base::TimeTicks::Now(); 887 start_time_ticks_ = base::TimeTicks::Now();
848 start_presentation_timestamp_ = GetCurrentTime(); 888 start_presentation_timestamp_ = GetCurrentTime();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 927
888 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) { 928 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) {
889 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")"; 929 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")";
890 DCHECK_NE(event, NO_EVENT_PENDING); 930 DCHECK_NE(event, NO_EVENT_PENDING);
891 DCHECK(IsEventPending(event)) << GetEventName(event); 931 DCHECK(IsEventPending(event)) << GetEventName(event);
892 932
893 pending_event_ &= ~event; 933 pending_event_ &= ~event;
894 } 934 }
895 935
896 } // namespace media 936 } // 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