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#ifndef MEDIA_FILTERS_FFMPEG_VIDEO_DECODER_H_
6#define MEDIA_FILTERS_FFMPEG_VIDEO_DECODER_H_
7
8#include <list>
9
10#include "base/callback.h"
11#include "base/memory/scoped_ptr.h"
12#include "media/base/video_decoder.h"
13#include "media/base/video_decoder_config.h"
14#include "media/base/video_frame_pool.h"
15#include "media/ffmpeg/ffmpeg_deleters.h"
16
17struct AVCodecContext;
18struct AVFrame;
19
20namespace base {
21class SingleThreadTaskRunner;
22}
23
24namespace media {
25
26class DecoderBuffer;
27
28class MEDIA_EXPORT FFmpegVideoDecoder : public VideoDecoder {
29 public:
30  explicit FFmpegVideoDecoder(
31      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
32  virtual ~FFmpegVideoDecoder();
33
34  // Allow decoding of individual NALU. Entire frames are required by default.
35  // Disables low-latency mode. Must be called before Initialize().
36  void set_decode_nalus(bool decode_nalus) { decode_nalus_ = decode_nalus; }
37
38  // VideoDecoder implementation.
39  virtual std::string GetDisplayName() const OVERRIDE;
40  virtual void Initialize(const VideoDecoderConfig& config,
41                          bool low_delay,
42                          const PipelineStatusCB& status_cb,
43                          const OutputCB& output_cb) OVERRIDE;
44  virtual void Decode(const scoped_refptr<DecoderBuffer>& buffer,
45                      const DecodeCB& decode_cb) OVERRIDE;
46  virtual void Reset(const base::Closure& closure) OVERRIDE;
47
48  // Callback called from within FFmpeg to allocate a buffer based on
49  // the dimensions of |codec_context|. See AVCodecContext.get_buffer2
50  // documentation inside FFmpeg.
51  int GetVideoBuffer(struct AVCodecContext* codec_context,
52                     AVFrame* frame,
53                     int flags);
54
55 private:
56  enum DecoderState {
57    kUninitialized,
58    kNormal,
59    kDecodeFinished,
60    kError
61  };
62
63  // Handles decoding an unencrypted encoded buffer.
64  bool FFmpegDecode(const scoped_refptr<DecoderBuffer>& buffer,
65                    bool* has_produced_frame);
66
67  // Handles (re-)initializing the decoder with a (new) config.
68  // Returns true if initialization was successful.
69  bool ConfigureDecoder(bool low_delay);
70
71  // Releases resources associated with |codec_context_| and |av_frame_|
72  // and resets them to NULL.
73  void ReleaseFFmpegResources();
74
75  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
76
77  DecoderState state_;
78
79  OutputCB output_cb_;
80
81  // FFmpeg structures owned by this object.
82  scoped_ptr<AVCodecContext, ScopedPtrAVFreeContext> codec_context_;
83  scoped_ptr<AVFrame, ScopedPtrAVFreeFrame> av_frame_;
84
85  VideoDecoderConfig config_;
86
87  VideoFramePool frame_pool_;
88
89  bool decode_nalus_;
90
91  DISALLOW_COPY_AND_ASSIGN(FFmpegVideoDecoder);
92};
93
94}  // namespace media
95
96#endif  // MEDIA_FILTERS_FFMPEG_VIDEO_DECODER_H_
97