Home | History | Annotate | Download | only in filters
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "media/filters/ffmpeg_video_decoder.h"
      6 
      7 #include <algorithm>
      8 #include <string>
      9 
     10 #include "base/bind.h"
     11 #include "base/callback_helpers.h"
     12 #include "base/command_line.h"
     13 #include "base/location.h"
     14 #include "base/message_loop/message_loop_proxy.h"
     15 #include "base/strings/string_number_conversions.h"
     16 #include "media/base/bind_to_loop.h"
     17 #include "media/base/decoder_buffer.h"
     18 #include "media/base/limits.h"
     19 #include "media/base/media_switches.h"
     20 #include "media/base/pipeline.h"
     21 #include "media/base/video_decoder_config.h"
     22 #include "media/base/video_frame.h"
     23 #include "media/base/video_util.h"
     24 #include "media/ffmpeg/ffmpeg_common.h"
     25 #include "media/filters/ffmpeg_glue.h"
     26 
     27 namespace media {
     28 
     29 // Always try to use three threads for video decoding.  There is little reason
     30 // not to since current day CPUs tend to be multi-core and we measured
     31 // performance benefits on older machines such as P4s with hyperthreading.
     32 //
     33 // Handling decoding on separate threads also frees up the pipeline thread to
     34 // continue processing. Although it'd be nice to have the option of a single
     35 // decoding thread, FFmpeg treats having one thread the same as having zero
     36 // threads (i.e., avcodec_decode_video() will execute on the calling thread).
     37 // Yet another reason for having two threads :)
     38 static const int kDecodeThreads = 2;
     39 static const int kMaxDecodeThreads = 16;
     40 
     41 // Returns the number of threads given the FFmpeg CodecID. Also inspects the
     42 // command line for a valid --video-threads flag.
     43 static int GetThreadCount(AVCodecID codec_id) {
     44   // Refer to http://crbug.com/93932 for tsan suppressions on decoding.
     45   int decode_threads = kDecodeThreads;
     46 
     47   const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
     48   std::string threads(cmd_line->GetSwitchValueASCII(switches::kVideoThreads));
     49   if (threads.empty() || !base::StringToInt(threads, &decode_threads))
     50     return decode_threads;
     51 
     52   decode_threads = std::max(decode_threads, 0);
     53   decode_threads = std::min(decode_threads, kMaxDecodeThreads);
     54   return decode_threads;
     55 }
     56 
     57 FFmpegVideoDecoder::FFmpegVideoDecoder(
     58     const scoped_refptr<base::MessageLoopProxy>& message_loop)
     59     : message_loop_(message_loop),
     60       weak_factory_(this),
     61       state_(kUninitialized),
     62       codec_context_(NULL),
     63       av_frame_(NULL) {
     64 }
     65 
     66 int FFmpegVideoDecoder::GetVideoBuffer(AVCodecContext* codec_context,
     67                                        AVFrame* frame) {
     68   // Don't use |codec_context_| here! With threaded decoding,
     69   // it will contain unsynchronized width/height/pix_fmt values,
     70   // whereas |codec_context| contains the current threads's
     71   // updated width/height/pix_fmt, which can change for adaptive
     72   // content.
     73   VideoFrame::Format format = PixelFormatToVideoFormat(codec_context->pix_fmt);
     74   if (format == VideoFrame::INVALID)
     75     return AVERROR(EINVAL);
     76   DCHECK(format == VideoFrame::YV12 || format == VideoFrame::YV16);
     77 
     78   gfx::Size size(codec_context->width, codec_context->height);
     79   int ret;
     80   if ((ret = av_image_check_size(size.width(), size.height(), 0, NULL)) < 0)
     81     return ret;
     82 
     83   gfx::Size natural_size;
     84   if (codec_context->sample_aspect_ratio.num > 0) {
     85     natural_size = GetNaturalSize(size,
     86                                   codec_context->sample_aspect_ratio.num,
     87                                   codec_context->sample_aspect_ratio.den);
     88   } else {
     89     natural_size = config_.natural_size();
     90   }
     91 
     92   if (!VideoFrame::IsValidConfig(format, size, gfx::Rect(size), natural_size))
     93     return AVERROR(EINVAL);
     94 
     95   scoped_refptr<VideoFrame> video_frame =
     96       VideoFrame::CreateFrame(format, size, gfx::Rect(size), natural_size,
     97                               kNoTimestamp());
     98 
     99   for (int i = 0; i < 3; i++) {
    100     frame->base[i] = video_frame->data(i);
    101     frame->data[i] = video_frame->data(i);
    102     frame->linesize[i] = video_frame->stride(i);
    103   }
    104 
    105   frame->opaque = NULL;
    106   video_frame.swap(reinterpret_cast<VideoFrame**>(&frame->opaque));
    107   frame->type = FF_BUFFER_TYPE_USER;
    108   frame->pkt_pts = codec_context->pkt ? codec_context->pkt->pts :
    109                                         AV_NOPTS_VALUE;
    110   frame->width = codec_context->width;
    111   frame->height = codec_context->height;
    112   frame->format = codec_context->pix_fmt;
    113 
    114   return 0;
    115 }
    116 
    117 static int GetVideoBufferImpl(AVCodecContext* s, AVFrame* frame) {
    118   FFmpegVideoDecoder* decoder = static_cast<FFmpegVideoDecoder*>(s->opaque);
    119   return decoder->GetVideoBuffer(s, frame);
    120 }
    121 
    122 static void ReleaseVideoBufferImpl(AVCodecContext* s, AVFrame* frame) {
    123   scoped_refptr<VideoFrame> video_frame;
    124   video_frame.swap(reinterpret_cast<VideoFrame**>(&frame->opaque));
    125 
    126   // The FFmpeg API expects us to zero the data pointers in
    127   // this callback
    128   memset(frame->data, 0, sizeof(frame->data));
    129   frame->opaque = NULL;
    130 }
    131 
    132 void FFmpegVideoDecoder::Initialize(const VideoDecoderConfig& config,
    133                                     const PipelineStatusCB& status_cb) {
    134   DCHECK(message_loop_->BelongsToCurrentThread());
    135   DCHECK(decode_cb_.is_null());
    136   DCHECK(reset_cb_.is_null());
    137   DCHECK(!config.is_encrypted());
    138 
    139   FFmpegGlue::InitializeFFmpeg();
    140   weak_this_ = weak_factory_.GetWeakPtr();
    141 
    142   config_ = config;
    143   PipelineStatusCB initialize_cb = BindToCurrentLoop(status_cb);
    144 
    145   if (!config.IsValidConfig() || !ConfigureDecoder()) {
    146     initialize_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
    147     return;
    148   }
    149 
    150   // Success!
    151   state_ = kNormal;
    152   initialize_cb.Run(PIPELINE_OK);
    153 }
    154 
    155 void FFmpegVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
    156                                 const DecodeCB& decode_cb) {
    157   DCHECK(message_loop_->BelongsToCurrentThread());
    158   DCHECK(!decode_cb.is_null());
    159   CHECK_NE(state_, kUninitialized);
    160   CHECK(decode_cb_.is_null()) << "Overlapping decodes are not supported.";
    161   decode_cb_ = BindToCurrentLoop(decode_cb);
    162 
    163   if (state_ == kError) {
    164     base::ResetAndReturn(&decode_cb_).Run(kDecodeError, NULL);
    165     return;
    166   }
    167 
    168   // Return empty frames if decoding has finished.
    169   if (state_ == kDecodeFinished) {
    170     base::ResetAndReturn(&decode_cb_).Run(kOk, VideoFrame::CreateEmptyFrame());
    171     return;
    172   }
    173 
    174   DecodeBuffer(buffer);
    175 }
    176 
    177 void FFmpegVideoDecoder::Reset(const base::Closure& closure) {
    178   DCHECK(message_loop_->BelongsToCurrentThread());
    179   DCHECK(reset_cb_.is_null());
    180   reset_cb_ = BindToCurrentLoop(closure);
    181 
    182   // Defer the reset if a decode is pending.
    183   if (!decode_cb_.is_null())
    184     return;
    185 
    186   DoReset();
    187 }
    188 
    189 void FFmpegVideoDecoder::DoReset() {
    190   DCHECK(decode_cb_.is_null());
    191 
    192   avcodec_flush_buffers(codec_context_);
    193   state_ = kNormal;
    194   base::ResetAndReturn(&reset_cb_).Run();
    195 }
    196 
    197 void FFmpegVideoDecoder::Stop(const base::Closure& closure) {
    198   DCHECK(message_loop_->BelongsToCurrentThread());
    199   base::ScopedClosureRunner runner(BindToCurrentLoop(closure));
    200 
    201   if (state_ == kUninitialized)
    202     return;
    203 
    204   if (!decode_cb_.is_null()) {
    205     base::ResetAndReturn(&decode_cb_).Run(kOk, NULL);
    206     // Reset is pending only when decode is pending.
    207     if (!reset_cb_.is_null())
    208       base::ResetAndReturn(&reset_cb_).Run();
    209   }
    210 
    211   ReleaseFFmpegResources();
    212   state_ = kUninitialized;
    213 }
    214 
    215 FFmpegVideoDecoder::~FFmpegVideoDecoder() {
    216   DCHECK_EQ(kUninitialized, state_);
    217   DCHECK(!codec_context_);
    218   DCHECK(!av_frame_);
    219 }
    220 
    221 void FFmpegVideoDecoder::DecodeBuffer(
    222     const scoped_refptr<DecoderBuffer>& buffer) {
    223   DCHECK(message_loop_->BelongsToCurrentThread());
    224   DCHECK_NE(state_, kUninitialized);
    225   DCHECK_NE(state_, kDecodeFinished);
    226   DCHECK_NE(state_, kError);
    227   DCHECK(reset_cb_.is_null());
    228   DCHECK(!decode_cb_.is_null());
    229   DCHECK(buffer);
    230 
    231   // During decode, because reads are issued asynchronously, it is possible to
    232   // receive multiple end of stream buffers since each decode is acked. When the
    233   // first end of stream buffer is read, FFmpeg may still have frames queued
    234   // up in the decoder so we need to go through the decode loop until it stops
    235   // giving sensible data.  After that, the decoder should output empty
    236   // frames.  There are three states the decoder can be in:
    237   //
    238   //   kNormal: This is the starting state. Buffers are decoded. Decode errors
    239   //            are discarded.
    240   //   kFlushCodec: There isn't any more input data. Call avcodec_decode_video2
    241   //                until no more data is returned to flush out remaining
    242   //                frames. The input buffer is ignored at this point.
    243   //   kDecodeFinished: All calls return empty frames.
    244   //   kError: Unexpected error happened.
    245   //
    246   // These are the possible state transitions.
    247   //
    248   // kNormal -> kFlushCodec:
    249   //     When buffer->end_of_stream() is first true.
    250   // kNormal -> kError:
    251   //     A decoding error occurs and decoding needs to stop.
    252   // kFlushCodec -> kDecodeFinished:
    253   //     When avcodec_decode_video2() returns 0 data.
    254   // kFlushCodec -> kError:
    255   //     When avcodec_decode_video2() errors out.
    256   // (any state) -> kNormal:
    257   //     Any time Reset() is called.
    258 
    259   // Transition to kFlushCodec on the first end of stream buffer.
    260   if (state_ == kNormal && buffer->end_of_stream()) {
    261     state_ = kFlushCodec;
    262   }
    263 
    264   scoped_refptr<VideoFrame> video_frame;
    265   if (!FFmpegDecode(buffer, &video_frame)) {
    266     state_ = kError;
    267     base::ResetAndReturn(&decode_cb_).Run(kDecodeError, NULL);
    268     return;
    269   }
    270 
    271   if (!video_frame.get()) {
    272     if (state_ == kFlushCodec) {
    273       DCHECK(buffer->end_of_stream());
    274       state_ = kDecodeFinished;
    275       base::ResetAndReturn(&decode_cb_)
    276           .Run(kOk, VideoFrame::CreateEmptyFrame());
    277       return;
    278     }
    279 
    280     base::ResetAndReturn(&decode_cb_).Run(kNotEnoughData, NULL);
    281     return;
    282   }
    283 
    284   base::ResetAndReturn(&decode_cb_).Run(kOk, video_frame);
    285 }
    286 
    287 bool FFmpegVideoDecoder::FFmpegDecode(
    288     const scoped_refptr<DecoderBuffer>& buffer,
    289     scoped_refptr<VideoFrame>* video_frame) {
    290   DCHECK(video_frame);
    291 
    292   // Reset frame to default values.
    293   avcodec_get_frame_defaults(av_frame_);
    294 
    295   // Create a packet for input data.
    296   // Due to FFmpeg API changes we no longer have const read-only pointers.
    297   AVPacket packet;
    298   av_init_packet(&packet);
    299   if (buffer->end_of_stream()) {
    300     packet.data = NULL;
    301     packet.size = 0;
    302   } else {
    303     packet.data = const_cast<uint8*>(buffer->data());
    304     packet.size = buffer->data_size();
    305 
    306     // Let FFmpeg handle presentation timestamp reordering.
    307     codec_context_->reordered_opaque = buffer->timestamp().InMicroseconds();
    308 
    309     // This is for codecs not using get_buffer to initialize
    310     // |av_frame_->reordered_opaque|
    311     av_frame_->reordered_opaque = codec_context_->reordered_opaque;
    312   }
    313 
    314   int frame_decoded = 0;
    315   int result = avcodec_decode_video2(codec_context_,
    316                                      av_frame_,
    317                                      &frame_decoded,
    318                                      &packet);
    319   // Log the problem if we can't decode a video frame and exit early.
    320   if (result < 0) {
    321     LOG(ERROR) << "Error decoding video: " << buffer->AsHumanReadableString();
    322     *video_frame = NULL;
    323     return false;
    324   }
    325 
    326   // If no frame was produced then signal that more data is required to
    327   // produce more frames. This can happen under two circumstances:
    328   //   1) Decoder was recently initialized/flushed
    329   //   2) End of stream was reached and all internal frames have been output
    330   if (frame_decoded == 0) {
    331     *video_frame = NULL;
    332     return true;
    333   }
    334 
    335   // TODO(fbarchard): Work around for FFmpeg http://crbug.com/27675
    336   // The decoder is in a bad state and not decoding correctly.
    337   // Checking for NULL avoids a crash in CopyPlane().
    338   if (!av_frame_->data[VideoFrame::kYPlane] ||
    339       !av_frame_->data[VideoFrame::kUPlane] ||
    340       !av_frame_->data[VideoFrame::kVPlane]) {
    341     LOG(ERROR) << "Video frame was produced yet has invalid frame data.";
    342     *video_frame = NULL;
    343     return false;
    344   }
    345 
    346   if (!av_frame_->opaque) {
    347     LOG(ERROR) << "VideoFrame object associated with frame data not set.";
    348     return false;
    349   }
    350   *video_frame = static_cast<VideoFrame*>(av_frame_->opaque);
    351 
    352   (*video_frame)->SetTimestamp(
    353       base::TimeDelta::FromMicroseconds(av_frame_->reordered_opaque));
    354 
    355   return true;
    356 }
    357 
    358 void FFmpegVideoDecoder::ReleaseFFmpegResources() {
    359   if (codec_context_) {
    360     av_free(codec_context_->extradata);
    361     avcodec_close(codec_context_);
    362     av_free(codec_context_);
    363     codec_context_ = NULL;
    364   }
    365   if (av_frame_) {
    366     av_free(av_frame_);
    367     av_frame_ = NULL;
    368   }
    369 }
    370 
    371 bool FFmpegVideoDecoder::ConfigureDecoder() {
    372   // Release existing decoder resources if necessary.
    373   ReleaseFFmpegResources();
    374 
    375   // Initialize AVCodecContext structure.
    376   codec_context_ = avcodec_alloc_context3(NULL);
    377   VideoDecoderConfigToAVCodecContext(config_, codec_context_);
    378 
    379   // Enable motion vector search (potentially slow), strong deblocking filter
    380   // for damaged macroblocks, and set our error detection sensitivity.
    381   codec_context_->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK;
    382   codec_context_->thread_count = GetThreadCount(codec_context_->codec_id);
    383   codec_context_->opaque = this;
    384   codec_context_->flags |= CODEC_FLAG_EMU_EDGE;
    385   codec_context_->get_buffer = GetVideoBufferImpl;
    386   codec_context_->release_buffer = ReleaseVideoBufferImpl;
    387 
    388   AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
    389   if (!codec || avcodec_open2(codec_context_, codec, NULL) < 0) {
    390     ReleaseFFmpegResources();
    391     return false;
    392   }
    393 
    394   av_frame_ = avcodec_alloc_frame();
    395   return true;
    396 }
    397 
    398 }  // namespace media
    399