diff options
Diffstat (limited to 'chromium/media/filters/ffmpeg_audio_decoder.h')
-rw-r--r-- | chromium/media/filters/ffmpeg_audio_decoder.h | 116 |
1 files changed, 64 insertions, 52 deletions
diff --git a/chromium/media/filters/ffmpeg_audio_decoder.h b/chromium/media/filters/ffmpeg_audio_decoder.h index 40103b8d751..39a408973dc 100644 --- a/chromium/media/filters/ffmpeg_audio_decoder.h +++ b/chromium/media/filters/ffmpeg_audio_decoder.h @@ -9,93 +9,105 @@ #include "base/callback.h" #include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "media/base/audio_decoder.h" #include "media/base/demuxer_stream.h" +#include "media/base/media_log.h" #include "media/base/sample_format.h" +#include "media/ffmpeg/ffmpeg_deleters.h" struct AVCodecContext; struct AVFrame; namespace base { -class MessageLoopProxy; +class SingleThreadTaskRunner; } namespace media { -class AudioTimestampHelper; +class AudioDiscardHelper; class DecoderBuffer; -struct QueuedAudioBuffer; -class ScopedPtrAVFreeContext; -class ScopedPtrAVFreeFrame; class MEDIA_EXPORT FFmpegAudioDecoder : public AudioDecoder { public: - explicit FFmpegAudioDecoder( - const scoped_refptr<base::MessageLoopProxy>& message_loop); + FFmpegAudioDecoder( + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, + const LogCB& log_cb); virtual ~FFmpegAudioDecoder(); // AudioDecoder implementation. - virtual void Initialize(DemuxerStream* stream, + virtual void Initialize(const AudioDecoderConfig& config, const PipelineStatusCB& status_cb, - const StatisticsCB& statistics_cb) OVERRIDE; - virtual void Read(const ReadCB& read_cb) OVERRIDE; - virtual int bits_per_channel() OVERRIDE; - virtual ChannelLayout channel_layout() OVERRIDE; - virtual int samples_per_second() OVERRIDE; + const OutputCB& output_cb) OVERRIDE; + virtual void Decode(const scoped_refptr<DecoderBuffer>& buffer, + const DecodeCB& decode_cb) OVERRIDE; virtual void Reset(const base::Closure& closure) OVERRIDE; - - // Callback called from within FFmpeg to allocate a buffer based on - // the dimensions of |codec_context|. See AVCodecContext.get_buffer2 - // documentation inside FFmpeg. - int GetAudioBuffer(AVCodecContext* codec, AVFrame* frame, int flags); + virtual void Stop() OVERRIDE; private: - // Reads from the demuxer stream with corresponding callback method. - void ReadFromDemuxerStream(); - void BufferReady(DemuxerStream::Status status, - const scoped_refptr<DecoderBuffer>& input); - + // There are four states the decoder can be in: + // + // - kUninitialized: The decoder is not initialized. + // - kNormal: This is the normal state. The decoder is idle and ready to + // decode input buffers, or is decoding an input buffer. + // - kDecodeFinished: EOS buffer received, codec flushed and decode finished. + // No further Decode() call should be made. + // - kError: Unexpected error happened. + // + // These are the possible state transitions. + // + // kUninitialized -> kNormal: + // The decoder is successfully initialized and is ready to decode buffers. + // kNormal -> kDecodeFinished: + // When buffer->end_of_stream() is true and avcodec_decode_audio4() + // returns 0 data. + // kNormal -> kError: + // A decoding error occurs and decoding needs to stop. + // (any state) -> kNormal: + // Any time Reset() is called. + enum DecoderState { + kUninitialized, + kNormal, + kDecodeFinished, + kError + }; + + // Reset decoder and call |reset_cb_|. + void DoReset(); + + // Handles decoding an unencrypted encoded buffer. + void DecodeBuffer(const scoped_refptr<DecoderBuffer>& buffer, + const DecodeCB& decode_cb); + bool FFmpegDecode(const scoped_refptr<DecoderBuffer>& buffer, + bool* has_produced_frame); + + // Handles (re-)initializing the decoder with a (new) config. + // Returns true if initialization was successful. bool ConfigureDecoder(); + + // Releases resources associated with |codec_context_| and |av_frame_| + // and resets them to NULL. void ReleaseFFmpegResources(); void ResetTimestampState(); - void RunDecodeLoop(const scoped_refptr<DecoderBuffer>& input, - bool skip_eos_append); - - scoped_refptr<base::MessageLoopProxy> message_loop_; - base::WeakPtrFactory<FFmpegAudioDecoder> weak_factory_; - base::WeakPtr<FFmpegAudioDecoder> weak_this_; - DemuxerStream* demuxer_stream_; - StatisticsCB statistics_cb_; - scoped_ptr_malloc<AVCodecContext, ScopedPtrAVFreeContext> codec_context_; + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - // Decoded audio format. - int bytes_per_channel_; - ChannelLayout channel_layout_; - int channels_; - int samples_per_second_; + OutputCB output_cb_; - // AVSampleFormat initially requested; not Chrome's SampleFormat. - int av_sample_format_; - SampleFormat sample_format_; + DecoderState state_; - // Used for computing output timestamps. - scoped_ptr<AudioTimestampHelper> output_timestamp_helper_; - base::TimeDelta last_input_timestamp_; + // FFmpeg structures owned by this object. + scoped_ptr<AVCodecContext, ScopedPtrAVFreeContext> codec_context_; + scoped_ptr<AVFrame, ScopedPtrAVFreeFrame> av_frame_; - // Number of frames to drop before generating output buffers. - int output_frames_to_drop_; + AudioDecoderConfig config_; - // Holds decoded audio. - scoped_ptr_malloc<AVFrame, ScopedPtrAVFreeFrame> av_frame_; + // AVSampleFormat initially requested; not Chrome's SampleFormat. + int av_sample_format_; - ReadCB read_cb_; + scoped_ptr<AudioDiscardHelper> discard_helper_; - // Since multiple frames may be decoded from the same packet we need to queue - // them up and hand them out as we receive Read() calls. - std::list<QueuedAudioBuffer> queued_audio_; + LogCB log_cb_; DISALLOW_IMPLICIT_CONSTRUCTORS(FFmpegAudioDecoder); }; |