ffmpeg_video_decoder.h revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef MEDIA_FILTERS_FFMPEG_VIDEO_DECODER_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MEDIA_FILTERS_FFMPEG_VIDEO_DECODER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <list>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/weak_ptr.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/demuxer_stream.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/video_decoder.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct AVCodecContext;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct AVFrame;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MessageLoopProxy;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DecoderBuffer;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MEDIA_EXPORT FFmpegVideoDecoder : public VideoDecoder {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit FFmpegVideoDecoder(
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const scoped_refptr<base::MessageLoopProxy>& message_loop);
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~FFmpegVideoDecoder();
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // VideoDecoder implementation.
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void Initialize(DemuxerStream* stream,
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const PipelineStatusCB& status_cb,
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const StatisticsCB& statistics_cb) OVERRIDE;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Read(const ReadCB& read_cb) OVERRIDE;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Reset(const base::Closure& closure) OVERRIDE;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Stop(const base::Closure& closure) OVERRIDE;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback called from within FFmpeg to allocate a buffer based on
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the dimensions of |codec_context|. See AVCodecContext.get_buffer
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // documentation inside FFmpeg.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int GetVideoBuffer(AVCodecContext *codec_context, AVFrame* frame);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum DecoderState {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUninitialized,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kNormal,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kFlushCodec,
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    kDecodeFinished,
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    kError
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Reads from the demuxer stream and corresponding read callback.
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ReturnFrameOrReadFromDemuxerStream();
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void BufferReady(DemuxerStream::Status status,
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   const scoped_refptr<DecoderBuffer>& buffer);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Handles decoding an unencrypted encoded buffer.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DecodeBuffer(const scoped_refptr<DecoderBuffer>& buffer);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Decode(const scoped_refptr<DecoderBuffer>& buffer,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              scoped_refptr<VideoFrame>* video_frame);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handles (re-)initializing the decoder with a (new) config.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if initialization was successful.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ConfigureDecoder();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Releases resources associated with |codec_context_| and |av_frame_|
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and resets them to NULL.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ReleaseFFmpegResources();
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset decoder and call |reset_cb_|.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DoReset();
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> message_loop_;
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::WeakPtrFactory<FFmpegVideoDecoder> weak_factory_;
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::WeakPtr<FFmpegVideoDecoder> weak_this_;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DecoderState state_;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StatisticsCB statistics_cb_;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReadCB read_cb_;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Closure reset_cb_;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // FFmpeg structures owned by this object.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AVCodecContext* codec_context_;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AVFrame* av_frame_;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Pointer to the demuxer stream that will feed us compressed buffers.
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DemuxerStream* demuxer_stream_;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::list<scoped_refptr<VideoFrame> > decoded_frames_;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FFmpegVideoDecoder);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // MEDIA_FILTERS_FFMPEG_VIDEO_DECODER_H_
101