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

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

Powered by Google App Engine
This is Rietveld 408576698