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_AUDIO_DECODER_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MEDIA_FILTERS_FFMPEG_AUDIO_DECODER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <list>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
1168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/audio_decoder.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/demuxer_stream.h"
15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "media/base/media_log.h"
167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "media/base/sample_format.h"
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "media/ffmpeg/ffmpeg_deleters.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct AVCodecContext;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct AVFrame;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class SingleThreadTaskRunner;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass AudioDiscardHelper;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DecoderBuffer;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MEDIA_EXPORT FFmpegAudioDecoder : public AudioDecoder {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  FFmpegAudioDecoder(
34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      const LogCB& log_cb);
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~FFmpegAudioDecoder();
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // AudioDecoder implementation.
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual std::string GetDisplayName() const OVERRIDE;
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void Initialize(const AudioDecoderConfig& config,
41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                          const PipelineStatusCB& status_cb,
42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                          const OutputCB& output_cb) OVERRIDE;
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void Decode(const scoped_refptr<DecoderBuffer>& buffer,
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                      const DecodeCB& decode_cb) OVERRIDE;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Reset(const base::Closure& closure) OVERRIDE;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // There are four states the decoder can be in:
496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  //
506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // - kUninitialized: The decoder is not initialized.
516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // - kNormal: This is the normal state. The decoder is idle and ready to
526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  //            decode input buffers, or is decoding an input buffer.
536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // - kDecodeFinished: EOS buffer received, codec flushed and decode finished.
546d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  //                    No further Decode() call should be made.
556d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // - kError: Unexpected error happened.
566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  //
576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // These are the possible state transitions.
586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  //
596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // kUninitialized -> kNormal:
606d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  //     The decoder is successfully initialized and is ready to decode buffers.
616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // kNormal -> kDecodeFinished:
626d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  //     When buffer->end_of_stream() is true and avcodec_decode_audio4()
636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  //     returns 0 data.
646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // kNormal -> kError:
656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  //     A decoding error occurs and decoding needs to stop.
666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // (any state) -> kNormal:
676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  //     Any time Reset() is called.
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  enum DecoderState {
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    kUninitialized,
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    kNormal,
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    kDecodeFinished,
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    kError
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  };
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Reset decoder and call |reset_cb_|.
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void DoReset();
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Handles decoding an unencrypted encoded buffer.
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void DecodeBuffer(const scoped_refptr<DecoderBuffer>& buffer,
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    const DecodeCB& decode_cb);
816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  bool FFmpegDecode(const scoped_refptr<DecoderBuffer>& buffer,
826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                    bool* has_produced_frame);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Handles (re-)initializing the decoder with a (new) config.
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Returns true if initialization was successful.
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool ConfigureDecoder();
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Releases resources associated with |codec_context_| and |av_frame_|
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // and resets them to NULL.
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ReleaseFFmpegResources();
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ResetTimestampState();
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  OutputCB output_cb_;
96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DecoderState state_;
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // FFmpeg structures owned by this object.
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<AVCodecContext, ScopedPtrAVFreeContext> codec_context_;
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<AVFrame, ScopedPtrAVFreeFrame> av_frame_;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  AudioDecoderConfig config_;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // AVSampleFormat initially requested; not Chrome's SampleFormat.
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int av_sample_format_;
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_ptr<AudioDiscardHelper> discard_helper_;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  LogCB log_cb_;
111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_IMPLICIT_CONSTRUCTORS(FFmpegAudioDecoder);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // MEDIA_FILTERS_FFMPEG_AUDIO_DECODER_H_
118