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)
397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochclass AudioBus;
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AudioDecoderSelector;
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AudioSplicer;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DecryptingDemuxerStream;
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MEDIA_EXPORT AudioRendererImpl
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public AudioRenderer,
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NON_EXPORTED_BASE(public AudioRendererSink::RenderCallback) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |message_loop| is the thread on which AudioRendererImpl will execute.
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |sink| is used as the destination for the rendered audio.
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |decoders| contains the AudioDecoders to use when initializing.
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |set_decryptor_ready_cb| is fired when the audio decryptor is available
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // (only applicable if the stream is encrypted and we have a decryptor).
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AudioRendererImpl(const scoped_refptr<base::MessageLoopProxy>& message_loop,
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    AudioRendererSink* sink,
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    ScopedVector<AudioDecoder> decoders,
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    const SetDecryptorReadyCB& set_decryptor_ready_cb);
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~AudioRendererImpl();
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // AudioRenderer implementation.
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void Initialize(DemuxerStream* stream,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const PipelineStatusCB& init_cb,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const StatisticsCB& statistics_cb,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const base::Closure& underflow_cb,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const TimeCB& time_cb,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const base::Closure& ended_cb,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const base::Closure& disabled_cb,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const PipelineStatusCB& error_cb) OVERRIDE;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Play(const base::Closure& callback) OVERRIDE;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Pause(const base::Closure& callback) OVERRIDE;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Flush(const base::Closure& callback) OVERRIDE;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Stop(const base::Closure& callback) OVERRIDE;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetPlaybackRate(float rate) OVERRIDE;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Preroll(base::TimeDelta time,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const PipelineStatusCB& cb) OVERRIDE;
78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void ResumeAfterUnderflow() OVERRIDE;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetVolume(float volume) OVERRIDE;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disables underflow support.  When used, |state_| will never transition to
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // kUnderflow resulting in Render calls that underflow returning 0 frames
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // instead of some number of silence frames.  Must be called prior to
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initialize().
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DisableUnderflowForTesting();
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Allows injection of a custom time callback for non-realtime testing.
887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef base::Callback<base::TimeTicks()> NowCB;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_now_cb_for_testing(const NowCB& now_cb) {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    now_cb_ = now_cb;
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class AudioRendererImplTest;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // TODO(acolwell): Add a state machine graph.
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  enum State {
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    kUninitialized,
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    kPaused,
100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    kFlushing,
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    kPrerolling,
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    kPlaying,
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    kStopped,
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    kUnderflow,
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    kRebuffering,
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback from the audio decoder delivering decoded audio samples.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DecodedAudioReady(AudioDecoder::Status status,
1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                         const scoped_refptr<AudioBuffer>& buffer);
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Handles buffers that come out of |splicer_|.
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true if more buffers are needed.
1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bool HandleSplicerBuffer(const scoped_refptr<AudioBuffer>& buffer);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper functions for AudioDecoder::Status values passed to
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DecodedAudioReady().
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleAbortedReadOrDecodeError(bool is_decode_error);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Estimate earliest time when current buffer can stop playing.
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateEarliestEndTime_Locked(int frames_filled,
1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                    const base::TimeDelta& playback_delay,
1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                    const base::TimeTicks& time_now);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void DoPlay_Locked();
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void DoPause_Locked();
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // AudioRendererSink::RenderCallback implementation.
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // NOTE: These are called on the audio callback thread!
1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  //
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Render() fills the given buffer with audio data by delegating to its
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |algorithm_|. Render() also takes care of updating the clock.
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Returns the number of frames copied into |audio_bus|, which may be less
1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // than or equal to the initial number of frames in |audio_bus|
1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  //
1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // If this method returns fewer frames than the initial number of frames in
1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |audio_bus|, it could be a sign that the pipeline is stalled or unable to
1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // stream the data fast enough.  In such scenarios, the callee should zero out
1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // unused portions of their buffer to play back silence.
1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  //
1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Render() updates the pipeline's playback timestamp. If Render() is
1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // not called at the same rate as audio samples are played, then the reported
1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // timestamp in the pipeline will be ahead of the actual audio playback. In
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // this case |audio_delay_milliseconds| should be used to indicate when in the
1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // future should the filled buffer be played.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int Render(AudioBus* audio_bus,
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     int audio_delay_milliseconds) OVERRIDE;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnRenderError() OVERRIDE;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Helper methods that schedule an asynchronous read from the decoder as long
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // as there isn't a pending read.
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Must be called on |message_loop_|.
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AttemptRead();
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AttemptRead_Locked();
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool CanRead_Locked();
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void ChangeState_Locked(State new_state);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the data in the buffer is all before
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |preroll_timestamp_|. This can only return true while
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the kPrerolling state.
1637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bool IsBeforePrerollTime(const scoped_refptr<AudioBuffer>& buffer);
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Called when |decoder_selector_| has selected |decoder| or is null if no
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // decoder could be selected.
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |decrypting_demuxer_stream| is non-null if a DecryptingDemuxerStream was
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // created to help decrypt the encrypted stream.
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnDecoderSelected(
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_ptr<AudioDecoder> decoder,
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream);
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Used to initiate the flush operation once all pending reads have
175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // completed.
176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void DoFlush_Locked();
177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Calls |decoder_|.Reset() and arranges for ResetDecoderDone() to get
179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // called when the reset completes.
180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void ResetDecoder();
181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Called when the |decoder_|.Reset() has completed.
183a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void ResetDecoderDone();
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> message_loop_;
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::WeakPtrFactory<AudioRendererImpl> weak_factory_;
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::WeakPtr<AudioRendererImpl> weak_this_;
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<AudioSplicer> splicer_;
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The sink (destination) for rendered audio. |sink_| must only be accessed
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // on |message_loop_|. |sink_| must never be called under |lock_| or else we
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // may deadlock between |message_loop_| and the audio callback thread.
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<media::AudioRendererSink> sink_;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<AudioDecoderSelector> decoder_selector_;
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // These two will be set by AudioDecoderSelector::SelectAudioDecoder().
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<AudioDecoder> decoder_;
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream_;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // AudioParameters constructed during Initialize() based on |decoder_|.
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AudioParameters audio_parameters_;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callbacks provided during Initialize().
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PipelineStatusCB init_cb_;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StatisticsCB statistics_cb_;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Closure underflow_cb_;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeCB time_cb_;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Closure ended_cb_;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Closure disabled_cb_;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PipelineStatusCB error_cb_;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Callback provided to Flush().
215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::Closure flush_cb_;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback provided to Preroll().
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PipelineStatusCB preroll_cb_;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Typically calls base::TimeTicks::Now() but can be overridden by a test.
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NowCB now_cb_;
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After Initialize() has completed, all variables below must be accessed
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // under |lock_|. ------------------------------------------------------------
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Lock lock_;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Algorithm for scaling audio.
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<AudioRendererAlgorithm> algorithm_;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simple state tracking variable.
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  State state_;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Keep track of whether or not the sink is playing.
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool sink_playing_;
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Keep track of our outstanding read to |decoder_|.
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool pending_read_;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Keeps track of whether we received and rendered the end of stream buffer.
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool received_end_of_stream_;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool rendered_end_of_stream_;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The timestamp of the last frame (i.e. furthest in the future) buffered as
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // well as the current time that takes current playback delay into account.
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta audio_time_buffered_;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta current_time_;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta preroll_timestamp_;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We're supposed to know amount of audio data OS or hardware buffered, but
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that is not always so -- on my Linux box
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // AudioBuffersState::hardware_delay_bytes never reaches 0.
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // As a result we cannot use it to find when stream ends. If we just ignore
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // buffered data we will notify host that stream ended before it is actually
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // did so, I've seen it done ~140ms too early when playing ~150ms file.
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Instead of trying to invent OS-specific solution for each and every OS we
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are supporting, use simple workaround: every time we fill the buffer we
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // remember when it should stop playing, and do not assume that buffer is
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // empty till that time. Workaround is not bulletproof, as we don't exactly
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // know when that particular data would start playing, but it is much better
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // than nothing.
2647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::TimeTicks earliest_end_time_;
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t total_frames_filled_;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool underflow_disabled_;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // True if the renderer receives a buffer with kAborted status during preroll,
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // false otherwise. This flag is cleared on the next Preroll() call.
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool preroll_aborted_;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // End variables which must be accessed under |lock_|. ----------------------
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