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

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: 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
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 // Disables underflow support. When used, |state_| will never transition to
86 // kUnderflow resulting in Render calls that underflow returning 0 frames
87 // instead of some number of silence frames. Must be called prior to
88 // Initialize().
89 void DisableUnderflowForTesting();
90
91 // Allows injection of a custom time callback for non-realtime testing. 83 // Allows injection of a custom time callback for non-realtime testing.
92 typedef base::Callback<base::TimeTicks()> NowCB; 84 typedef base::Callback<base::TimeTicks()> NowCB;
93 void set_now_cb_for_testing(const NowCB& now_cb) { 85 void set_now_cb_for_testing(const NowCB& now_cb) {
94 now_cb_ = now_cb; 86 now_cb_ = now_cb;
95 } 87 }
96 88
97 private: 89 private:
98 friend class AudioRendererImplTest; 90 friend class AudioRendererImplTest;
99 91
100 // 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
101 // 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
102 // rendering of audio is controlled via Start/StopRendering(). 94 // rendering of audio is controlled via Start/StopRendering().
103 // 95 //
104 // kUninitialized 96 // kUninitialized
105 // | Initialize() 97 // | Initialize()
106 // | 98 // |
107 // V 99 // V
108 // kInitializing 100 // kInitializing
109 // | Decoders initialized 101 // | Decoders initialized
110 // | 102 // |
111 // V Decoders reset 103 // V Decoders reset
112 // kFlushed <------------------ kFlushing 104 // kFlushed <------------------ kFlushing
113 // | Preroll() ^ 105 // | StartPlayingFrom() ^
114 // | | 106 // | |
115 // V | Flush() 107 // | | Flush()
116 // kPrerolling ----------------> kPlaying ---------. 108 // `---------> kPlaying --------'
acolwell GONE FROM CHROMIUM 2014/05/13 20:44:27 \o/ so much nicer
117 // Enough data buffered ^ | Not enough data
118 // | | buffered
119 // Enough data buffered | V
120 // kRebuffering <--- kUnderflow
121 // ResumeAfterUnderflow()
122 enum State { 109 enum State {
123 kUninitialized, 110 kUninitialized,
124 kInitializing, 111 kInitializing,
125 kFlushing, 112 kFlushing,
126 kFlushed, 113 kFlushed,
127 kPrerolling,
128 kPlaying, 114 kPlaying,
129 kStopped, 115 kStopped,
130 kUnderflow,
131 kRebuffering,
132 }; 116 };
133 117
134 // Callback from the audio decoder delivering decoded audio samples. 118 // Callback from the audio decoder delivering decoded audio samples.
135 void DecodedAudioReady(AudioBufferStream::Status status, 119 void DecodedAudioReady(AudioBufferStream::Status status,
136 const scoped_refptr<AudioBuffer>& buffer); 120 const scoped_refptr<AudioBuffer>& buffer);
137 121
138 // Handles buffers that come out of |splicer_|. 122 // Handles buffers that come out of |splicer_|.
139 // Returns true if more buffers are needed. 123 // Returns true if more buffers are needed.
140 bool HandleSplicerBuffer(const scoped_refptr<AudioBuffer>& buffer); 124 bool HandleSplicerBuffer(const scoped_refptr<AudioBuffer>& buffer);
141 125
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 160
177 // 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
178 // as there isn't a pending read. 162 // as there isn't a pending read.
179 // 163 //
180 // Must be called on |task_runner_|. 164 // Must be called on |task_runner_|.
181 void AttemptRead(); 165 void AttemptRead();
182 void AttemptRead_Locked(); 166 void AttemptRead_Locked();
183 bool CanRead_Locked(); 167 bool CanRead_Locked();
184 void ChangeState_Locked(State new_state); 168 void ChangeState_Locked(State new_state);
185 169
186 // 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_|.
187 // |preroll_timestamp_|. This can only return true while 171 // This can only return true while in the kPlaying state.
188 // in the kPrerolling state. 172 bool IsBeforeStartTime(const scoped_refptr<AudioBuffer>& buffer);
189 bool IsBeforePrerollTime(const scoped_refptr<AudioBuffer>& buffer);
190 173
191 // Called upon AudioBufferStream initialization, or failure thereof (indicated 174 // Called upon AudioBufferStream initialization, or failure thereof (indicated
192 // by the value of |success|). 175 // by the value of |success|).
193 void OnAudioBufferStreamInitialized(bool succes); 176 void OnAudioBufferStreamInitialized(bool succes);
194 177
195 // Used to initiate the flush operation once all pending reads have 178 // Used to initiate the flush operation once all pending reads have
196 // completed. 179 // completed.
197 void DoFlush_Locked(); 180 void DoFlush_Locked();
198 181
199 // Calls |decoder_|.Reset() and arranges for ResetDecoderDone() to get 182 // Calls |decoder_|.Reset() and arranges for ResetDecoderDone() to get
(...skipping 25 matching lines...) Expand all
225 AudioBufferStream audio_buffer_stream_; 208 AudioBufferStream audio_buffer_stream_;
226 209
227 // Interface to the hardware audio params. 210 // Interface to the hardware audio params.
228 const AudioHardwareConfig* const hardware_config_; 211 const AudioHardwareConfig* const hardware_config_;
229 212
230 // Cached copy of hardware params from |hardware_config_|. 213 // Cached copy of hardware params from |hardware_config_|.
231 AudioParameters audio_parameters_; 214 AudioParameters audio_parameters_;
232 215
233 // Callbacks provided during Initialize(). 216 // Callbacks provided during Initialize().
234 PipelineStatusCB init_cb_; 217 PipelineStatusCB init_cb_;
235 base::Closure underflow_cb_;
236 TimeCB time_cb_; 218 TimeCB time_cb_;
219 BufferingStateCB buffering_state_cb_;
237 base::Closure ended_cb_; 220 base::Closure ended_cb_;
238 PipelineStatusCB error_cb_; 221 PipelineStatusCB error_cb_;
239 222
223 BufferingState buffering_state_;
224
240 // Callback provided to Flush(). 225 // Callback provided to Flush().
241 base::Closure flush_cb_; 226 base::Closure flush_cb_;
242 227
243 // Callback provided to Preroll().
244 PipelineStatusCB preroll_cb_;
245
246 // Typically calls base::TimeTicks::Now() but can be overridden by a test. 228 // Typically calls base::TimeTicks::Now() but can be overridden by a test.
247 NowCB now_cb_; 229 NowCB now_cb_;
248 230
249 // After Initialize() has completed, all variables below must be accessed 231 // After Initialize() has completed, all variables below must be accessed
250 // under |lock_|. ------------------------------------------------------------ 232 // under |lock_|. ------------------------------------------------------------
251 base::Lock lock_; 233 base::Lock lock_;
252 234
253 // Algorithm for scaling audio. 235 // Algorithm for scaling audio.
254 scoped_ptr<AudioRendererAlgorithm> algorithm_; 236 scoped_ptr<AudioRendererAlgorithm> algorithm_;
255 237
256 // Simple state tracking variable. 238 // Simple state tracking variable.
257 State state_; 239 State state_;
258 240
259 // Keep track of whether or not the sink is playing and whether we should be 241 // Keep track of whether or not the sink is playing and whether we should be
260 // rendering. 242 // rendering.
261 bool rendering_; 243 bool rendering_;
262 bool sink_playing_; 244 bool sink_playing_;
263 245
264 // Keep track of our outstanding read to |decoder_|. 246 // Keep track of our outstanding read to |decoder_|.
265 bool pending_read_; 247 bool pending_read_;
266 248
267 // Keeps track of whether we received and rendered the end of stream buffer. 249 // Keeps track of whether we received and rendered the end of stream buffer.
268 bool received_end_of_stream_; 250 bool received_end_of_stream_;
269 bool rendered_end_of_stream_; 251 bool rendered_end_of_stream_;
270 252
271 scoped_ptr<AudioClock> audio_clock_; 253 scoped_ptr<AudioClock> audio_clock_;
272 254
273 base::TimeDelta preroll_timestamp_; 255 base::TimeDelta start_timestamp_;
274 256
275 // We're supposed to know amount of audio data OS or hardware buffered, but 257 // We're supposed to know amount of audio data OS or hardware buffered, but
276 // that is not always so -- on my Linux box 258 // that is not always so -- on my Linux box
277 // AudioBuffersState::hardware_delay_bytes never reaches 0. 259 // AudioBuffersState::hardware_delay_bytes never reaches 0.
278 // 260 //
279 // As a result we cannot use it to find when stream ends. If we just ignore 261 // As a result we cannot use it to find when stream ends. If we just ignore
280 // buffered data we will notify host that stream ended before it is actually 262 // buffered data we will notify host that stream ended before it is actually
281 // did so, I've seen it done ~140ms too early when playing ~150ms file. 263 // did so, I've seen it done ~140ms too early when playing ~150ms file.
282 // 264 //
283 // Instead of trying to invent OS-specific solution for each and every OS we 265 // Instead of trying to invent OS-specific solution for each and every OS we
284 // are supporting, use simple workaround: every time we fill the buffer we 266 // are supporting, use simple workaround: every time we fill the buffer we
285 // remember when it should stop playing, and do not assume that buffer is 267 // remember when it should stop playing, and do not assume that buffer is
286 // empty till that time. Workaround is not bulletproof, as we don't exactly 268 // empty till that time. Workaround is not bulletproof, as we don't exactly
287 // know when that particular data would start playing, but it is much better 269 // know when that particular data would start playing, but it is much better
288 // than nothing. 270 // than nothing.
289 base::TimeTicks earliest_end_time_; 271 base::TimeTicks earliest_end_time_;
290 size_t total_frames_filled_; 272 size_t total_frames_filled_;
291 273
292 bool underflow_disabled_;
293
294 // True if the renderer receives a buffer with kAborted status during preroll,
295 // false otherwise. This flag is cleared on the next Preroll() call.
296 bool preroll_aborted_;
297
298 // End variables which must be accessed under |lock_|. ---------------------- 274 // End variables which must be accessed under |lock_|. ----------------------
299 275
300 // NOTE: Weak pointers must be invalidated before all other member variables. 276 // NOTE: Weak pointers must be invalidated before all other member variables.
301 base::WeakPtrFactory<AudioRendererImpl> weak_factory_; 277 base::WeakPtrFactory<AudioRendererImpl> weak_factory_;
302 278
303 DISALLOW_COPY_AND_ASSIGN(AudioRendererImpl); 279 DISALLOW_COPY_AND_ASSIGN(AudioRendererImpl);
304 }; 280 };
305 281
306 } // namespace media 282 } // namespace media
307 283
308 #endif // MEDIA_FILTERS_AUDIO_RENDERER_IMPL_H_ 284 #endif // MEDIA_FILTERS_AUDIO_RENDERER_IMPL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698