audio_renderer_impl.h revision 868fa2fe829687343ffae624259930155e16dbd8
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)// Audio rendering unit utilizing an AudioRendererSink to output data.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class lives inside three threads during it's lifetime, namely:
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1. Render thread
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    Where the object is created.
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 2. Media thread (provided via constructor)
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    All AudioDecoder methods are called on this thread.
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3. Audio thread created by the AudioRendererSink.
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    Render() is called here where audio data is decoded into raw PCM data.
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AudioRendererImpl talks to an AudioRendererAlgorithm that takes care of
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// queueing audio data and stretching/shrinking audio data when playback rate !=
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1.0 or 0.0.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef MEDIA_FILTERS_AUDIO_RENDERER_IMPL_H_
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MEDIA_FILTERS_AUDIO_RENDERER_IMPL_H_
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <deque>
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/gtest_prod_util.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/weak_ptr.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/audio_decoder.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/audio_renderer.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/audio_renderer_sink.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/decryptor.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/filters/audio_renderer_algorithm.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace base {
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MessageLoopProxy;
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AudioDecoderSelector;
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AudioSplicer;
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DecryptingDemuxerStream;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MEDIA_EXPORT AudioRendererImpl
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public AudioRenderer,
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NON_EXPORTED_BASE(public AudioRendererSink::RenderCallback) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |message_loop| is the thread on which AudioRendererImpl will execute.
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |sink| is used as the destination for the rendered audio.
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |decoders| contains the AudioDecoders to use when initializing.
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |set_decryptor_ready_cb| is fired when the audio decryptor is available
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // (only applicable if the stream is encrypted and we have a decryptor).
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  //
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // |increase_preroll_on_underflow| Set to true if the preroll duration
57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // should be increased when ResumeAfterUnderflow() is called.
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AudioRendererImpl(const scoped_refptr<base::MessageLoopProxy>& message_loop,
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    AudioRendererSink* sink,
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    ScopedVector<AudioDecoder> decoders,
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    const SetDecryptorReadyCB& set_decryptor_ready_cb,
62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    bool increase_preroll_on_underflow);
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~AudioRendererImpl();
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // AudioRenderer implementation.
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void Initialize(DemuxerStream* stream,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const PipelineStatusCB& init_cb,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const StatisticsCB& statistics_cb,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const base::Closure& underflow_cb,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const TimeCB& time_cb,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const base::Closure& ended_cb,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const base::Closure& disabled_cb,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const PipelineStatusCB& error_cb) OVERRIDE;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Play(const base::Closure& callback) OVERRIDE;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Pause(const base::Closure& callback) OVERRIDE;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Flush(const base::Closure& callback) OVERRIDE;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Stop(const base::Closure& callback) OVERRIDE;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetPlaybackRate(float rate) OVERRIDE;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Preroll(base::TimeDelta time,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const PipelineStatusCB& cb) OVERRIDE;
81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void ResumeAfterUnderflow() OVERRIDE;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetVolume(float volume) OVERRIDE;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disables underflow support.  When used, |state_| will never transition to
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // kUnderflow resulting in Render calls that underflow returning 0 frames
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // instead of some number of silence frames.  Must be called prior to
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initialize().
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DisableUnderflowForTesting();
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Allows injection of a custom time callback for non-realtime testing.
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef base::Callback<base::Time()> NowCB;
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_now_cb_for_testing(const NowCB& now_cb) {
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    now_cb_ = now_cb;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class AudioRendererImplTest;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback from the audio decoder delivering decoded audio samples.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DecodedAudioReady(AudioDecoder::Status status,
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         const scoped_refptr<DataBuffer>& buffer);
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Handles buffers that come out of |splicer_|.
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true if more buffers are needed.
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool HandleSplicerBuffer(const scoped_refptr<DataBuffer>& buffer);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper functions for AudioDecoder::Status values passed to
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DecodedAudioReady().
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleAbortedReadOrDecodeError(bool is_decode_error);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fills the given buffer with audio data by delegating to its |algorithm_|.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // FillBuffer() also takes care of updating the clock. Returns the number of
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // frames copied into |dest|, which may be less than or equal to
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |requested_frames|.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If this method returns fewer frames than |requested_frames|, it could
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be a sign that the pipeline is stalled or unable to stream the data fast
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // enough.  In such scenarios, the callee should zero out unused portions
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of their buffer to playback silence.
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // FillBuffer() updates the pipeline's playback timestamp. If FillBuffer() is
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not called at the same rate as audio samples are played, then the reported
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // timestamp in the pipeline will be ahead of the actual audio playback. In
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this case |playback_delay| should be used to indicate when in the future
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should the filled buffer be played.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Safe to call on any thread.
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 FillBuffer(uint8* dest,
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    uint32 requested_frames,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    int audio_delay_milliseconds);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Estimate earliest time when current buffer can stop playing.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateEarliestEndTime_Locked(int frames_filled,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    base::TimeDelta playback_delay,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    base::Time time_now);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DoPlay();
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DoPause();
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // AudioRendererSink::RenderCallback implementation.
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // NOTE: These are called on the audio callback thread!
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int Render(AudioBus* audio_bus,
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     int audio_delay_milliseconds) OVERRIDE;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnRenderError() OVERRIDE;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Helper methods that schedule an asynchronous read from the decoder as long
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // as there isn't a pending read.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Must be called on |message_loop_|.
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AttemptRead();
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AttemptRead_Locked();
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool CanRead_Locked();
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the data in the buffer is all before
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |preroll_timestamp_|. This can only return true while
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the kPrerolling state.
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool IsBeforePrerollTime(const scoped_refptr<DataBuffer>& buffer);
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Called when |decoder_selector_| has selected |decoder| or is null if no
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // decoder could be selected.
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |decrypting_demuxer_stream| is non-null if a DecryptingDemuxerStream was
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // created to help decrypt the encrypted stream.
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnDecoderSelected(
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_ptr<AudioDecoder> decoder,
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream);
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ResetDecoder(const base::Closure& callback);
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> message_loop_;
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::WeakPtrFactory<AudioRendererImpl> weak_factory_;
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::WeakPtr<AudioRendererImpl> weak_this_;
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<AudioSplicer> splicer_;
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The sink (destination) for rendered audio. |sink_| must only be accessed
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // on |message_loop_|. |sink_| must never be called under |lock_| or else we
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // may deadlock between |message_loop_| and the audio callback thread.
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<media::AudioRendererSink> sink_;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<AudioDecoderSelector> decoder_selector_;
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // These two will be set by AudioDecoderSelector::SelectAudioDecoder().
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<AudioDecoder> decoder_;
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream_;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // AudioParameters constructed during Initialize() based on |decoder_|.
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AudioParameters audio_parameters_;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callbacks provided during Initialize().
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PipelineStatusCB init_cb_;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StatisticsCB statistics_cb_;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Closure underflow_cb_;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeCB time_cb_;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Closure ended_cb_;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Closure disabled_cb_;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PipelineStatusCB error_cb_;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback provided to Pause().
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Closure pause_cb_;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback provided to Preroll().
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PipelineStatusCB preroll_cb_;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Typically calls base::Time::Now() but can be overridden by a test.
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NowCB now_cb_;
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After Initialize() has completed, all variables below must be accessed
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // under |lock_|. ------------------------------------------------------------
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Lock lock_;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Algorithm for scaling audio.
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<AudioRendererAlgorithm> algorithm_;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simple state tracking variable.
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum State {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUninitialized,
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kPaused,
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kPrerolling,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kPlaying,
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kStopped,
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUnderflow,
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kRebuffering,
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  State state_;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Keep track of whether or not the sink is playing.
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool sink_playing_;
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Keep track of our outstanding read to |decoder_|.
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool pending_read_;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Keeps track of whether we received and rendered the end of stream buffer.
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool received_end_of_stream_;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool rendered_end_of_stream_;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The timestamp of the last frame (i.e. furthest in the future) buffered as
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // well as the current time that takes current playback delay into account.
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta audio_time_buffered_;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta current_time_;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta preroll_timestamp_;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We're supposed to know amount of audio data OS or hardware buffered, but
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that is not always so -- on my Linux box
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // AudioBuffersState::hardware_delay_bytes never reaches 0.
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // As a result we cannot use it to find when stream ends. If we just ignore
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // buffered data we will notify host that stream ended before it is actually
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // did so, I've seen it done ~140ms too early when playing ~150ms file.
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Instead of trying to invent OS-specific solution for each and every OS we
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are supporting, use simple workaround: every time we fill the buffer we
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // remember when it should stop playing, and do not assume that buffer is
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // empty till that time. Workaround is not bulletproof, as we don't exactly
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // know when that particular data would start playing, but it is much better
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // than nothing.
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time earliest_end_time_;
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t total_frames_filled_;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool underflow_disabled_;
263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool increase_preroll_on_underflow_;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // True if the renderer receives a buffer with kAborted status during preroll,
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // false otherwise. This flag is cleared on the next Preroll() call.
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool preroll_aborted_;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // End variables which must be accessed under |lock_|. ----------------------
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Variables used only on the audio thread. ---------------------------------
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int actual_frames_per_buffer_;
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<uint8[]> audio_buffer_;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AudioRendererImpl);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // MEDIA_FILTERS_AUDIO_RENDERER_IMPL_H_
281