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

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

Issue 141243003: Add AudioBufferStream. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@decoderstream_rebased
Patch Set: fix a couple comments Created 6 years, 9 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
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 #include "media/filters/audio_renderer_impl.h" 5 #include "media/filters/audio_renderer_impl.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 10
(...skipping 26 matching lines...) Expand all
37 } // namespace 37 } // namespace
38 38
39 AudioRendererImpl::AudioRendererImpl( 39 AudioRendererImpl::AudioRendererImpl(
40 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 40 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
41 media::AudioRendererSink* sink, 41 media::AudioRendererSink* sink,
42 ScopedVector<AudioDecoder> decoders, 42 ScopedVector<AudioDecoder> decoders,
43 const SetDecryptorReadyCB& set_decryptor_ready_cb) 43 const SetDecryptorReadyCB& set_decryptor_ready_cb)
44 : task_runner_(task_runner), 44 : task_runner_(task_runner),
45 weak_factory_(this), 45 weak_factory_(this),
46 sink_(sink), 46 sink_(sink),
47 decoder_selector_(new AudioDecoderSelector( 47 audio_buffer_stream_(task_runner,
48 task_runner, decoders.Pass(), set_decryptor_ready_cb)), 48 decoders.Pass(),
49 set_decryptor_ready_cb),
49 now_cb_(base::Bind(&base::TimeTicks::Now)), 50 now_cb_(base::Bind(&base::TimeTicks::Now)),
50 state_(kUninitialized), 51 state_(kUninitialized),
51 sink_playing_(false), 52 sink_playing_(false),
52 pending_read_(false), 53 pending_read_(false),
53 received_end_of_stream_(false), 54 received_end_of_stream_(false),
54 rendered_end_of_stream_(false), 55 rendered_end_of_stream_(false),
55 audio_time_buffered_(kNoTimestamp()), 56 audio_time_buffered_(kNoTimestamp()),
56 current_time_(kNoTimestamp()), 57 current_time_(kNoTimestamp()),
57 underflow_disabled_(false), 58 underflow_disabled_(false),
58 preroll_aborted_(false) { 59 preroll_aborted_(false) {}
59 }
60 60
61 AudioRendererImpl::~AudioRendererImpl() { 61 AudioRendererImpl::~AudioRendererImpl() {
62 // Stop() should have been called and |algorithm_| should have been destroyed. 62 // Stop() should have been called and |algorithm_| should have been destroyed.
63 DCHECK(state_ == kUninitialized || state_ == kStopped); 63 DCHECK(state_ == kUninitialized || state_ == kStopped);
64 DCHECK(!algorithm_.get()); 64 DCHECK(!algorithm_.get());
65 } 65 }
66 66
67 void AudioRendererImpl::Play(const base::Closure& callback) { 67 void AudioRendererImpl::Play(const base::Closure& callback) {
68 DCHECK(task_runner_->BelongsToCurrentThread()); 68 DCHECK(task_runner_->BelongsToCurrentThread());
69 69
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 DoFlush_Locked(); 138 DoFlush_Locked();
139 } 139 }
140 140
141 void AudioRendererImpl::DoFlush_Locked() { 141 void AudioRendererImpl::DoFlush_Locked() {
142 DCHECK(task_runner_->BelongsToCurrentThread()); 142 DCHECK(task_runner_->BelongsToCurrentThread());
143 lock_.AssertAcquired(); 143 lock_.AssertAcquired();
144 144
145 DCHECK(!pending_read_); 145 DCHECK(!pending_read_);
146 DCHECK_EQ(state_, kPaused); 146 DCHECK_EQ(state_, kPaused);
147 147
148 if (decrypting_demuxer_stream_) { 148 audio_buffer_stream_.Reset(
149 decrypting_demuxer_stream_->Reset( 149 base::Bind(&AudioRendererImpl::ResetDecoderDone, weak_this_));
150 base::Bind(&AudioRendererImpl::ResetDecoder, weak_this_));
151 return;
152 }
153
154 ResetDecoder();
155 }
156
157 void AudioRendererImpl::ResetDecoder() {
158 DCHECK(task_runner_->BelongsToCurrentThread());
159 decoder_->Reset(base::Bind(&AudioRendererImpl::ResetDecoderDone, weak_this_));
160 } 150 }
161 151
162 void AudioRendererImpl::ResetDecoderDone() { 152 void AudioRendererImpl::ResetDecoderDone() {
163 DCHECK(task_runner_->BelongsToCurrentThread()); 153 DCHECK(task_runner_->BelongsToCurrentThread());
164 { 154 {
165 base::AutoLock auto_lock(lock_); 155 base::AutoLock auto_lock(lock_);
166 if (state_ == kStopped) 156 if (state_ == kStopped)
167 return; 157 return;
168 158
169 DCHECK_EQ(state_, kPaused); 159 DCHECK_EQ(state_, kPaused);
170 DCHECK(!flush_cb_.is_null()); 160 DCHECK(!flush_cb_.is_null());
171 161
172 audio_time_buffered_ = kNoTimestamp(); 162 audio_time_buffered_ = kNoTimestamp();
173 current_time_ = kNoTimestamp(); 163 current_time_ = kNoTimestamp();
174 received_end_of_stream_ = false; 164 received_end_of_stream_ = false;
175 rendered_end_of_stream_ = false; 165 rendered_end_of_stream_ = false;
176 preroll_aborted_ = false; 166 preroll_aborted_ = false;
177 167
178 earliest_end_time_ = now_cb_.Run(); 168 earliest_end_time_ = now_cb_.Run();
179 splicer_->Reset(); 169 splicer_->Reset();
180 algorithm_->FlushBuffers(); 170 algorithm_->FlushBuffers();
181 } 171 }
182 base::ResetAndReturn(&flush_cb_).Run(); 172 base::ResetAndReturn(&flush_cb_).Run();
183 } 173 }
184 174
185 void AudioRendererImpl::Stop(const base::Closure& callback) { 175 void AudioRendererImpl::Stop(const base::Closure& callback) {
186 DCHECK(task_runner_->BelongsToCurrentThread()); 176 DCHECK(task_runner_->BelongsToCurrentThread());
187 DCHECK(!callback.is_null()); 177 DCHECK(!callback.is_null());
188 DCHECK(stop_cb_.is_null());
189
190 stop_cb_ = callback;
191 178
192 // TODO(scherkus): Consider invalidating |weak_factory_| and replacing 179 // TODO(scherkus): Consider invalidating |weak_factory_| and replacing
193 // task-running guards that check |state_| with DCHECK(). 180 // task-running guards that check |state_| with DCHECK().
194 181
195 { 182 {
196 base::AutoLock auto_lock(lock_); 183 base::AutoLock auto_lock(lock_);
197 if (state_ == kInitializing) { 184
198 decoder_selector_->Abort(); 185 if (state_ == kStopped) {
186 task_runner_->PostTask(FROM_HERE, callback);
199 return; 187 return;
200 } 188 }
201 189
202 if (state_ == kStopped) {
203 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_));
204 return;
205 }
206
207 ChangeState_Locked(kStopped); 190 ChangeState_Locked(kStopped);
208 algorithm_.reset(); 191 algorithm_.reset();
209 underflow_cb_.Reset(); 192 underflow_cb_.Reset();
210 time_cb_.Reset(); 193 time_cb_.Reset();
211 flush_cb_.Reset(); 194 flush_cb_.Reset();
212 } 195 }
213 196
214 if (sink_) { 197 if (sink_) {
215 sink_->Stop(); 198 sink_->Stop();
216 sink_ = NULL; 199 sink_ = NULL;
217 } 200 }
218 201
219 if (decrypting_demuxer_stream_) { 202 audio_buffer_stream_.Stop(callback);
220 decrypting_demuxer_stream_->Stop(
221 base::Bind(&AudioRendererImpl::StopDecoder, weak_this_));
222 return;
223 }
224
225 StopDecoder();
226 }
227
228 void AudioRendererImpl::StopDecoder() {
229 DCHECK(task_runner_->BelongsToCurrentThread());
230 DCHECK(!stop_cb_.is_null());
231
232 if (decoder_) {
233 decoder_->Stop(base::ResetAndReturn(&stop_cb_));
234 return;
235 }
236
237 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_));
238 } 203 }
239 204
240 void AudioRendererImpl::Preroll(base::TimeDelta time, 205 void AudioRendererImpl::Preroll(base::TimeDelta time,
241 const PipelineStatusCB& cb) { 206 const PipelineStatusCB& cb) {
242 DCHECK(task_runner_->BelongsToCurrentThread()); 207 DCHECK(task_runner_->BelongsToCurrentThread());
243 208
244 base::AutoLock auto_lock(lock_); 209 base::AutoLock auto_lock(lock_);
245 DCHECK(!sink_playing_); 210 DCHECK(!sink_playing_);
246 DCHECK_EQ(state_, kPaused); 211 DCHECK_EQ(state_, kPaused);
247 DCHECK(!pending_read_) << "Pending read must complete before seeking"; 212 DCHECK(!pending_read_) << "Pending read must complete before seeking";
(...skipping 24 matching lines...) Expand all
272 DCHECK(!ended_cb.is_null()); 237 DCHECK(!ended_cb.is_null());
273 DCHECK(!disabled_cb.is_null()); 238 DCHECK(!disabled_cb.is_null());
274 DCHECK(!error_cb.is_null()); 239 DCHECK(!error_cb.is_null());
275 DCHECK_EQ(kUninitialized, state_); 240 DCHECK_EQ(kUninitialized, state_);
276 DCHECK(sink_); 241 DCHECK(sink_);
277 242
278 state_ = kInitializing; 243 state_ = kInitializing;
279 244
280 weak_this_ = weak_factory_.GetWeakPtr(); 245 weak_this_ = weak_factory_.GetWeakPtr();
281 init_cb_ = init_cb; 246 init_cb_ = init_cb;
282 statistics_cb_ = statistics_cb;
283 underflow_cb_ = underflow_cb; 247 underflow_cb_ = underflow_cb;
284 time_cb_ = time_cb; 248 time_cb_ = time_cb;
285 ended_cb_ = ended_cb; 249 ended_cb_ = ended_cb;
286 disabled_cb_ = disabled_cb; 250 disabled_cb_ = disabled_cb;
287 error_cb_ = error_cb; 251 error_cb_ = error_cb;
288 252
289 decoder_selector_->SelectDecoder( 253 audio_buffer_stream_.Initialize(
290 stream, 254 stream,
291 statistics_cb, 255 statistics_cb,
292 base::Bind(&AudioRendererImpl::OnDecoderSelected, weak_this_)); 256 base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized,
257 weak_this_));
293 } 258 }
294 259
295 void AudioRendererImpl::OnDecoderSelected( 260 void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) {
296 scoped_ptr<AudioDecoder> decoder,
297 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) {
298 DCHECK(task_runner_->BelongsToCurrentThread()); 261 DCHECK(task_runner_->BelongsToCurrentThread());
299 262
300 scoped_ptr<AudioDecoderSelector> deleter(decoder_selector_.Pass()); 263 base::AutoLock auto_lock(lock_);
301 decoder_ = decoder.Pass();
302 264
303 if (!decoder_ || !stop_cb_.is_null()) { 265 if (state_ == kStopped) {
304 { 266 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT);
305 base::AutoLock auto_lock(lock_);
306 ChangeState_Locked(kUninitialized);
307 }
308 // Stop() called during initialization.
309 if (!stop_cb_.is_null()) {
310 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT);
311 Stop(base::ResetAndReturn(&stop_cb_));
312 } else {
313 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
314 }
315 return; 267 return;
316 } 268 }
317 269
318 base::AutoLock auto_lock(lock_); 270 if (!success) {
319 decrypting_demuxer_stream_ = decrypting_demuxer_stream.Pass(); 271 state_ = kUninitialized;
272 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
273 return;
274 }
320 275
321 int sample_rate = decoder_->samples_per_second(); 276 int sample_rate = audio_buffer_stream_.decoder()->samples_per_second();
322 277
323 // The actual buffer size is controlled via the size of the AudioBus 278 // The actual buffer size is controlled via the size of the AudioBus
324 // provided to Render(), so just choose something reasonable here for looks. 279 // provided to Render(), so just choose something reasonable here for looks.
325 int buffer_size = decoder_->samples_per_second() / 100; 280 int buffer_size = audio_buffer_stream_.decoder()->samples_per_second() / 100;
326 audio_parameters_ = AudioParameters( 281
327 AudioParameters::AUDIO_PCM_LOW_LATENCY, decoder_->channel_layout(), 282 // TODO(rileya): Remove the channel_layout/bits_per_channel/samples_per_second
328 sample_rate, decoder_->bits_per_channel(), buffer_size); 283 // getters from AudioDecoder, and adjust this accordingly.
284 audio_parameters_ =
285 AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY,
286 audio_buffer_stream_.decoder()->channel_layout(),
287 sample_rate,
288 audio_buffer_stream_.decoder()->bits_per_channel(),
289 buffer_size);
329 if (!audio_parameters_.IsValid()) { 290 if (!audio_parameters_.IsValid()) {
330 ChangeState_Locked(kUninitialized); 291 ChangeState_Locked(kUninitialized);
331 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED); 292 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED);
332 return; 293 return;
333 } 294 }
334 295
335 splicer_.reset(new AudioSplicer(sample_rate)); 296 splicer_.reset(new AudioSplicer(sample_rate));
336 297
337 // We're all good! Continue initializing the rest of the audio renderer 298 // We're all good! Continue initializing the rest of the audio renderer
338 // based on the decoder format. 299 // based on the decoder format.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 } 335 }
375 } 336 }
376 337
377 void AudioRendererImpl::SetVolume(float volume) { 338 void AudioRendererImpl::SetVolume(float volume) {
378 DCHECK(task_runner_->BelongsToCurrentThread()); 339 DCHECK(task_runner_->BelongsToCurrentThread());
379 DCHECK(sink_); 340 DCHECK(sink_);
380 sink_->SetVolume(volume); 341 sink_->SetVolume(volume);
381 } 342 }
382 343
383 void AudioRendererImpl::DecodedAudioReady( 344 void AudioRendererImpl::DecodedAudioReady(
384 AudioDecoder::Status status, 345 AudioBufferStream::Status status,
385 const scoped_refptr<AudioBuffer>& buffer) { 346 const scoped_refptr<AudioBuffer>& buffer) {
386 DVLOG(1) << __FUNCTION__ << "(" << status << ")"; 347 DVLOG(1) << __FUNCTION__ << "(" << status << ")";
387 DCHECK(task_runner_->BelongsToCurrentThread()); 348 DCHECK(task_runner_->BelongsToCurrentThread());
388 349
389 base::AutoLock auto_lock(lock_); 350 base::AutoLock auto_lock(lock_);
390 DCHECK(state_ != kUninitialized); 351 DCHECK(state_ != kUninitialized);
391 352
392 CHECK(pending_read_); 353 CHECK(pending_read_);
393 pending_read_ = false; 354 pending_read_ = false;
394 355
395 if (status == AudioDecoder::kAborted) { 356 if (status == AudioBufferStream::ABORTED ||
357 status == AudioBufferStream::DEMUXER_READ_ABORTED) {
396 HandleAbortedReadOrDecodeError(false); 358 HandleAbortedReadOrDecodeError(false);
397 return; 359 return;
398 } 360 }
399 361
400 if (status == AudioDecoder::kDecodeError) { 362 if (status == AudioBufferStream::DECODE_ERROR) {
401 HandleAbortedReadOrDecodeError(true); 363 HandleAbortedReadOrDecodeError(true);
402 return; 364 return;
403 } 365 }
404 366
405 DCHECK_EQ(status, AudioDecoder::kOk); 367 DCHECK_EQ(status, AudioBufferStream::OK);
406 DCHECK(buffer.get()); 368 DCHECK(buffer.get());
407 369
408 if (state_ == kFlushing) { 370 if (state_ == kFlushing) {
409 ChangeState_Locked(kPaused); 371 ChangeState_Locked(kPaused);
410 DoFlush_Locked(); 372 DoFlush_Locked();
411 return; 373 return;
412 } 374 }
413 375
414 if (!splicer_->AddInput(buffer)) { 376 if (!splicer_->AddInput(buffer)) {
415 HandleAbortedReadOrDecodeError(true); 377 HandleAbortedReadOrDecodeError(true);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 } 464 }
503 465
504 void AudioRendererImpl::AttemptRead_Locked() { 466 void AudioRendererImpl::AttemptRead_Locked() {
505 DCHECK(task_runner_->BelongsToCurrentThread()); 467 DCHECK(task_runner_->BelongsToCurrentThread());
506 lock_.AssertAcquired(); 468 lock_.AssertAcquired();
507 469
508 if (!CanRead_Locked()) 470 if (!CanRead_Locked())
509 return; 471 return;
510 472
511 pending_read_ = true; 473 pending_read_ = true;
512 decoder_->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady, weak_this_)); 474 audio_buffer_stream_.Read(
475 base::Bind(&AudioRendererImpl::DecodedAudioReady, weak_this_));
513 } 476 }
514 477
515 bool AudioRendererImpl::CanRead_Locked() { 478 bool AudioRendererImpl::CanRead_Locked() {
516 lock_.AssertAcquired(); 479 lock_.AssertAcquired();
517 480
518 switch (state_) { 481 switch (state_) {
519 case kUninitialized: 482 case kUninitialized:
520 case kInitializing: 483 case kInitializing:
521 case kPaused: 484 case kPaused:
522 case kFlushing: 485 case kFlushing:
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 } 704 }
742 } 705 }
743 706
744 void AudioRendererImpl::ChangeState_Locked(State new_state) { 707 void AudioRendererImpl::ChangeState_Locked(State new_state) {
745 DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state; 708 DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state;
746 lock_.AssertAcquired(); 709 lock_.AssertAcquired();
747 state_ = new_state; 710 state_ = new_state;
748 } 711 }
749 712
750 } // namespace media 713 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698