Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / media / filters / ffmpeg_video_decoder.cc
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/single_thread_task_runner.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "media/base/bind_to_current_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 static int GetVideoBufferImpl(struct AVCodecContext* s,
58                               AVFrame* frame,
59                               int flags) {
60   FFmpegVideoDecoder* decoder = static_cast<FFmpegVideoDecoder*>(s->opaque);
61   return decoder->GetVideoBuffer(s, frame, flags);
62 }
63
64 static void ReleaseVideoBufferImpl(void* opaque, uint8* data) {
65   scoped_refptr<VideoFrame> video_frame;
66   video_frame.swap(reinterpret_cast<VideoFrame**>(&opaque));
67 }
68
69 static size_t RoundUp(size_t value, size_t alignment) {
70   // Check that |alignment| is a power of 2.
71   DCHECK((alignment + (alignment - 1)) == (alignment | (alignment - 1)));
72   return ((value + (alignment - 1)) & ~(alignment - 1));
73 }
74
75 FFmpegVideoDecoder::FFmpegVideoDecoder(
76     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
77     : task_runner_(task_runner), state_(kUninitialized),
78       decode_nalus_(false) {}
79
80 int FFmpegVideoDecoder::GetVideoBuffer(struct AVCodecContext* codec_context,
81                                        AVFrame* frame,
82                                        int flags) {
83   // Don't use |codec_context_| here! With threaded decoding,
84   // it will contain unsynchronized width/height/pix_fmt values,
85   // whereas |codec_context| contains the current threads's
86   // updated width/height/pix_fmt, which can change for adaptive
87   // content.
88   VideoFrame::Format format = PixelFormatToVideoFormat(codec_context->pix_fmt);
89   if (format == VideoFrame::UNKNOWN)
90     return AVERROR(EINVAL);
91   DCHECK(format == VideoFrame::YV12 || format == VideoFrame::YV16 ||
92          format == VideoFrame::YV12J || format == VideoFrame::YV24);
93
94   gfx::Size size(codec_context->width, codec_context->height);
95   const int ret = av_image_check_size(size.width(), size.height(), 0, NULL);
96   if (ret < 0)
97     return ret;
98
99   gfx::Size natural_size;
100   if (codec_context->sample_aspect_ratio.num > 0) {
101     natural_size = GetNaturalSize(size,
102                                   codec_context->sample_aspect_ratio.num,
103                                   codec_context->sample_aspect_ratio.den);
104   } else {
105     natural_size = config_.natural_size();
106   }
107
108   // FFmpeg has specific requirements on the allocation size of the frame.  The
109   // following logic replicates FFmpeg's allocation strategy to ensure buffers
110   // are not overread / overwritten.  See ff_init_buffer_info() for details.
111   //
112   // When lowres is non-zero, dimensions should be divided by 2^(lowres), but
113   // since we don't use this, just DCHECK that it's zero.
114   //
115   // Always round up to a multiple of two to match VideoFrame restrictions on
116   // frame alignment.
117   DCHECK_EQ(codec_context->lowres, 0);
118   gfx::Size coded_size(
119       RoundUp(std::max(size.width(), codec_context->coded_width), 2),
120       RoundUp(std::max(size.height(), codec_context->coded_height), 2));
121
122   if (!VideoFrame::IsValidConfig(
123           format, coded_size, gfx::Rect(size), natural_size))
124     return AVERROR(EINVAL);
125
126   scoped_refptr<VideoFrame> video_frame = frame_pool_.CreateFrame(
127       format, coded_size, gfx::Rect(size), natural_size, kNoTimestamp());
128
129   for (int i = 0; i < 3; i++) {
130     frame->data[i] = video_frame->data(i);
131     frame->linesize[i] = video_frame->stride(i);
132   }
133
134   frame->width = coded_size.width();
135   frame->height = coded_size.height();
136   frame->format = codec_context->pix_fmt;
137   frame->reordered_opaque = codec_context->reordered_opaque;
138
139   // Now create an AVBufferRef for the data just allocated. It will own the
140   // reference to the VideoFrame object.
141   void* opaque = NULL;
142   video_frame.swap(reinterpret_cast<VideoFrame**>(&opaque));
143   frame->buf[0] =
144       av_buffer_create(frame->data[0],
145                        VideoFrame::AllocationSize(format, coded_size),
146                        ReleaseVideoBufferImpl,
147                        opaque,
148                        0);
149   return 0;
150 }
151
152 void FFmpegVideoDecoder::Initialize(const VideoDecoderConfig& config,
153                                     bool low_delay,
154                                     const PipelineStatusCB& status_cb,
155                                     const OutputCB& output_cb) {
156   DCHECK(task_runner_->BelongsToCurrentThread());
157   DCHECK(!config.is_encrypted());
158   DCHECK(!output_cb.is_null());
159
160   FFmpegGlue::InitializeFFmpeg();
161
162   config_ = config;
163   PipelineStatusCB initialize_cb = BindToCurrentLoop(status_cb);
164
165   if (!config.IsValidConfig() || !ConfigureDecoder(low_delay)) {
166     initialize_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
167     return;
168   }
169
170   output_cb_ = BindToCurrentLoop(output_cb);
171
172   // Success!
173   state_ = kNormal;
174   initialize_cb.Run(PIPELINE_OK);
175 }
176
177 void FFmpegVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
178                                 const DecodeCB& decode_cb) {
179   DCHECK(task_runner_->BelongsToCurrentThread());
180   DCHECK(buffer);
181   DCHECK(!decode_cb.is_null());
182   CHECK_NE(state_, kUninitialized);
183
184   DecodeCB decode_cb_bound = BindToCurrentLoop(decode_cb);
185
186   if (state_ == kError) {
187     decode_cb_bound.Run(kDecodeError);
188     return;
189   }
190
191   if (state_ == kDecodeFinished) {
192     decode_cb_bound.Run(kOk);
193     return;
194   }
195
196   DCHECK_EQ(state_, kNormal);
197
198   // During decode, because reads are issued asynchronously, it is possible to
199   // receive multiple end of stream buffers since each decode is acked. When the
200   // first end of stream buffer is read, FFmpeg may still have frames queued
201   // up in the decoder so we need to go through the decode loop until it stops
202   // giving sensible data.  After that, the decoder should output empty
203   // frames.  There are three states the decoder can be in:
204   //
205   //   kNormal: This is the starting state. Buffers are decoded. Decode errors
206   //            are discarded.
207   //   kDecodeFinished: All calls return empty frames.
208   //   kError: Unexpected error happened.
209   //
210   // These are the possible state transitions.
211   //
212   // kNormal -> kDecodeFinished:
213   //     When EOS buffer is received and the codec has been flushed.
214   // kNormal -> kError:
215   //     A decoding error occurs and decoding needs to stop.
216   // (any state) -> kNormal:
217   //     Any time Reset() is called.
218
219   bool has_produced_frame;
220   do {
221     has_produced_frame = false;
222     if (!FFmpegDecode(buffer, &has_produced_frame)) {
223       state_ = kError;
224       decode_cb_bound.Run(kDecodeError);
225       return;
226     }
227     // Repeat to flush the decoder after receiving EOS buffer.
228   } while (buffer->end_of_stream() && has_produced_frame);
229
230   if (buffer->end_of_stream())
231     state_ = kDecodeFinished;
232
233   decode_cb_bound.Run(kOk);
234 }
235
236 void FFmpegVideoDecoder::Reset(const base::Closure& closure) {
237   DCHECK(task_runner_->BelongsToCurrentThread());
238
239   avcodec_flush_buffers(codec_context_.get());
240   state_ = kNormal;
241   task_runner_->PostTask(FROM_HERE, closure);
242 }
243
244 FFmpegVideoDecoder::~FFmpegVideoDecoder() {
245   DCHECK(task_runner_->BelongsToCurrentThread());
246
247   if (state_ != kUninitialized)
248     ReleaseFFmpegResources();
249 }
250
251 bool FFmpegVideoDecoder::FFmpegDecode(
252     const scoped_refptr<DecoderBuffer>& buffer,
253     bool* has_produced_frame) {
254   DCHECK(!*has_produced_frame);
255
256   // Create a packet for input data.
257   // Due to FFmpeg API changes we no longer have const read-only pointers.
258   AVPacket packet;
259   av_init_packet(&packet);
260   if (buffer->end_of_stream()) {
261     packet.data = NULL;
262     packet.size = 0;
263   } else {
264     packet.data = const_cast<uint8*>(buffer->data());
265     packet.size = buffer->data_size();
266
267     // Let FFmpeg handle presentation timestamp reordering.
268     codec_context_->reordered_opaque = buffer->timestamp().InMicroseconds();
269   }
270
271   int frame_decoded = 0;
272   int result = avcodec_decode_video2(codec_context_.get(),
273                                      av_frame_.get(),
274                                      &frame_decoded,
275                                      &packet);
276   // Log the problem if we can't decode a video frame and exit early.
277   if (result < 0) {
278     LOG(ERROR) << "Error decoding video: " << buffer->AsHumanReadableString();
279     return false;
280   }
281
282   // FFmpeg says some codecs might have multiple frames per packet.  Previous
283   // discussions with rbultje@ indicate this shouldn't be true for the codecs
284   // we use.
285   DCHECK_EQ(result, packet.size);
286
287   // If no frame was produced then signal that more data is required to
288   // produce more frames. This can happen under two circumstances:
289   //   1) Decoder was recently initialized/flushed
290   //   2) End of stream was reached and all internal frames have been output
291   if (frame_decoded == 0) {
292     return true;
293   }
294
295   // TODO(fbarchard): Work around for FFmpeg http://crbug.com/27675
296   // The decoder is in a bad state and not decoding correctly.
297   // Checking for NULL avoids a crash in CopyPlane().
298   if (!av_frame_->data[VideoFrame::kYPlane] ||
299       !av_frame_->data[VideoFrame::kUPlane] ||
300       !av_frame_->data[VideoFrame::kVPlane]) {
301     LOG(ERROR) << "Video frame was produced yet has invalid frame data.";
302     av_frame_unref(av_frame_.get());
303     return false;
304   }
305
306   scoped_refptr<VideoFrame> frame =
307       reinterpret_cast<VideoFrame*>(av_buffer_get_opaque(av_frame_->buf[0]));
308   frame->set_timestamp(
309       base::TimeDelta::FromMicroseconds(av_frame_->reordered_opaque));
310   *has_produced_frame = true;
311   output_cb_.Run(frame);
312
313   av_frame_unref(av_frame_.get());
314   return true;
315 }
316
317 void FFmpegVideoDecoder::ReleaseFFmpegResources() {
318   codec_context_.reset();
319   av_frame_.reset();
320 }
321
322 bool FFmpegVideoDecoder::ConfigureDecoder(bool low_delay) {
323   // Release existing decoder resources if necessary.
324   ReleaseFFmpegResources();
325
326   // Initialize AVCodecContext structure.
327   codec_context_.reset(avcodec_alloc_context3(NULL));
328   VideoDecoderConfigToAVCodecContext(config_, codec_context_.get());
329
330   codec_context_->thread_count = GetThreadCount(codec_context_->codec_id);
331   codec_context_->thread_type = low_delay ? FF_THREAD_SLICE : FF_THREAD_FRAME;
332   codec_context_->opaque = this;
333   codec_context_->flags |= CODEC_FLAG_EMU_EDGE;
334   codec_context_->get_buffer2 = GetVideoBufferImpl;
335   codec_context_->refcounted_frames = 1;
336
337   if (decode_nalus_)
338     codec_context_->flags2 |= CODEC_FLAG2_CHUNKS;
339
340   AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
341   if (!codec || avcodec_open2(codec_context_.get(), codec, NULL) < 0) {
342     ReleaseFFmpegResources();
343     return false;
344   }
345
346   av_frame_.reset(av_frame_alloc());
347   return true;
348 }
349
350 }  // namespace media