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 // Audio rendering unit utilizing an AudioRendererSink to output data.
      6 //
      7 // This class lives inside three threads during it's lifetime, namely:
      8 // 1. Render thread
      9 //    Where the object is created.
     10 // 2. Media thread (provided via constructor)
     11 //    All AudioDecoder methods are called on this thread.
     12 // 3. Audio thread created by the AudioRendererSink.
     13 //    Render() is called here where audio data is decoded into raw PCM data.
     14 //
     15 // AudioRendererImpl talks to an AudioRendererAlgorithm that takes care of
     16 // queueing audio data and stretching/shrinking audio data when playback rate !=
     17 // 1.0 or 0.0.
     18 
     19 #ifndef MEDIA_FILTERS_AUDIO_RENDERER_IMPL_H_
     20 #define MEDIA_FILTERS_AUDIO_RENDERER_IMPL_H_
     21 
     22 #include <deque>
     23 
     24 #include "base/gtest_prod_util.h"
     25 #include "base/memory/weak_ptr.h"
     26 #include "base/synchronization/lock.h"
     27 #include "media/base/audio_decoder.h"
     28 #include "media/base/audio_renderer.h"
     29 #include "media/base/audio_renderer_sink.h"
     30 #include "media/base/decryptor.h"
     31 #include "media/filters/audio_renderer_algorithm.h"
     32 
     33 namespace base {
     34 class MessageLoopProxy;
     35 }
     36 
     37 namespace media {
     38 
     39 class AudioBus;
     40 class AudioDecoderSelector;
     41 class AudioSplicer;
     42 class DecryptingDemuxerStream;
     43 
     44 class MEDIA_EXPORT AudioRendererImpl
     45     : public AudioRenderer,
     46       NON_EXPORTED_BASE(public AudioRendererSink::RenderCallback) {
     47  public:
     48   // |message_loop| is the thread on which AudioRendererImpl will execute.
     49   //
     50   // |sink| is used as the destination for the rendered audio.
     51   //
     52   // |decoders| contains the AudioDecoders to use when initializing.
     53   //
     54   // |set_decryptor_ready_cb| is fired when the audio decryptor is available
     55   // (only applicable if the stream is encrypted and we have a decryptor).
     56   AudioRendererImpl(const scoped_refptr<base::MessageLoopProxy>& message_loop,
     57                     AudioRendererSink* sink,
     58                     ScopedVector<AudioDecoder> decoders,
     59                     const SetDecryptorReadyCB& set_decryptor_ready_cb);
     60   virtual ~AudioRendererImpl();
     61 
     62   // AudioRenderer implementation.
     63   virtual void Initialize(DemuxerStream* stream,
     64                           const PipelineStatusCB& init_cb,
     65                           const StatisticsCB& statistics_cb,
     66                           const base::Closure& underflow_cb,
     67                           const TimeCB& time_cb,
     68                           const base::Closure& ended_cb,
     69                           const base::Closure& disabled_cb,
     70                           const PipelineStatusCB& error_cb) OVERRIDE;
     71   virtual void Play(const base::Closure& callback) OVERRIDE;
     72   virtual void Pause(const base::Closure& callback) OVERRIDE;
     73   virtual void Flush(const base::Closure& callback) OVERRIDE;
     74   virtual void Stop(const base::Closure& callback) OVERRIDE;
     75   virtual void SetPlaybackRate(float rate) OVERRIDE;
     76   virtual void Preroll(base::TimeDelta time,
     77                        const PipelineStatusCB& cb) OVERRIDE;
     78   virtual void ResumeAfterUnderflow() OVERRIDE;
     79   virtual void SetVolume(float volume) OVERRIDE;
     80 
     81   // Disables underflow support.  When used, |state_| will never transition to
     82   // kUnderflow resulting in Render calls that underflow returning 0 frames
     83   // instead of some number of silence frames.  Must be called prior to
     84   // Initialize().
     85   void DisableUnderflowForTesting();
     86 
     87   // Allows injection of a custom time callback for non-realtime testing.
     88   typedef base::Callback<base::TimeTicks()> NowCB;
     89   void set_now_cb_for_testing(const NowCB& now_cb) {
     90     now_cb_ = now_cb;
     91   }
     92 
     93  private:
     94   friend class AudioRendererImplTest;
     95 
     96   // TODO(acolwell): Add a state machine graph.
     97   enum State {
     98     kUninitialized,
     99     kPaused,
    100     kFlushing,
    101     kPrerolling,
    102     kPlaying,
    103     kStopped,
    104     kUnderflow,
    105     kRebuffering,
    106   };
    107 
    108   // Callback from the audio decoder delivering decoded audio samples.
    109   void DecodedAudioReady(AudioDecoder::Status status,
    110                          const scoped_refptr<AudioBuffer>& buffer);
    111 
    112   // Handles buffers that come out of |splicer_|.
    113   // Returns true if more buffers are needed.
    114   bool HandleSplicerBuffer(const scoped_refptr<AudioBuffer>& buffer);
    115 
    116   // Helper functions for AudioDecoder::Status values passed to
    117   // DecodedAudioReady().
    118   void HandleAbortedReadOrDecodeError(bool is_decode_error);
    119 
    120   // Estimate earliest time when current buffer can stop playing.
    121   void UpdateEarliestEndTime_Locked(int frames_filled,
    122                                     const base::TimeDelta& playback_delay,
    123                                     const base::TimeTicks& time_now);
    124 
    125   void DoPlay_Locked();
    126   void DoPause_Locked();
    127 
    128   // AudioRendererSink::RenderCallback implementation.
    129   //
    130   // NOTE: These are called on the audio callback thread!
    131   //
    132   // Render() fills the given buffer with audio data by delegating to its
    133   // |algorithm_|. Render() also takes care of updating the clock.
    134   // Returns the number of frames copied into |audio_bus|, which may be less
    135   // than or equal to the initial number of frames in |audio_bus|
    136   //
    137   // If this method returns fewer frames than the initial number of frames in
    138   // |audio_bus|, it could be a sign that the pipeline is stalled or unable to
    139   // stream the data fast enough.  In such scenarios, the callee should zero out
    140   // unused portions of their buffer to play back silence.
    141   //
    142   // Render() updates the pipeline's playback timestamp. If Render() is
    143   // not called at the same rate as audio samples are played, then the reported
    144   // timestamp in the pipeline will be ahead of the actual audio playback. In
    145   // this case |audio_delay_milliseconds| should be used to indicate when in the
    146   // future should the filled buffer be played.
    147   virtual int Render(AudioBus* audio_bus,
    148                      int audio_delay_milliseconds) OVERRIDE;
    149   virtual void OnRenderError() OVERRIDE;
    150 
    151   // Helper methods that schedule an asynchronous read from the decoder as long
    152   // as there isn't a pending read.
    153   //
    154   // Must be called on |message_loop_|.
    155   void AttemptRead();
    156   void AttemptRead_Locked();
    157   bool CanRead_Locked();
    158   void ChangeState_Locked(State new_state);
    159 
    160   // Returns true if the data in the buffer is all before
    161   // |preroll_timestamp_|. This can only return true while
    162   // in the kPrerolling state.
    163   bool IsBeforePrerollTime(const scoped_refptr<AudioBuffer>& buffer);
    164 
    165   // Called when |decoder_selector_| has selected |decoder| or is null if no
    166   // decoder could be selected.
    167   //
    168   // |decrypting_demuxer_stream| is non-null if a DecryptingDemuxerStream was
    169   // created to help decrypt the encrypted stream.
    170   void OnDecoderSelected(
    171       scoped_ptr<AudioDecoder> decoder,
    172       scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream);
    173 
    174   // Used to initiate the flush operation once all pending reads have
    175   // completed.
    176   void DoFlush_Locked();
    177 
    178   // Calls |decoder_|.Reset() and arranges for ResetDecoderDone() to get
    179   // called when the reset completes.
    180   void ResetDecoder();
    181 
    182   // Called when the |decoder_|.Reset() has completed.
    183   void ResetDecoderDone();
    184 
    185   scoped_refptr<base::MessageLoopProxy> message_loop_;
    186   base::WeakPtrFactory<AudioRendererImpl> weak_factory_;
    187   base::WeakPtr<AudioRendererImpl> weak_this_;
    188 
    189   scoped_ptr<AudioSplicer> splicer_;
    190 
    191   // The sink (destination) for rendered audio. |sink_| must only be accessed
    192   // on |message_loop_|. |sink_| must never be called under |lock_| or else we
    193   // may deadlock between |message_loop_| and the audio callback thread.
    194   scoped_refptr<media::AudioRendererSink> sink_;
    195 
    196   scoped_ptr<AudioDecoderSelector> decoder_selector_;
    197 
    198   // These two will be set by AudioDecoderSelector::SelectAudioDecoder().
    199   scoped_ptr<AudioDecoder> decoder_;
    200   scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream_;
    201 
    202   // AudioParameters constructed during Initialize() based on |decoder_|.
    203   AudioParameters audio_parameters_;
    204 
    205   // Callbacks provided during Initialize().
    206   PipelineStatusCB init_cb_;
    207   StatisticsCB statistics_cb_;
    208   base::Closure underflow_cb_;
    209   TimeCB time_cb_;
    210   base::Closure ended_cb_;
    211   base::Closure disabled_cb_;
    212   PipelineStatusCB error_cb_;
    213 
    214   // Callback provided to Flush().
    215   base::Closure flush_cb_;
    216 
    217   // Callback provided to Preroll().
    218   PipelineStatusCB preroll_cb_;
    219 
    220   // Typically calls base::TimeTicks::Now() but can be overridden by a test.
    221   NowCB now_cb_;
    222 
    223   // After Initialize() has completed, all variables below must be accessed
    224   // under |lock_|. ------------------------------------------------------------
    225   base::Lock lock_;
    226 
    227   // Algorithm for scaling audio.
    228   scoped_ptr<AudioRendererAlgorithm> algorithm_;
    229 
    230   // Simple state tracking variable.
    231   State state_;
    232 
    233   // Keep track of whether or not the sink is playing.
    234   bool sink_playing_;
    235 
    236   // Keep track of our outstanding read to |decoder_|.
    237   bool pending_read_;
    238 
    239   // Keeps track of whether we received and rendered the end of stream buffer.
    240   bool received_end_of_stream_;
    241   bool rendered_end_of_stream_;
    242 
    243   // The timestamp of the last frame (i.e. furthest in the future) buffered as
    244   // well as the current time that takes current playback delay into account.
    245   base::TimeDelta audio_time_buffered_;
    246   base::TimeDelta current_time_;
    247 
    248   base::TimeDelta preroll_timestamp_;
    249 
    250   // We're supposed to know amount of audio data OS or hardware buffered, but
    251   // that is not always so -- on my Linux box
    252   // AudioBuffersState::hardware_delay_bytes never reaches 0.
    253   //
    254   // As a result we cannot use it to find when stream ends. If we just ignore
    255   // buffered data we will notify host that stream ended before it is actually
    256   // did so, I've seen it done ~140ms too early when playing ~150ms file.
    257   //
    258   // Instead of trying to invent OS-specific solution for each and every OS we
    259   // are supporting, use simple workaround: every time we fill the buffer we
    260   // remember when it should stop playing, and do not assume that buffer is
    261   // empty till that time. Workaround is not bulletproof, as we don't exactly
    262   // know when that particular data would start playing, but it is much better
    263   // than nothing.
    264   base::TimeTicks earliest_end_time_;
    265   size_t total_frames_filled_;
    266 
    267   bool underflow_disabled_;
    268 
    269   // True if the renderer receives a buffer with kAborted status during preroll,
    270   // false otherwise. This flag is cleared on the next Preroll() call.
    271   bool preroll_aborted_;
    272 
    273   // End variables which must be accessed under |lock_|. ----------------------
    274 
    275   DISALLOW_COPY_AND_ASSIGN(AudioRendererImpl);
    276 };
    277 
    278 }  // namespace media
    279 
    280 #endif  // MEDIA_FILTERS_AUDIO_RENDERER_IMPL_H_
    281