Upstream version 6.35.121.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 FFmpegVideoDecoder::FFmpegVideoDecoder(
58     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
59     : task_runner_(task_runner), state_(kUninitialized) {}
60
61 int FFmpegVideoDecoder::GetVideoBuffer(AVCodecContext* codec_context,
62                                        AVFrame* frame) {
63   // Don't use |codec_context_| here! With threaded decoding,
64   // it will contain unsynchronized width/height/pix_fmt values,
65   // whereas |codec_context| contains the current threads's
66   // updated width/height/pix_fmt, which can change for adaptive
67   // content.
68   VideoFrame::Format format = PixelFormatToVideoFormat(codec_context->pix_fmt);
69   if (format == VideoFrame::UNKNOWN)
70     return AVERROR(EINVAL);
71   DCHECK(format == VideoFrame::YV12 || format == VideoFrame::YV16 ||
72          format == VideoFrame::YV12J);
73
74   gfx::Size size(codec_context->width, codec_context->height);
75   int ret;
76   if ((ret = av_image_check_size(size.width(), size.height(), 0, NULL)) < 0)
77     return ret;
78
79   gfx::Size natural_size;
80   if (codec_context->sample_aspect_ratio.num > 0) {
81     natural_size = GetNaturalSize(size,
82                                   codec_context->sample_aspect_ratio.num,
83                                   codec_context->sample_aspect_ratio.den);
84   } else {
85     natural_size = config_.natural_size();
86   }
87
88   if (!VideoFrame::IsValidConfig(format, size, gfx::Rect(size), natural_size))
89     return AVERROR(EINVAL);
90
91   scoped_refptr<VideoFrame> video_frame =
92       frame_pool_.CreateFrame(format, size, gfx::Rect(size),
93                               natural_size, kNoTimestamp());
94
95   for (int i = 0; i < 3; i++) {
96     frame->base[i] = video_frame->data(i);
97     frame->data[i] = video_frame->data(i);
98     frame->linesize[i] = video_frame->stride(i);
99   }
100
101   frame->opaque = NULL;
102   video_frame.swap(reinterpret_cast<VideoFrame**>(&frame->opaque));
103   frame->type = FF_BUFFER_TYPE_USER;
104   frame->width = codec_context->width;
105   frame->height = codec_context->height;
106   frame->format = codec_context->pix_fmt;
107
108   return 0;
109 }
110
111 static int GetVideoBufferImpl(AVCodecContext* s, AVFrame* frame) {
112   FFmpegVideoDecoder* decoder = static_cast<FFmpegVideoDecoder*>(s->opaque);
113   return decoder->GetVideoBuffer(s, frame);
114 }
115
116 static void ReleaseVideoBufferImpl(AVCodecContext* s, AVFrame* frame) {
117   scoped_refptr<VideoFrame> video_frame;
118   video_frame.swap(reinterpret_cast<VideoFrame**>(&frame->opaque));
119
120   // The FFmpeg API expects us to zero the data pointers in
121   // this callback
122   memset(frame->data, 0, sizeof(frame->data));
123   frame->opaque = NULL;
124 }
125
126 void FFmpegVideoDecoder::Initialize(const VideoDecoderConfig& config,
127                                     const PipelineStatusCB& status_cb) {
128   DCHECK(task_runner_->BelongsToCurrentThread());
129   DCHECK(decode_cb_.is_null());
130   DCHECK(reset_cb_.is_null());
131   DCHECK(!config.is_encrypted());
132
133   FFmpegGlue::InitializeFFmpeg();
134
135   config_ = config;
136   PipelineStatusCB initialize_cb = BindToCurrentLoop(status_cb);
137
138   if (!config.IsValidConfig() || !ConfigureDecoder()) {
139     initialize_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
140     return;
141   }
142
143   // Success!
144   state_ = kNormal;
145   initialize_cb.Run(PIPELINE_OK);
146 }
147
148 void FFmpegVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
149                                 const DecodeCB& decode_cb) {
150   DCHECK(task_runner_->BelongsToCurrentThread());
151   DCHECK(!decode_cb.is_null());
152   CHECK_NE(state_, kUninitialized);
153   CHECK(decode_cb_.is_null()) << "Overlapping decodes are not supported.";
154   decode_cb_ = BindToCurrentLoop(decode_cb);
155
156   if (state_ == kError) {
157     base::ResetAndReturn(&decode_cb_).Run(kDecodeError, NULL);
158     return;
159   }
160
161   // Return empty frames if decoding has finished.
162   if (state_ == kDecodeFinished) {
163     base::ResetAndReturn(&decode_cb_).Run(kOk, VideoFrame::CreateEOSFrame());
164     return;
165   }
166
167   DecodeBuffer(buffer);
168 }
169
170 void FFmpegVideoDecoder::Reset(const base::Closure& closure) {
171   DCHECK(task_runner_->BelongsToCurrentThread());
172   DCHECK(reset_cb_.is_null());
173   reset_cb_ = BindToCurrentLoop(closure);
174
175   // Defer the reset if a decode is pending.
176   if (!decode_cb_.is_null())
177     return;
178
179   DoReset();
180 }
181
182 void FFmpegVideoDecoder::DoReset() {
183   DCHECK(decode_cb_.is_null());
184
185   avcodec_flush_buffers(codec_context_.get());
186   state_ = kNormal;
187   base::ResetAndReturn(&reset_cb_).Run();
188 }
189
190 void FFmpegVideoDecoder::Stop(const base::Closure& closure) {
191   DCHECK(task_runner_->BelongsToCurrentThread());
192   base::ScopedClosureRunner runner(BindToCurrentLoop(closure));
193
194   if (state_ == kUninitialized)
195     return;
196
197   if (!decode_cb_.is_null()) {
198     base::ResetAndReturn(&decode_cb_).Run(kAborted, NULL);
199     // Reset is pending only when decode is pending.
200     if (!reset_cb_.is_null())
201       base::ResetAndReturn(&reset_cb_).Run();
202   }
203
204   ReleaseFFmpegResources();
205   state_ = kUninitialized;
206 }
207
208 FFmpegVideoDecoder::~FFmpegVideoDecoder() {
209   DCHECK_EQ(kUninitialized, state_);
210   DCHECK(!codec_context_);
211   DCHECK(!av_frame_);
212 }
213
214 void FFmpegVideoDecoder::DecodeBuffer(
215     const scoped_refptr<DecoderBuffer>& buffer) {
216   DCHECK(task_runner_->BelongsToCurrentThread());
217   DCHECK_NE(state_, kUninitialized);
218   DCHECK_NE(state_, kDecodeFinished);
219   DCHECK_NE(state_, kError);
220   DCHECK(reset_cb_.is_null());
221   DCHECK(!decode_cb_.is_null());
222   DCHECK(buffer);
223
224   // During decode, because reads are issued asynchronously, it is possible to
225   // receive multiple end of stream buffers since each decode is acked. When the
226   // first end of stream buffer is read, FFmpeg may still have frames queued
227   // up in the decoder so we need to go through the decode loop until it stops
228   // giving sensible data.  After that, the decoder should output empty
229   // frames.  There are three states the decoder can be in:
230   //
231   //   kNormal: This is the starting state. Buffers are decoded. Decode errors
232   //            are discarded.
233   //   kFlushCodec: There isn't any more input data. Call avcodec_decode_video2
234   //                until no more data is returned to flush out remaining
235   //                frames. The input buffer is ignored at this point.
236   //   kDecodeFinished: All calls return empty frames.
237   //   kError: Unexpected error happened.
238   //
239   // These are the possible state transitions.
240   //
241   // kNormal -> kFlushCodec:
242   //     When buffer->end_of_stream() is first true.
243   // kNormal -> kError:
244   //     A decoding error occurs and decoding needs to stop.
245   // kFlushCodec -> kDecodeFinished:
246   //     When avcodec_decode_video2() returns 0 data.
247   // kFlushCodec -> kError:
248   //     When avcodec_decode_video2() errors out.
249   // (any state) -> kNormal:
250   //     Any time Reset() is called.
251
252   // Transition to kFlushCodec on the first end of stream buffer.
253   if (state_ == kNormal && buffer->end_of_stream()) {
254     state_ = kFlushCodec;
255   }
256
257   scoped_refptr<VideoFrame> video_frame;
258   if (!FFmpegDecode(buffer, &video_frame)) {
259     state_ = kError;
260     base::ResetAndReturn(&decode_cb_).Run(kDecodeError, NULL);
261     return;
262   }
263
264   if (!video_frame.get()) {
265     if (state_ == kFlushCodec) {
266       DCHECK(buffer->end_of_stream());
267       state_ = kDecodeFinished;
268       base::ResetAndReturn(&decode_cb_)
269           .Run(kOk, VideoFrame::CreateEOSFrame());
270       return;
271     }
272
273     base::ResetAndReturn(&decode_cb_).Run(kNotEnoughData, NULL);
274     return;
275   }
276
277   base::ResetAndReturn(&decode_cb_).Run(kOk, video_frame);
278 }
279
280 bool FFmpegVideoDecoder::FFmpegDecode(
281     const scoped_refptr<DecoderBuffer>& buffer,
282     scoped_refptr<VideoFrame>* video_frame) {
283   DCHECK(video_frame);
284
285   // Reset frame to default values.
286   avcodec_get_frame_defaults(av_frame_.get());
287
288   // Create a packet for input data.
289   // Due to FFmpeg API changes we no longer have const read-only pointers.
290   AVPacket packet;
291   av_init_packet(&packet);
292   if (buffer->end_of_stream()) {
293     packet.data = NULL;
294     packet.size = 0;
295   } else {
296     packet.data = const_cast<uint8*>(buffer->data());
297     packet.size = buffer->data_size();
298
299     // Let FFmpeg handle presentation timestamp reordering.
300     codec_context_->reordered_opaque = buffer->timestamp().InMicroseconds();
301
302     // This is for codecs not using get_buffer to initialize
303     // |av_frame_->reordered_opaque|
304     av_frame_->reordered_opaque = codec_context_->reordered_opaque;
305   }
306
307   int frame_decoded = 0;
308   int result = avcodec_decode_video2(codec_context_.get(),
309                                      av_frame_.get(),
310                                      &frame_decoded,
311                                      &packet);
312   // Log the problem if we can't decode a video frame and exit early.
313   if (result < 0) {
314     LOG(ERROR) << "Error decoding video: " << buffer->AsHumanReadableString();
315     *video_frame = NULL;
316     return false;
317   }
318
319   // If no frame was produced then signal that more data is required to
320   // produce more frames. This can happen under two circumstances:
321   //   1) Decoder was recently initialized/flushed
322   //   2) End of stream was reached and all internal frames have been output
323   if (frame_decoded == 0) {
324     *video_frame = NULL;
325     return true;
326   }
327
328   // TODO(fbarchard): Work around for FFmpeg http://crbug.com/27675
329   // The decoder is in a bad state and not decoding correctly.
330   // Checking for NULL avoids a crash in CopyPlane().
331   if (!av_frame_->data[VideoFrame::kYPlane] ||
332       !av_frame_->data[VideoFrame::kUPlane] ||
333       !av_frame_->data[VideoFrame::kVPlane]) {
334     LOG(ERROR) << "Video frame was produced yet has invalid frame data.";
335     *video_frame = NULL;
336     return false;
337   }
338
339   if (!av_frame_->opaque) {
340     LOG(ERROR) << "VideoFrame object associated with frame data not set.";
341     return false;
342   }
343   *video_frame = static_cast<VideoFrame*>(av_frame_->opaque);
344
345   (*video_frame)->SetTimestamp(
346       base::TimeDelta::FromMicroseconds(av_frame_->reordered_opaque));
347
348   return true;
349 }
350
351 void FFmpegVideoDecoder::ReleaseFFmpegResources() {
352   codec_context_.reset();
353   av_frame_.reset();
354 }
355
356 bool FFmpegVideoDecoder::ConfigureDecoder() {
357   // Release existing decoder resources if necessary.
358   ReleaseFFmpegResources();
359
360   // Initialize AVCodecContext structure.
361   codec_context_.reset(avcodec_alloc_context3(NULL));
362   VideoDecoderConfigToAVCodecContext(config_, codec_context_.get());
363
364   // Enable motion vector search (potentially slow), strong deblocking filter
365   // for damaged macroblocks, and set our error detection sensitivity.
366   codec_context_->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK;
367   codec_context_->thread_count = GetThreadCount(codec_context_->codec_id);
368   codec_context_->opaque = this;
369   codec_context_->flags |= CODEC_FLAG_EMU_EDGE;
370   codec_context_->get_buffer = GetVideoBufferImpl;
371   codec_context_->release_buffer = ReleaseVideoBufferImpl;
372
373   AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
374   if (!codec || avcodec_open2(codec_context_.get(), codec, NULL) < 0) {
375     ReleaseFFmpegResources();
376     return false;
377   }
378
379   av_frame_.reset(av_frame_alloc());
380   return true;
381 }
382
383 }  // namespace media