| Index: media/filters/ffmpeg_video_decoder.cc
|
| diff --git a/media/filters/ffmpeg_video_decoder.cc b/media/filters/ffmpeg_video_decoder.cc
|
| index 0cc5573b494509ffe819c3282b7761ce8078ed46..b51ac662063b753b859586bf457934c41e50035a 100644
|
| --- a/media/filters/ffmpeg_video_decoder.cc
|
| +++ b/media/filters/ffmpeg_video_decoder.cc
|
| @@ -13,6 +13,7 @@
|
| #include "base/location.h"
|
| #include "base/message_loop_proxy.h"
|
| #include "base/string_number_conversions.h"
|
| +#include "media/base/bind_to_loop.h"
|
| #include "media/base/decoder_buffer.h"
|
| #include "media/base/demuxer_stream.h"
|
| #include "media/base/limits.h"
|
| @@ -133,18 +134,14 @@ static void ReleaseVideoBufferImpl(AVCodecContext* s, AVFrame* frame) {
|
| void FFmpegVideoDecoder::Initialize(const scoped_refptr<DemuxerStream>& stream,
|
| const PipelineStatusCB& status_cb,
|
| const StatisticsCB& statistics_cb) {
|
| - if (!message_loop_->BelongsToCurrentThread()) {
|
| - message_loop_->PostTask(FROM_HERE, base::Bind(
|
| - &FFmpegVideoDecoder::Initialize, this,
|
| - stream, status_cb, statistics_cb));
|
| - return;
|
| - }
|
| + DCHECK(message_loop_->BelongsToCurrentThread());
|
| + PipelineStatusCB initialize_cb = BindToCurrentLoop(status_cb);
|
|
|
| FFmpegGlue::InitializeFFmpeg();
|
| DCHECK(!demuxer_stream_) << "Already initialized.";
|
|
|
| if (!stream) {
|
| - status_cb.Run(PIPELINE_ERROR_DECODE);
|
| + initialize_cb.Run(PIPELINE_ERROR_DECODE);
|
| return;
|
| }
|
|
|
| @@ -152,31 +149,35 @@ void FFmpegVideoDecoder::Initialize(const scoped_refptr<DemuxerStream>& stream,
|
| statistics_cb_ = statistics_cb;
|
|
|
| if (!ConfigureDecoder()) {
|
| - status_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
|
| + initialize_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
|
| return;
|
| }
|
|
|
| // Success!
|
| state_ = kNormal;
|
| - status_cb.Run(PIPELINE_OK);
|
| + initialize_cb.Run(PIPELINE_OK);
|
| }
|
|
|
| void FFmpegVideoDecoder::Read(const ReadCB& read_cb) {
|
| - // Complete operation asynchronously on different stack of execution as per
|
| - // the API contract of VideoDecoder::Read()
|
| - message_loop_->PostTask(FROM_HERE, base::Bind(
|
| - &FFmpegVideoDecoder::DoRead, this, read_cb));
|
| -}
|
| + DCHECK(message_loop_->BelongsToCurrentThread());
|
| + DCHECK(!read_cb.is_null());
|
| + CHECK_NE(state_, kUninitialized);
|
| + CHECK(read_cb_.is_null()) << "Overlapping decodes are not supported.";
|
| + read_cb_ = BindToCurrentLoop(read_cb);
|
|
|
| -void FFmpegVideoDecoder::Reset(const base::Closure& closure) {
|
| - if (!message_loop_->BelongsToCurrentThread()) {
|
| - message_loop_->PostTask(FROM_HERE, base::Bind(
|
| - &FFmpegVideoDecoder::Reset, this, closure));
|
| + // Return empty frames if decoding has finished.
|
| + if (state_ == kDecodeFinished) {
|
| + base::ResetAndReturn(&read_cb_).Run(kOk, VideoFrame::CreateEmptyFrame());
|
| return;
|
| }
|
|
|
| + ReadFromDemuxerStream();
|
| +}
|
| +
|
| +void FFmpegVideoDecoder::Reset(const base::Closure& closure) {
|
| + DCHECK(message_loop_->BelongsToCurrentThread());
|
| DCHECK(reset_cb_.is_null());
|
| - reset_cb_ = closure;
|
| + reset_cb_ = BindToCurrentLoop(closure);
|
|
|
| if (decryptor_)
|
| decryptor_->CancelDecrypt(Decryptor::kVideo);
|
| @@ -193,21 +194,15 @@ void FFmpegVideoDecoder::DoReset() {
|
|
|
| avcodec_flush_buffers(codec_context_);
|
| state_ = kNormal;
|
| - reset_cb_.Run();
|
| - reset_cb_.Reset();
|
| + base::ResetAndReturn(&reset_cb_).Run();
|
| }
|
|
|
| void FFmpegVideoDecoder::Stop(const base::Closure& closure) {
|
| - if (!message_loop_->BelongsToCurrentThread()) {
|
| - message_loop_->PostTask(FROM_HERE, base::Bind(
|
| - &FFmpegVideoDecoder::Stop, this, closure));
|
| - return;
|
| - }
|
| + DCHECK(message_loop_->BelongsToCurrentThread());
|
| + base::ScopedClosureRunner runner(BindToCurrentLoop(closure));
|
|
|
| - if (state_ == kUninitialized) {
|
| - closure.Run();
|
| + if (state_ == kUninitialized)
|
| return;
|
| - }
|
|
|
| if (decryptor_)
|
| decryptor_->CancelDecrypt(Decryptor::kVideo);
|
| @@ -217,7 +212,6 @@ void FFmpegVideoDecoder::Stop(const base::Closure& closure) {
|
|
|
| ReleaseFFmpegResources();
|
| state_ = kUninitialized;
|
| - closure.Run();
|
| }
|
|
|
| FFmpegVideoDecoder::~FFmpegVideoDecoder() {
|
| @@ -226,40 +220,19 @@ FFmpegVideoDecoder::~FFmpegVideoDecoder() {
|
| DCHECK(!av_frame_);
|
| }
|
|
|
| -void FFmpegVideoDecoder::DoRead(const ReadCB& read_cb) {
|
| - DCHECK(message_loop_->BelongsToCurrentThread());
|
| - DCHECK(!read_cb.is_null());
|
| - CHECK_NE(state_, kUninitialized);
|
| - CHECK(read_cb_.is_null()) << "Overlapping decodes are not supported.";
|
| -
|
| - // Return empty frames if decoding has finished.
|
| - if (state_ == kDecodeFinished) {
|
| - read_cb.Run(kOk, VideoFrame::CreateEmptyFrame());
|
| - return;
|
| - }
|
| -
|
| - read_cb_ = read_cb;
|
| - ReadFromDemuxerStream();
|
| -}
|
| -
|
| void FFmpegVideoDecoder::ReadFromDemuxerStream() {
|
| DCHECK_NE(state_, kUninitialized);
|
| DCHECK_NE(state_, kDecodeFinished);
|
| DCHECK(!read_cb_.is_null());
|
|
|
| demuxer_stream_->Read(base::Bind(
|
| - &FFmpegVideoDecoder::DoDecryptOrDecodeBuffer, this));
|
| + &FFmpegVideoDecoder::DecryptOrDecodeBuffer, this));
|
| }
|
|
|
| -void FFmpegVideoDecoder::DoDecryptOrDecodeBuffer(
|
| +void FFmpegVideoDecoder::DecryptOrDecodeBuffer(
|
| DemuxerStream::Status status,
|
| const scoped_refptr<DecoderBuffer>& buffer) {
|
| - if (!message_loop_->BelongsToCurrentThread()) {
|
| - message_loop_->PostTask(FROM_HERE, base::Bind(
|
| - &FFmpegVideoDecoder::DoDecryptOrDecodeBuffer, this, status, buffer));
|
| - return;
|
| - }
|
| -
|
| + DCHECK(message_loop_->BelongsToCurrentThread());
|
| DCHECK_NE(state_, kDecodeFinished);
|
| DCHECK_EQ(status != DemuxerStream::kOk, !buffer) << status;
|
|
|
| @@ -291,10 +264,10 @@ void FFmpegVideoDecoder::DoDecryptOrDecodeBuffer(
|
|
|
| DCHECK_EQ(status, DemuxerStream::kOk);
|
|
|
| + // TODO(xhwang): Remove decryptor after DecryptingDemuxerStream is ready.
|
| if (buffer->GetDecryptConfig() && buffer->GetDataSize()) {
|
| - decryptor_->Decrypt(Decryptor::kVideo,
|
| - buffer,
|
| - base::Bind(&FFmpegVideoDecoder::BufferDecrypted, this));
|
| + decryptor_->Decrypt(Decryptor::kVideo, buffer, BindToCurrentLoop(
|
| + base::Bind(&FFmpegVideoDecoder::BufferDecrypted, this)));
|
| return;
|
| }
|
|
|
| @@ -304,13 +277,6 @@ void FFmpegVideoDecoder::DoDecryptOrDecodeBuffer(
|
| void FFmpegVideoDecoder::BufferDecrypted(
|
| Decryptor::Status decrypt_status,
|
| const scoped_refptr<DecoderBuffer>& buffer) {
|
| - message_loop_->PostTask(FROM_HERE, base::Bind(
|
| - &FFmpegVideoDecoder::DoBufferDecrypted, this, decrypt_status, buffer));
|
| -}
|
| -
|
| -void FFmpegVideoDecoder::DoBufferDecrypted(
|
| - Decryptor::Status decrypt_status,
|
| - const scoped_refptr<DecoderBuffer>& buffer) {
|
| DCHECK(message_loop_->BelongsToCurrentThread());
|
| DCHECK_NE(state_, kDecodeFinished);
|
|
|
|
|