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 #ifndef MEDIA_FILTERS_FFMPEG_AUDIO_DECODER_H_
      6 #define MEDIA_FILTERS_FFMPEG_AUDIO_DECODER_H_
      7 
      8 #include <list>
      9 
     10 #include "base/callback.h"
     11 #include "base/memory/scoped_ptr.h"
     12 #include "base/time/time.h"
     13 #include "media/base/audio_decoder.h"
     14 #include "media/base/demuxer_stream.h"
     15 #include "media/base/media_log.h"
     16 #include "media/base/sample_format.h"
     17 #include "media/ffmpeg/ffmpeg_deleters.h"
     18 
     19 struct AVCodecContext;
     20 struct AVFrame;
     21 
     22 namespace base {
     23 class SingleThreadTaskRunner;
     24 }
     25 
     26 namespace media {
     27 
     28 class AudioDiscardHelper;
     29 class DecoderBuffer;
     30 
     31 class MEDIA_EXPORT FFmpegAudioDecoder : public AudioDecoder {
     32  public:
     33   FFmpegAudioDecoder(
     34       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
     35       const LogCB& log_cb);
     36   virtual ~FFmpegAudioDecoder();
     37 
     38   // AudioDecoder implementation.
     39   virtual std::string GetDisplayName() const OVERRIDE;
     40   virtual void Initialize(const AudioDecoderConfig& config,
     41                           const PipelineStatusCB& status_cb,
     42                           const OutputCB& output_cb) OVERRIDE;
     43   virtual void Decode(const scoped_refptr<DecoderBuffer>& buffer,
     44                       const DecodeCB& decode_cb) OVERRIDE;
     45   virtual void Reset(const base::Closure& closure) OVERRIDE;
     46 
     47  private:
     48   // There are four states the decoder can be in:
     49   //
     50   // - kUninitialized: The decoder is not initialized.
     51   // - kNormal: This is the normal state. The decoder is idle and ready to
     52   //            decode input buffers, or is decoding an input buffer.
     53   // - kDecodeFinished: EOS buffer received, codec flushed and decode finished.
     54   //                    No further Decode() call should be made.
     55   // - kError: Unexpected error happened.
     56   //
     57   // These are the possible state transitions.
     58   //
     59   // kUninitialized -> kNormal:
     60   //     The decoder is successfully initialized and is ready to decode buffers.
     61   // kNormal -> kDecodeFinished:
     62   //     When buffer->end_of_stream() is true and avcodec_decode_audio4()
     63   //     returns 0 data.
     64   // kNormal -> kError:
     65   //     A decoding error occurs and decoding needs to stop.
     66   // (any state) -> kNormal:
     67   //     Any time Reset() is called.
     68   enum DecoderState {
     69     kUninitialized,
     70     kNormal,
     71     kDecodeFinished,
     72     kError
     73   };
     74 
     75   // Reset decoder and call |reset_cb_|.
     76   void DoReset();
     77 
     78   // Handles decoding an unencrypted encoded buffer.
     79   void DecodeBuffer(const scoped_refptr<DecoderBuffer>& buffer,
     80                     const DecodeCB& decode_cb);
     81   bool FFmpegDecode(const scoped_refptr<DecoderBuffer>& buffer,
     82                     bool* has_produced_frame);
     83 
     84   // Handles (re-)initializing the decoder with a (new) config.
     85   // Returns true if initialization was successful.
     86   bool ConfigureDecoder();
     87 
     88   // Releases resources associated with |codec_context_| and |av_frame_|
     89   // and resets them to NULL.
     90   void ReleaseFFmpegResources();
     91   void ResetTimestampState();
     92 
     93   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
     94 
     95   OutputCB output_cb_;
     96 
     97   DecoderState state_;
     98 
     99   // FFmpeg structures owned by this object.
    100   scoped_ptr<AVCodecContext, ScopedPtrAVFreeContext> codec_context_;
    101   scoped_ptr<AVFrame, ScopedPtrAVFreeFrame> av_frame_;
    102 
    103   AudioDecoderConfig config_;
    104 
    105   // AVSampleFormat initially requested; not Chrome's SampleFormat.
    106   int av_sample_format_;
    107 
    108   scoped_ptr<AudioDiscardHelper> discard_helper_;
    109 
    110   LogCB log_cb_;
    111 
    112   DISALLOW_IMPLICIT_CONSTRUCTORS(FFmpegAudioDecoder);
    113 };
    114 
    115 }  // namespace media
    116 
    117 #endif  // MEDIA_FILTERS_FFMPEG_AUDIO_DECODER_H_
    118