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