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

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: add more unit test coverage 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 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 base::TimeDelta MediaSourcePlayer::GetCurrentTime() { 223 base::TimeDelta MediaSourcePlayer::GetCurrentTime() {
224 return clock_.Elapsed(); 224 return clock_.Elapsed();
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
234 // Allow SEEK_EVENT_PENDING and CONFIG_CHANGE_EVENT_PENDING to survive the
235 // Release(). Clear all others. If PREFETCH_DONE_EVENT_PENDING was previously
236 // pending, or a job was still decoding, then at end of Release() we need to
237 // ProcessPendingEvents() since seek or config change would not otherwise be
238 // processed.
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 if (IsEventPending(SEEK_EVENT_PENDING) ||
qinmin 2013/10/30 23:07:48 No need for this if statement, processPendingEvent
wolenetz 2013/10/31 01:39:11 Excellent point, thank you. Done.
244 IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) {
245 process_pending_events = IsEventPending(PREFETCH_DONE_EVENT_PENDING) ||
246 (audio_decoder_job_ && audio_decoder_job_->is_decoding()) ||
247 (video_decoder_job_ && video_decoder_job_->is_decoding());
248 }
249 if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING))
acolwell GONE FROM CHROMIUM 2013/10/30 23:29:53 nit: How about the following instead: // Clear al
wolenetz 2013/10/31 01:39:11 Done. I was trying to keep the raw pending_event_
250 ClearPendingEvent(SURFACE_CHANGE_EVENT_PENDING);
251 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING))
252 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
253 if (IsEventPending(PREFETCH_DONE_EVENT_PENDING))
254 ClearPendingEvent(PREFETCH_DONE_EVENT_PENDING);
255
233 audio_decoder_job_.reset(); 256 audio_decoder_job_.reset();
234 video_decoder_job_.reset(); 257 video_decoder_job_.reset();
258
259 // Prevent job re-creation attempts in OnDemuxerConfigsAvailable()
235 reconfig_audio_decoder_ = false; 260 reconfig_audio_decoder_ = false;
236 reconfig_video_decoder_ = false; 261 reconfig_video_decoder_ = false;
262
263 // Prevent player restart, including job re-creation attempts.
237 playing_ = false; 264 playing_ = false;
238 pending_event_ = NO_EVENT_PENDING; 265
239 decoder_starvation_callback_.Cancel(); 266 decoder_starvation_callback_.Cancel();
240 surface_ = gfx::ScopedJavaSurface(); 267 surface_ = gfx::ScopedJavaSurface();
241 manager()->ReleaseMediaResources(player_id()); 268 manager()->ReleaseMediaResources(player_id());
269 if (process_pending_events) {
270 DVLOG(1) << __FUNCTION__ << " : Resuming seek or config change processing";
271 ProcessPendingEvents();
272 }
242 } 273 }
243 274
244 void MediaSourcePlayer::SetVolume(double volume) { 275 void MediaSourcePlayer::SetVolume(double volume) {
245 volume_ = volume; 276 volume_ = volume;
246 SetVolumeInternal(); 277 SetVolumeInternal();
247 } 278 }
248 279
249 void MediaSourcePlayer::OnKeyAdded() { 280 void MediaSourcePlayer::OnKeyAdded() {
250 DVLOG(1) << __FUNCTION__; 281 DVLOG(1) << __FUNCTION__;
251 if (!is_waiting_for_key_) 282 if (!is_waiting_for_key_)
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 "MediaCodecStatus", 573 "MediaCodecStatus",
543 base::IntToString(status)); 574 base::IntToString(status));
544 } else { 575 } else {
545 TRACE_EVENT_ASYNC_END1("media", 576 TRACE_EVENT_ASYNC_END1("media",
546 "MediaSourcePlayer::DecodeMoreVideo", 577 "MediaSourcePlayer::DecodeMoreVideo",
547 video_decoder_job_.get(), 578 video_decoder_job_.get(),
548 "MediaCodecStatus", 579 "MediaCodecStatus",
549 base::IntToString(status)); 580 base::IntToString(status));
550 } 581 }
551 582
583 // Let tests hook the completion of a decode cycle.
584 manager()->OnMediaDecoderCallbackForTesting();
585
552 bool is_clock_manager = is_audio || !HasAudio(); 586 bool is_clock_manager = is_audio || !HasAudio();
553 587
554 if (is_clock_manager) 588 if (is_clock_manager)
555 decoder_starvation_callback_.Cancel(); 589 decoder_starvation_callback_.Cancel();
556 590
557 if (status == MEDIA_CODEC_ERROR) { 591 if (status == MEDIA_CODEC_ERROR) {
592 DVLOG(1) << __FUNCTION__ << " : decode error";
558 Release(); 593 Release();
559 manager()->OnError(player_id(), MEDIA_ERROR_DECODE); 594 manager()->OnError(player_id(), MEDIA_ERROR_DECODE);
560 return; 595 return;
561 } 596 }
562 597
563 if (pending_event_ != NO_EVENT_PENDING) { 598 if (pending_event_ != NO_EVENT_PENDING) {
564 ProcessPendingEvents(); 599 ProcessPendingEvents();
565 return; 600 return;
566 } 601 }
567 602
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 863
829 bool MediaSourcePlayer::IsProtectedSurfaceRequired() { 864 bool MediaSourcePlayer::IsProtectedSurfaceRequired() {
830 return is_video_encrypted_ && 865 return is_video_encrypted_ &&
831 drm_bridge_ && drm_bridge_->IsProtectedSurfaceRequired(); 866 drm_bridge_ && drm_bridge_->IsProtectedSurfaceRequired();
832 } 867 }
833 868
834 void MediaSourcePlayer::OnPrefetchDone() { 869 void MediaSourcePlayer::OnPrefetchDone() {
835 DVLOG(1) << __FUNCTION__; 870 DVLOG(1) << __FUNCTION__;
836 DCHECK(!audio_decoder_job_ || !audio_decoder_job_->is_decoding()); 871 DCHECK(!audio_decoder_job_ || !audio_decoder_job_->is_decoding());
837 DCHECK(!video_decoder_job_ || !video_decoder_job_->is_decoding()); 872 DCHECK(!video_decoder_job_ || !video_decoder_job_->is_decoding());
838 DCHECK(IsEventPending(PREFETCH_DONE_EVENT_PENDING)); 873
874 // A previously posted OnPrefetchDone() could race against a Release(). If
875 // Release() won the race, we should no longer have decoder jobs.
876 // TODO(qinmin/wolenetz): Maintain channel state to not double-request data
877 // or drop data received across Release()+Start(). See http://crbug.com/306314
878 // and http://crbug.com/304234.
879 if (!IsEventPending(PREFETCH_DONE_EVENT_PENDING)) {
880 DVLOG(1) << __FUNCTION__ << " : aborting";
881 DCHECK(!audio_decoder_job_ && !video_decoder_job_);
882 return;
883 }
839 884
840 ClearPendingEvent(PREFETCH_DONE_EVENT_PENDING); 885 ClearPendingEvent(PREFETCH_DONE_EVENT_PENDING);
841 886
842 if (pending_event_ != NO_EVENT_PENDING) { 887 if (pending_event_ != NO_EVENT_PENDING) {
843 ProcessPendingEvents(); 888 ProcessPendingEvents();
844 return; 889 return;
845 } 890 }
846 891
847 start_time_ticks_ = base::TimeTicks::Now(); 892 start_time_ticks_ = base::TimeTicks::Now();
848 start_presentation_timestamp_ = GetCurrentTime(); 893 start_presentation_timestamp_ = GetCurrentTime();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 932
888 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) { 933 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) {
889 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")"; 934 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")";
890 DCHECK_NE(event, NO_EVENT_PENDING); 935 DCHECK_NE(event, NO_EVENT_PENDING);
891 DCHECK(IsEventPending(event)) << GetEventName(event); 936 DCHECK(IsEventPending(event)) << GetEventName(event);
892 937
893 pending_event_ &= ~event; 938 pending_event_ &= ~event;
894 } 939 }
895 940
896 } // namespace media 941 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698