Chromium Code Reviews| Index: media/base/android/media_source_player.cc |
| diff --git a/media/base/android/media_source_player.cc b/media/base/android/media_source_player.cc |
| index 8e23a91629331fc6f8df18098a23ee69d37915d2..8be8691a62829ae354587c5e258ce69f221ab527 100644 |
| --- a/media/base/android/media_source_player.cc |
| +++ b/media/base/android/media_source_player.cc |
| @@ -232,9 +232,17 @@ void MediaSourcePlayer::Release() { |
| DVLOG(1) << __FUNCTION__; |
| audio_decoder_job_.reset(); |
| video_decoder_job_.reset(); |
| + |
| + // Prevent job re-creation attempts in OnDemuxerConfigsAvailable() |
| reconfig_audio_decoder_ = false; |
| reconfig_video_decoder_ = false; |
| + |
| + // Prevent player restart, including job re-creation attempts. |
| playing_ = false; |
| + |
| + // TODO(qinmin/wolenetz): Maintain channel state to not double-request data |
| + // or drop data received across Release()+Start(). See http://crbug.com/306314 |
| + // and http://crbug.com/304234. |
| pending_event_ = NO_EVENT_PENDING; |
| decoder_starvation_callback_.Cancel(); |
| surface_ = gfx::ScopedJavaSurface(); |
| @@ -549,12 +557,16 @@ void MediaSourcePlayer::MediaDecoderCallback( |
| base::IntToString(status)); |
| } |
| + // Let tests hook the completion of a decode cycle. |
| + manager()->OnMediaDecoderCallback(); |
| + |
| bool is_clock_manager = is_audio || !HasAudio(); |
| if (is_clock_manager) |
| decoder_starvation_callback_.Cancel(); |
| if (status == MEDIA_CODEC_ERROR) { |
| + DVLOG(1) << __FUNCTION__ << " : decode error"; |
| Release(); |
| manager()->OnError(player_id(), MEDIA_ERROR_DECODE); |
| return; |
| @@ -835,7 +847,20 @@ void MediaSourcePlayer::OnPrefetchDone() { |
| DVLOG(1) << __FUNCTION__; |
| DCHECK(!audio_decoder_job_ || !audio_decoder_job_->is_decoding()); |
| DCHECK(!video_decoder_job_ || !video_decoder_job_->is_decoding()); |
| - DCHECK(IsEventPending(PREFETCH_DONE_EVENT_PENDING)); |
| + |
| + // A previously posted OnPrefetchDone() could race against a Release(). If |
| + // Release() won the race, we should no longer have decoder jobs and should |
| + // just process any other pending events. |
| + // TODO(qinmin/wolenetz): Maintain channel state to not double-request data |
| + // or drop data received across Release()+Start(). See http://crbug.com/306314 |
| + // and http://crbug.com/304234. |
| + if (!IsEventPending(PREFETCH_DONE_EVENT_PENDING)) { |
| + DVLOG(1) << __FUNCTION__ << " : aborting"; |
| + DCHECK(!audio_decoder_job_ && !video_decoder_job_); |
| + if (pending_event_ != NO_EVENT_PENDING) |
| + 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
|
| + return; |
| + } |
| ClearPendingEvent(PREFETCH_DONE_EVENT_PENDING); |