Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(243)

Side by Side Diff: media/filters/audio_renderer_impl.h

Issue 284763002: Update AudioRenderer API to fire changes in BufferingState. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/base/pipeline_unittest.cc ('k') | media/filters/audio_renderer_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Audio rendering unit utilizing an AudioRendererSink to output data. 5 // Audio rendering unit utilizing an AudioRendererSink to output data.
6 // 6 //
7 // This class lives inside three threads during it's lifetime, namely: 7 // This class lives inside three threads during it's lifetime, namely:
8 // 1. Render thread 8 // 1. Render thread
9 // Where the object is created. 9 // Where the object is created.
10 // 2. Media thread (provided via constructor) 10 // 2. Media thread (provided via constructor)
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 AudioRendererSink* sink, 61 AudioRendererSink* sink,
62 ScopedVector<AudioDecoder> decoders, 62 ScopedVector<AudioDecoder> decoders,
63 const SetDecryptorReadyCB& set_decryptor_ready_cb, 63 const SetDecryptorReadyCB& set_decryptor_ready_cb,
64 AudioHardwareConfig* hardware_params); 64 AudioHardwareConfig* hardware_params);
65 virtual ~AudioRendererImpl(); 65 virtual ~AudioRendererImpl();
66 66
67 // AudioRenderer implementation. 67 // AudioRenderer implementation.
68 virtual void Initialize(DemuxerStream* stream, 68 virtual void Initialize(DemuxerStream* stream,
69 const PipelineStatusCB& init_cb, 69 const PipelineStatusCB& init_cb,
70 const StatisticsCB& statistics_cb, 70 const StatisticsCB& statistics_cb,
71 const base::Closure& underflow_cb,
72 const TimeCB& time_cb, 71 const TimeCB& time_cb,
72 const BufferingStateCB& buffering_state_cb,
73 const base::Closure& ended_cb, 73 const base::Closure& ended_cb,
74 const PipelineStatusCB& error_cb) OVERRIDE; 74 const PipelineStatusCB& error_cb) OVERRIDE;
75 virtual void StartRendering() OVERRIDE; 75 virtual void StartRendering() OVERRIDE;
76 virtual void StopRendering() OVERRIDE; 76 virtual void StopRendering() OVERRIDE;
77 virtual void Flush(const base::Closure& callback) OVERRIDE; 77 virtual void Flush(const base::Closure& callback) OVERRIDE;
78 virtual void Stop(const base::Closure& callback) OVERRIDE; 78 virtual void Stop(const base::Closure& callback) OVERRIDE;
79 virtual void SetPlaybackRate(float rate) OVERRIDE; 79 virtual void SetPlaybackRate(float rate) OVERRIDE;
80 virtual void Preroll(base::TimeDelta time, 80 virtual void StartPlayingFrom(base::TimeDelta timestamp) OVERRIDE;
81 const PipelineStatusCB& cb) OVERRIDE;
82 virtual void ResumeAfterUnderflow() OVERRIDE;
83 virtual void SetVolume(float volume) OVERRIDE; 81 virtual void SetVolume(float volume) OVERRIDE;
84 82
85 // Allows injection of a custom time callback for non-realtime testing. 83 // Allows injection of a custom time callback for non-realtime testing.
86 typedef base::Callback<base::TimeTicks()> NowCB; 84 typedef base::Callback<base::TimeTicks()> NowCB;
87 void set_now_cb_for_testing(const NowCB& now_cb) { 85 void set_now_cb_for_testing(const NowCB& now_cb) {
88 now_cb_ = now_cb; 86 now_cb_ = now_cb;
89 } 87 }
90 88
91 private: 89 private:
92 friend class AudioRendererImplTest; 90 friend class AudioRendererImplTest;
93 91
94 // Important detail: being in kPlaying doesn't imply that audio is being 92 // Important detail: being in kPlaying doesn't imply that audio is being
95 // rendered. Rather, it means that the renderer is ready to go. The actual 93 // rendered. Rather, it means that the renderer is ready to go. The actual
96 // rendering of audio is controlled via Start/StopRendering(). 94 // rendering of audio is controlled via Start/StopRendering().
97 // 95 //
98 // kUninitialized 96 // kUninitialized
99 // | Initialize() 97 // | Initialize()
100 // | 98 // |
101 // V 99 // V
102 // kInitializing 100 // kInitializing
103 // | Decoders initialized 101 // | Decoders initialized
104 // | 102 // |
105 // V Decoders reset 103 // V Decoders reset
106 // kFlushed <------------------ kFlushing 104 // kFlushed <------------------ kFlushing
107 // | Preroll() ^ 105 // | StartPlayingFrom() ^
108 // | | 106 // | |
109 // V | Flush() 107 // | | Flush()
110 // kPrerolling ----------------> kPlaying ---------. 108 // `---------> kPlaying --------'
111 // Enough data buffered ^ | Not enough data
112 // | | buffered
113 // Enough data buffered | V
114 // kRebuffering <--- kUnderflow
115 // ResumeAfterUnderflow()
116 enum State { 109 enum State {
117 kUninitialized, 110 kUninitialized,
118 kInitializing, 111 kInitializing,
119 kFlushing, 112 kFlushing,
120 kFlushed, 113 kFlushed,
121 kPrerolling,
122 kPlaying, 114 kPlaying,
123 kStopped, 115 kStopped,
124 kUnderflow,
125 kRebuffering,
126 }; 116 };
127 117
128 // Callback from the audio decoder delivering decoded audio samples. 118 // Callback from the audio decoder delivering decoded audio samples.
129 void DecodedAudioReady(AudioBufferStream::Status status, 119 void DecodedAudioReady(AudioBufferStream::Status status,
130 const scoped_refptr<AudioBuffer>& buffer); 120 const scoped_refptr<AudioBuffer>& buffer);
131 121
132 // Handles buffers that come out of |splicer_|. 122 // Handles buffers that come out of |splicer_|.
133 // Returns true if more buffers are needed. 123 // Returns true if more buffers are needed.
134 bool HandleSplicerBuffer(const scoped_refptr<AudioBuffer>& buffer); 124 bool HandleSplicerBuffer_Locked(const scoped_refptr<AudioBuffer>& buffer);
135 125
136 // Helper functions for AudioDecoder::Status values passed to 126 // Helper functions for AudioDecoder::Status values passed to
137 // DecodedAudioReady(). 127 // DecodedAudioReady().
138 void HandleAbortedReadOrDecodeError(bool is_decode_error); 128 void HandleAbortedReadOrDecodeError(bool is_decode_error);
139 129
140 // Estimate earliest time when current buffer can stop playing. 130 // Estimate earliest time when current buffer can stop playing.
141 void UpdateEarliestEndTime_Locked(int frames_filled, 131 void UpdateEarliestEndTime_Locked(int frames_filled,
142 const base::TimeDelta& playback_delay, 132 const base::TimeDelta& playback_delay,
143 const base::TimeTicks& time_now); 133 const base::TimeTicks& time_now);
144 134
(...skipping 25 matching lines...) Expand all
170 160
171 // Helper methods that schedule an asynchronous read from the decoder as long 161 // Helper methods that schedule an asynchronous read from the decoder as long
172 // as there isn't a pending read. 162 // as there isn't a pending read.
173 // 163 //
174 // Must be called on |task_runner_|. 164 // Must be called on |task_runner_|.
175 void AttemptRead(); 165 void AttemptRead();
176 void AttemptRead_Locked(); 166 void AttemptRead_Locked();
177 bool CanRead_Locked(); 167 bool CanRead_Locked();
178 void ChangeState_Locked(State new_state); 168 void ChangeState_Locked(State new_state);
179 169
180 // Returns true if the data in the buffer is all before 170 // Returns true if the data in the buffer is all before |start_timestamp_|.
181 // |preroll_timestamp_|. This can only return true while 171 // This can only return true while in the kPlaying state.
182 // in the kPrerolling state. 172 bool IsBeforeStartTime(const scoped_refptr<AudioBuffer>& buffer);
183 bool IsBeforePrerollTime(const scoped_refptr<AudioBuffer>& buffer);
184 173
185 // Called upon AudioBufferStream initialization, or failure thereof (indicated 174 // Called upon AudioBufferStream initialization, or failure thereof (indicated
186 // by the value of |success|). 175 // by the value of |success|).
187 void OnAudioBufferStreamInitialized(bool succes); 176 void OnAudioBufferStreamInitialized(bool succes);
188 177
189 // Used to initiate the flush operation once all pending reads have 178 // Used to initiate the flush operation once all pending reads have
190 // completed. 179 // completed.
191 void DoFlush_Locked(); 180 void DoFlush_Locked();
192 181
193 // Calls |decoder_|.Reset() and arranges for ResetDecoderDone() to get 182 // Calls |decoder_|.Reset() and arranges for ResetDecoderDone() to get
194 // called when the reset completes. 183 // called when the reset completes.
195 void ResetDecoder(); 184 void ResetDecoder();
196 185
197 // Called when the |decoder_|.Reset() has completed. 186 // Called when the |decoder_|.Reset() has completed.
198 void ResetDecoderDone(); 187 void ResetDecoderDone();
199 188
200 // Called by the AudioBufferStream when a splice buffer is demuxed. 189 // Called by the AudioBufferStream when a splice buffer is demuxed.
201 void OnNewSpliceBuffer(base::TimeDelta); 190 void OnNewSpliceBuffer(base::TimeDelta);
202 191
203 // Called by the AudioBufferStream when a config change occurs. 192 // Called by the AudioBufferStream when a config change occurs.
204 void OnConfigChange(); 193 void OnConfigChange();
205 194
195 // Updates |buffering_state_| and fires |buffering_state_cb_|.
196 void SetBufferingState_Locked(BufferingState buffering_state);
197
206 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 198 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
207 199
208 scoped_ptr<AudioSplicer> splicer_; 200 scoped_ptr<AudioSplicer> splicer_;
209 scoped_ptr<AudioBufferConverter> buffer_converter_; 201 scoped_ptr<AudioBufferConverter> buffer_converter_;
210 202
211 // Whether or not we expect to handle config changes. 203 // Whether or not we expect to handle config changes.
212 bool expecting_config_changes_; 204 bool expecting_config_changes_;
213 205
214 // The sink (destination) for rendered audio. |sink_| must only be accessed 206 // The sink (destination) for rendered audio. |sink_| must only be accessed
215 // on |task_runner_|. |sink_| must never be called under |lock_| or else we 207 // on |task_runner_|. |sink_| must never be called under |lock_| or else we
216 // may deadlock between |task_runner_| and the audio callback thread. 208 // may deadlock between |task_runner_| and the audio callback thread.
217 scoped_refptr<media::AudioRendererSink> sink_; 209 scoped_refptr<media::AudioRendererSink> sink_;
218 210
219 AudioBufferStream audio_buffer_stream_; 211 AudioBufferStream audio_buffer_stream_;
220 212
221 // Interface to the hardware audio params. 213 // Interface to the hardware audio params.
222 const AudioHardwareConfig* const hardware_config_; 214 const AudioHardwareConfig* const hardware_config_;
223 215
224 // Cached copy of hardware params from |hardware_config_|. 216 // Cached copy of hardware params from |hardware_config_|.
225 AudioParameters audio_parameters_; 217 AudioParameters audio_parameters_;
226 218
227 // Callbacks provided during Initialize(). 219 // Callbacks provided during Initialize().
228 PipelineStatusCB init_cb_; 220 PipelineStatusCB init_cb_;
229 base::Closure underflow_cb_;
230 TimeCB time_cb_; 221 TimeCB time_cb_;
222 BufferingStateCB buffering_state_cb_;
231 base::Closure ended_cb_; 223 base::Closure ended_cb_;
232 PipelineStatusCB error_cb_; 224 PipelineStatusCB error_cb_;
233 225
234 // Callback provided to Flush(). 226 // Callback provided to Flush().
235 base::Closure flush_cb_; 227 base::Closure flush_cb_;
236 228
237 // Callback provided to Preroll().
238 PipelineStatusCB preroll_cb_;
239
240 // Typically calls base::TimeTicks::Now() but can be overridden by a test. 229 // Typically calls base::TimeTicks::Now() but can be overridden by a test.
241 NowCB now_cb_; 230 NowCB now_cb_;
242 231
243 // After Initialize() has completed, all variables below must be accessed 232 // After Initialize() has completed, all variables below must be accessed
244 // under |lock_|. ------------------------------------------------------------ 233 // under |lock_|. ------------------------------------------------------------
245 base::Lock lock_; 234 base::Lock lock_;
246 235
247 // Algorithm for scaling audio. 236 // Algorithm for scaling audio.
248 scoped_ptr<AudioRendererAlgorithm> algorithm_; 237 scoped_ptr<AudioRendererAlgorithm> algorithm_;
249 238
250 // Simple state tracking variable. 239 // Simple state tracking variable.
251 State state_; 240 State state_;
252 241
242 BufferingState buffering_state_;
243
253 // Keep track of whether or not the sink is playing and whether we should be 244 // Keep track of whether or not the sink is playing and whether we should be
254 // rendering. 245 // rendering.
255 bool rendering_; 246 bool rendering_;
256 bool sink_playing_; 247 bool sink_playing_;
257 248
258 // Keep track of our outstanding read to |decoder_|. 249 // Keep track of our outstanding read to |decoder_|.
259 bool pending_read_; 250 bool pending_read_;
260 251
261 // Keeps track of whether we received and rendered the end of stream buffer. 252 // Keeps track of whether we received and rendered the end of stream buffer.
262 bool received_end_of_stream_; 253 bool received_end_of_stream_;
263 bool rendered_end_of_stream_; 254 bool rendered_end_of_stream_;
264 255
265 scoped_ptr<AudioClock> audio_clock_; 256 scoped_ptr<AudioClock> audio_clock_;
266 257
267 base::TimeDelta preroll_timestamp_; 258 base::TimeDelta start_timestamp_;
268 259
269 // We're supposed to know amount of audio data OS or hardware buffered, but 260 // We're supposed to know amount of audio data OS or hardware buffered, but
270 // that is not always so -- on my Linux box 261 // that is not always so -- on my Linux box
271 // AudioBuffersState::hardware_delay_bytes never reaches 0. 262 // AudioBuffersState::hardware_delay_bytes never reaches 0.
272 // 263 //
273 // As a result we cannot use it to find when stream ends. If we just ignore 264 // As a result we cannot use it to find when stream ends. If we just ignore
274 // buffered data we will notify host that stream ended before it is actually 265 // buffered data we will notify host that stream ended before it is actually
275 // did so, I've seen it done ~140ms too early when playing ~150ms file. 266 // did so, I've seen it done ~140ms too early when playing ~150ms file.
276 // 267 //
277 // Instead of trying to invent OS-specific solution for each and every OS we 268 // Instead of trying to invent OS-specific solution for each and every OS we
278 // are supporting, use simple workaround: every time we fill the buffer we 269 // are supporting, use simple workaround: every time we fill the buffer we
279 // remember when it should stop playing, and do not assume that buffer is 270 // remember when it should stop playing, and do not assume that buffer is
280 // empty till that time. Workaround is not bulletproof, as we don't exactly 271 // empty till that time. Workaround is not bulletproof, as we don't exactly
281 // know when that particular data would start playing, but it is much better 272 // know when that particular data would start playing, but it is much better
282 // than nothing. 273 // than nothing.
283 base::TimeTicks earliest_end_time_; 274 base::TimeTicks earliest_end_time_;
284 size_t total_frames_filled_; 275 size_t total_frames_filled_;
285 276
286 // True if the renderer receives a buffer with kAborted status during preroll,
287 // false otherwise. This flag is cleared on the next Preroll() call.
288 bool preroll_aborted_;
289
290 // End variables which must be accessed under |lock_|. ---------------------- 277 // End variables which must be accessed under |lock_|. ----------------------
291 278
292 // NOTE: Weak pointers must be invalidated before all other member variables. 279 // NOTE: Weak pointers must be invalidated before all other member variables.
293 base::WeakPtrFactory<AudioRendererImpl> weak_factory_; 280 base::WeakPtrFactory<AudioRendererImpl> weak_factory_;
294 281
295 DISALLOW_COPY_AND_ASSIGN(AudioRendererImpl); 282 DISALLOW_COPY_AND_ASSIGN(AudioRendererImpl);
296 }; 283 };
297 284
298 } // namespace media 285 } // namespace media
299 286
300 #endif // MEDIA_FILTERS_AUDIO_RENDERER_IMPL_H_ 287 #endif // MEDIA_FILTERS_AUDIO_RENDERER_IMPL_H_
OLDNEW
« no previous file with comments | « media/base/pipeline_unittest.cc ('k') | media/filters/audio_renderer_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698