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

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
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(const scoped_refptr<AudioBuffer>& buffer);
135 125
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
(...skipping 25 matching lines...) Expand all
219 AudioBufferStream audio_buffer_stream_; 208 AudioBufferStream audio_buffer_stream_;
220 209
221 // Interface to the hardware audio params. 210 // Interface to the hardware audio params.
222 const AudioHardwareConfig* const hardware_config_; 211 const AudioHardwareConfig* const hardware_config_;
223 212
224 // Cached copy of hardware params from |hardware_config_|. 213 // Cached copy of hardware params from |hardware_config_|.
225 AudioParameters audio_parameters_; 214 AudioParameters audio_parameters_;
226 215
227 // Callbacks provided during Initialize(). 216 // Callbacks provided during Initialize().
228 PipelineStatusCB init_cb_; 217 PipelineStatusCB init_cb_;
229 base::Closure underflow_cb_;
230 TimeCB time_cb_; 218 TimeCB time_cb_;
219 BufferingStateCB buffering_state_cb_;
231 base::Closure ended_cb_; 220 base::Closure ended_cb_;
232 PipelineStatusCB error_cb_; 221 PipelineStatusCB error_cb_;
233 222
223 BufferingState buffering_state_;
224
acolwell GONE FROM CHROMIUM 2014/05/16 17:25:08 This should go somewhere below the lock_ decl sinc
scherkus (not reviewing) 2014/05/22 17:49:12 Done.
234 // Callback provided to Flush(). 225 // Callback provided to Flush().
235 base::Closure flush_cb_; 226 base::Closure flush_cb_;
236 227
237 // Callback provided to Preroll().
238 PipelineStatusCB preroll_cb_;
239
240 // 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.
241 NowCB now_cb_; 229 NowCB now_cb_;
242 230
243 // After Initialize() has completed, all variables below must be accessed 231 // After Initialize() has completed, all variables below must be accessed
244 // under |lock_|. ------------------------------------------------------------ 232 // under |lock_|. ------------------------------------------------------------
245 base::Lock lock_; 233 base::Lock lock_;
246 234
247 // Algorithm for scaling audio. 235 // Algorithm for scaling audio.
248 scoped_ptr<AudioRendererAlgorithm> algorithm_; 236 scoped_ptr<AudioRendererAlgorithm> algorithm_;
249 237
250 // Simple state tracking variable. 238 // Simple state tracking variable.
251 State state_; 239 State state_;
252 240
253 // 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
254 // rendering. 242 // rendering.
255 bool rendering_; 243 bool rendering_;
256 bool sink_playing_; 244 bool sink_playing_;
257 245
258 // Keep track of our outstanding read to |decoder_|. 246 // Keep track of our outstanding read to |decoder_|.
259 bool pending_read_; 247 bool pending_read_;
260 248
261 // 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.
262 bool received_end_of_stream_; 250 bool received_end_of_stream_;
263 bool rendered_end_of_stream_; 251 bool rendered_end_of_stream_;
264 252
265 scoped_ptr<AudioClock> audio_clock_; 253 scoped_ptr<AudioClock> audio_clock_;
266 254
267 base::TimeDelta preroll_timestamp_; 255 base::TimeDelta start_timestamp_;
268 256
269 // 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
270 // that is not always so -- on my Linux box 258 // that is not always so -- on my Linux box
271 // AudioBuffersState::hardware_delay_bytes never reaches 0. 259 // AudioBuffersState::hardware_delay_bytes never reaches 0.
272 // 260 //
273 // 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
274 // 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
275 // 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.
276 // 264 //
277 // 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
278 // 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
279 // 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
280 // 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
281 // 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
282 // than nothing. 270 // than nothing.
283 base::TimeTicks earliest_end_time_; 271 base::TimeTicks earliest_end_time_;
284 size_t total_frames_filled_; 272 size_t total_frames_filled_;
285 273
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_|. ---------------------- 274 // End variables which must be accessed under |lock_|. ----------------------
291 275
292 // NOTE: Weak pointers must be invalidated before all other member variables. 276 // NOTE: Weak pointers must be invalidated before all other member variables.
293 base::WeakPtrFactory<AudioRendererImpl> weak_factory_; 277 base::WeakPtrFactory<AudioRendererImpl> weak_factory_;
294 278
295 DISALLOW_COPY_AND_ASSIGN(AudioRendererImpl); 279 DISALLOW_COPY_AND_ASSIGN(AudioRendererImpl);
296 }; 280 };
297 281
298 } // namespace media 282 } // namespace media
299 283
300 #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