Reland revision 174161 (reverted in 174163 because it broke the build).
[chromium-blink-merge.git] / media / filters / audio_renderer_impl.h
blob9158aa1426fcb22cd97dfbed04b4243e0c9ea768
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.
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 // This object is created on the render thread.
10 // 2. Pipeline thread
11 // Initialize() is called here with the audio format.
12 // Play/Pause/Preroll() also happens here.
13 // 3. Audio thread created by the AudioRendererSink.
14 // Render() is called here where audio data is decoded into raw PCM data.
16 // AudioRendererImpl talks to an AudioRendererAlgorithm that takes care of
17 // queueing audio data and stretching/shrinking audio data when playback rate !=
18 // 1.0 or 0.0.
20 #ifndef MEDIA_FILTERS_AUDIO_RENDERER_IMPL_H_
21 #define MEDIA_FILTERS_AUDIO_RENDERER_IMPL_H_
23 #include <deque>
25 #include "base/gtest_prod_util.h"
26 #include "base/synchronization/lock.h"
27 #include "base/threading/thread_checker.h"
28 #include "media/base/audio_decoder.h"
29 #include "media/base/audio_renderer.h"
30 #include "media/base/audio_renderer_sink.h"
31 #include "media/base/buffers.h"
32 #include "media/base/decryptor.h"
33 #include "media/filters/audio_renderer_algorithm.h"
35 namespace media {
37 class AudioDecoderSelector;
38 class AudioSplicer;
39 class DecryptingDemuxerStream;
41 class MEDIA_EXPORT AudioRendererImpl
42 : public AudioRenderer,
43 NON_EXPORTED_BASE(public AudioRendererSink::RenderCallback) {
44 public:
45 // Methods called on Render thread ------------------------------------------
46 // An AudioRendererSink is used as the destination for the rendered audio.
47 AudioRendererImpl(AudioRendererSink* sink,
48 const SetDecryptorReadyCB& set_decryptor_ready_cb);
50 // Methods called on pipeline thread ----------------------------------------
51 // AudioRenderer implementation.
52 virtual void Initialize(const scoped_refptr<DemuxerStream>& stream,
53 const AudioDecoderList& decoders,
54 const PipelineStatusCB& init_cb,
55 const StatisticsCB& statistics_cb,
56 const base::Closure& underflow_cb,
57 const TimeCB& time_cb,
58 const base::Closure& ended_cb,
59 const base::Closure& disabled_cb,
60 const PipelineStatusCB& error_cb) OVERRIDE;
61 virtual void Play(const base::Closure& callback) OVERRIDE;
62 virtual void Pause(const base::Closure& callback) OVERRIDE;
63 virtual void Flush(const base::Closure& callback) OVERRIDE;
64 virtual void Stop(const base::Closure& callback) OVERRIDE;
65 virtual void SetPlaybackRate(float rate) OVERRIDE;
66 virtual void Preroll(base::TimeDelta time,
67 const PipelineStatusCB& cb) OVERRIDE;
68 virtual void ResumeAfterUnderflow(bool buffer_more_audio) OVERRIDE;
69 virtual void SetVolume(float volume) OVERRIDE;
71 // Disables underflow support. When used, |state_| will never transition to
72 // kUnderflow resulting in Render calls that underflow returning 0 frames
73 // instead of some number of silence frames. Must be called prior to
74 // Initialize().
75 void DisableUnderflowForTesting();
77 protected:
78 virtual ~AudioRendererImpl();
80 private:
81 friend class AudioRendererImplTest;
82 FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest, EndOfStream);
83 FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest, Underflow_EndOfStream);
85 // Callback from the audio decoder delivering decoded audio samples.
86 void DecodedAudioReady(AudioDecoder::Status status,
87 const scoped_refptr<Buffer>& buffer);
89 // Handles buffers that come out of |splicer_|.
90 // Returns true if more buffers are needed.
91 bool HandleSplicerBuffer(const scoped_refptr<Buffer>& buffer);
93 // Helper functions for AudioDecoder::Status values passed to
94 // DecodedAudioReady().
95 void HandleAbortedReadOrDecodeError(bool is_decode_error);
97 // Fills the given buffer with audio data by delegating to its |algorithm_|.
98 // FillBuffer() also takes care of updating the clock. Returns the number of
99 // frames copied into |dest|, which may be less than or equal to
100 // |requested_frames|.
102 // If this method returns fewer frames than |requested_frames|, it could
103 // be a sign that the pipeline is stalled or unable to stream the data fast
104 // enough. In such scenarios, the callee should zero out unused portions
105 // of their buffer to playback silence.
107 // FillBuffer() updates the pipeline's playback timestamp. If FillBuffer() is
108 // not called at the same rate as audio samples are played, then the reported
109 // timestamp in the pipeline will be ahead of the actual audio playback. In
110 // this case |playback_delay| should be used to indicate when in the future
111 // should the filled buffer be played.
113 // Safe to call on any thread.
114 uint32 FillBuffer(uint8* dest,
115 uint32 requested_frames,
116 int audio_delay_milliseconds);
118 // Estimate earliest time when current buffer can stop playing.
119 void UpdateEarliestEndTime_Locked(int frames_filled,
120 float playback_rate,
121 base::TimeDelta playback_delay,
122 base::Time time_now);
124 // Methods called on pipeline thread ----------------------------------------
125 void DoPlay();
126 void DoPause();
128 // media::AudioRendererSink::RenderCallback implementation. Called on the
129 // AudioDevice thread.
130 virtual int Render(AudioBus* audio_bus,
131 int audio_delay_milliseconds) OVERRIDE;
132 virtual void OnRenderError() OVERRIDE;
134 // Helper method that schedules an asynchronous read from the decoder and
135 // increments |pending_reads_|.
137 // Safe to call from any thread.
138 void ScheduleRead_Locked();
140 // Returns true if the data in the buffer is all before
141 // |preroll_timestamp_|. This can only return true while
142 // in the kPrerolling state.
143 bool IsBeforePrerollTime(const scoped_refptr<Buffer>& buffer);
145 // Called when |decoder_selector_| selected the |selected_decoder|.
146 // |decrypting_demuxer_stream| was also populated if a DecryptingDemuxerStream
147 // created to help decrypt the encrypted stream.
148 // Note: |decoder_selector| is passed here to keep the AudioDecoderSelector
149 // alive until OnDecoderSelected() finishes.
150 void OnDecoderSelected(
151 scoped_ptr<AudioDecoderSelector> decoder_selector,
152 const scoped_refptr<AudioDecoder>& selected_decoder,
153 const scoped_refptr<DecryptingDemuxerStream>& decrypting_demuxer_stream);
155 void ResetDecoder(const base::Closure& callback);
157 scoped_ptr<AudioSplicer> splicer_;
159 // The sink (destination) for rendered audio. |sink_| must only be accessed
160 // on the pipeline thread (verify with |pipeline_thread_checker_|). |sink_|
161 // must never be called under |lock_| or the 3-way thread bridge between the
162 // audio, pipeline, and decoder threads may deadlock.
163 scoped_refptr<media::AudioRendererSink> sink_;
165 SetDecryptorReadyCB set_decryptor_ready_cb_;
167 // These two will be set by AudioDecoderSelector::SelectAudioDecoder().
168 scoped_refptr<AudioDecoder> decoder_;
169 scoped_refptr<DecryptingDemuxerStream> decrypting_demuxer_stream_;
171 // Ensures certain methods are always called on the pipeline thread.
172 base::ThreadChecker pipeline_thread_checker_;
174 // AudioParameters constructed during Initialize() based on |decoder_|.
175 AudioParameters audio_parameters_;
177 // Callbacks provided during Initialize().
178 PipelineStatusCB init_cb_;
179 StatisticsCB statistics_cb_;
180 base::Closure underflow_cb_;
181 TimeCB time_cb_;
182 base::Closure ended_cb_;
183 base::Closure disabled_cb_;
184 PipelineStatusCB error_cb_;
186 // Callback provided to Pause().
187 base::Closure pause_cb_;
189 // Callback provided to Preroll().
190 PipelineStatusCB preroll_cb_;
192 // After Initialize() has completed, all variables below must be accessed
193 // under |lock_|. ------------------------------------------------------------
194 base::Lock lock_;
196 // Algorithm for scaling audio.
197 scoped_ptr<AudioRendererAlgorithm> algorithm_;
199 // Simple state tracking variable.
200 enum State {
201 kUninitialized,
202 kPaused,
203 kPrerolling,
204 kPlaying,
205 kStopped,
206 kUnderflow,
207 kRebuffering,
209 State state_;
211 // Keep track of our outstanding read to |decoder_|.
212 bool pending_read_;
214 // Keeps track of whether we received and rendered the end of stream buffer.
215 bool received_end_of_stream_;
216 bool rendered_end_of_stream_;
218 // The timestamp of the last frame (i.e. furthest in the future) buffered as
219 // well as the current time that takes current playback delay into account.
220 base::TimeDelta audio_time_buffered_;
221 base::TimeDelta current_time_;
223 base::TimeDelta preroll_timestamp_;
225 // We're supposed to know amount of audio data OS or hardware buffered, but
226 // that is not always so -- on my Linux box
227 // AudioBuffersState::hardware_delay_bytes never reaches 0.
229 // As a result we cannot use it to find when stream ends. If we just ignore
230 // buffered data we will notify host that stream ended before it is actually
231 // did so, I've seen it done ~140ms too early when playing ~150ms file.
233 // Instead of trying to invent OS-specific solution for each and every OS we
234 // are supporting, use simple workaround: every time we fill the buffer we
235 // remember when it should stop playing, and do not assume that buffer is
236 // empty till that time. Workaround is not bulletproof, as we don't exactly
237 // know when that particular data would start playing, but it is much better
238 // than nothing.
239 base::Time earliest_end_time_;
241 bool underflow_disabled_;
243 // True if the renderer receives a buffer with kAborted status during preroll,
244 // false otherwise. This flag is cleared on the next Preroll() call.
245 bool preroll_aborted_;
247 // End variables which must be accessed under |lock_|. ----------------------
249 // Variables used only on the audio thread. ---------------------------------
250 int actual_frames_per_buffer_;
251 scoped_array<uint8> audio_buffer_;
253 DISALLOW_COPY_AND_ASSIGN(AudioRendererImpl);
256 } // namespace media
258 #endif // MEDIA_FILTERS_AUDIO_RENDERER_IMPL_H_