Chromium Code Reviews| Index: media/filters/ffmpeg_audio_decoder.cc |
| diff --git a/media/filters/ffmpeg_audio_decoder.cc b/media/filters/ffmpeg_audio_decoder.cc |
| index a0e5889eff11aca7e6c84c6bdbf26080ca2fd8c0..47131c2863957d22ec482048fb50b9ef62724db0 100644 |
| --- a/media/filters/ffmpeg_audio_decoder.cc |
| +++ b/media/filters/ffmpeg_audio_decoder.cc |
| @@ -115,6 +115,8 @@ void FFmpegAudioDecoder::Read(const ReadCB& read_cb) { |
| DCHECK(task_runner_->BelongsToCurrentThread()); |
| DCHECK(!read_cb.is_null()); |
| CHECK(read_cb_.is_null()) << "Overlapping decodes are not supported."; |
| + DCHECK(stop_cb_.is_null()); |
| + DCHECK(reset_cb_.is_null()); |
|
xhwang
2014/01/10 22:14:15
nit: change the order of these two lines
|
| read_cb_ = BindToCurrentLoop(read_cb); |
| @@ -147,20 +149,28 @@ int FFmpegAudioDecoder::samples_per_second() { |
| void FFmpegAudioDecoder::Reset(const base::Closure& closure) { |
| DCHECK(task_runner_->BelongsToCurrentThread()); |
| - base::Closure reset_cb = BindToCurrentLoop(closure); |
| + reset_cb_ = BindToCurrentLoop(closure); |
| - avcodec_flush_buffers(codec_context_.get()); |
| - ResetTimestampState(); |
| - queued_audio_.clear(); |
| - reset_cb.Run(); |
| + if (read_cb_.is_null()) |
| + DoReset(); |
| + // Otherwise a demuxer read is pending, we'll wait until it finishes. |
| } |
| -FFmpegAudioDecoder::~FFmpegAudioDecoder() { |
| - // TODO(scherkus): should we require Stop() to be called? this might end up |
| - // getting called on a random thread due to refcounting. |
| - ReleaseFFmpegResources(); |
| +void FFmpegAudioDecoder::Stop(const base::Closure& closure) { |
| + DCHECK(task_runner_->BelongsToCurrentThread()); |
| + stop_cb_ = BindToCurrentLoop(closure); |
| + |
| + if (read_cb_.is_null()) { |
|
xhwang
2014/01/10 22:14:15
We like to check abnormal cases and return early.
|
| + if (!reset_cb_.is_null()) |
| + DoReset(); |
|
rileya (GONE FROM CHROMIUM)
2014/01/10 21:35:06
As-is I don't think(?) this will ever happen (Rese
xhwang
2014/01/10 22:14:15
That's correct. Feel free to DCHECK here :)
|
| + else |
| + DoStop(); |
| + } |
| + // Otherwise a demuxer read is pending, we'll wait until it finishes. |
| } |
| +FFmpegAudioDecoder::~FFmpegAudioDecoder() {} |
| + |
| int FFmpegAudioDecoder::GetAudioBuffer(AVCodecContext* codec, |
| AVFrame* frame, |
| int flags) { |
| @@ -226,6 +236,32 @@ int FFmpegAudioDecoder::GetAudioBuffer(AVCodecContext* codec, |
| return 0; |
| } |
| +void FFmpegAudioDecoder::DoStop() { |
| + DCHECK(task_runner_->BelongsToCurrentThread()); |
| + DCHECK(!stop_cb_.is_null()); |
| + DCHECK(read_cb_.is_null()); |
| + DCHECK(reset_cb_.is_null()); |
| + |
| + ResetTimestampState(); |
| + queued_audio_.clear(); |
| + ReleaseFFmpegResources(); |
| + base::ResetAndReturn(&stop_cb_).Run(); |
| +} |
| + |
| +void FFmpegAudioDecoder::DoReset() { |
| + DCHECK(task_runner_->BelongsToCurrentThread()); |
| + DCHECK(!reset_cb_.is_null()); |
| + DCHECK(read_cb_.is_null()); |
| + |
| + avcodec_flush_buffers(codec_context_.get()); |
| + ResetTimestampState(); |
| + queued_audio_.clear(); |
| + base::ResetAndReturn(&reset_cb_).Run(); |
| + |
| + if (!stop_cb_.is_null()) |
| + DoStop(); |
| +} |
| + |
| void FFmpegAudioDecoder::ReadFromDemuxerStream() { |
| DCHECK(!read_cb_.is_null()); |
| demuxer_stream_->Read(base::Bind( |
| @@ -240,6 +276,24 @@ void FFmpegAudioDecoder::BufferReady( |
| DCHECK(queued_audio_.empty()); |
| DCHECK_EQ(status != DemuxerStream::kOk, !input.get()) << status; |
| + // Pending Reset: ignore the buffer we just got, send kAborted to |read_cb_| |
| + // and carry out the Reset(). |
| + // If there happens to also be a pending Stop(), that will be handled at |
| + // the end of DoReset(). |
| + if (!reset_cb_.is_null()) { |
| + base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); |
| + DoReset(); |
| + return; |
| + } |
| + |
| + // Pending Stop: ignore the buffer we just got, send kAborted to |read_cb_| |
| + // and carry out the Stop(). |
| + if (!stop_cb_.is_null()) { |
| + base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); |
| + DoStop(); |
| + return; |
| + } |
| + |
| if (status == DemuxerStream::kAborted) { |
| DCHECK(!input.get()); |
| base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); |