summaryrefslogtreecommitdiffstats
path: root/chromium/media/filters/ffmpeg_audio_decoder.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/media/filters/ffmpeg_audio_decoder.h')
-rw-r--r--chromium/media/filters/ffmpeg_audio_decoder.h116
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);
};