OLD | NEW |
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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 media::AudioRendererSink* sink, | 45 media::AudioRendererSink* sink, |
46 ScopedVector<AudioDecoder> decoders, | 46 ScopedVector<AudioDecoder> decoders, |
47 const SetDecryptorReadyCB& set_decryptor_ready_cb, | 47 const SetDecryptorReadyCB& set_decryptor_ready_cb, |
48 AudioHardwareConfig* hardware_config) | 48 AudioHardwareConfig* hardware_config) |
49 : task_runner_(task_runner), | 49 : task_runner_(task_runner), |
50 sink_(sink), | 50 sink_(sink), |
51 audio_buffer_stream_(new AudioBufferStream(task_runner, | 51 audio_buffer_stream_(new AudioBufferStream(task_runner, |
52 decoders.Pass(), | 52 decoders.Pass(), |
53 set_decryptor_ready_cb)), | 53 set_decryptor_ready_cb)), |
54 hardware_config_(hardware_config), | 54 hardware_config_(hardware_config), |
| 55 playback_rate_(0), |
55 state_(kUninitialized), | 56 state_(kUninitialized), |
56 buffering_state_(BUFFERING_HAVE_NOTHING), | 57 buffering_state_(BUFFERING_HAVE_NOTHING), |
57 rendering_(false), | 58 rendering_(false), |
58 sink_playing_(false), | 59 sink_playing_(false), |
59 pending_read_(false), | 60 pending_read_(false), |
60 received_end_of_stream_(false), | 61 received_end_of_stream_(false), |
61 rendered_end_of_stream_(false), | 62 rendered_end_of_stream_(false), |
62 weak_factory_(this) { | 63 weak_factory_(this) { |
63 audio_buffer_stream_->set_splice_observer(base::Bind( | 64 audio_buffer_stream_->set_splice_observer(base::Bind( |
64 &AudioRendererImpl::OnNewSpliceBuffer, weak_factory_.GetWeakPtr())); | 65 &AudioRendererImpl::OnNewSpliceBuffer, weak_factory_.GetWeakPtr())); |
65 audio_buffer_stream_->set_config_change_observer(base::Bind( | 66 audio_buffer_stream_->set_config_change_observer(base::Bind( |
66 &AudioRendererImpl::OnConfigChange, weak_factory_.GetWeakPtr())); | 67 &AudioRendererImpl::OnConfigChange, weak_factory_.GetWeakPtr())); |
67 } | 68 } |
68 | 69 |
69 AudioRendererImpl::~AudioRendererImpl() { | 70 AudioRendererImpl::~AudioRendererImpl() { |
70 // Stop() should have been called and |algorithm_| should have been destroyed. | 71 // Stop() should have been called and |algorithm_| should have been destroyed. |
71 DCHECK(state_ == kUninitialized || state_ == kStopped); | 72 DCHECK(state_ == kUninitialized || state_ == kStopped); |
72 DCHECK(!algorithm_.get()); | 73 DCHECK(!algorithm_.get()); |
73 } | 74 } |
74 | 75 |
75 void AudioRendererImpl::StartRendering() { | 76 void AudioRendererImpl::StartRendering() { |
76 DVLOG(1) << __FUNCTION__; | 77 DVLOG(1) << __FUNCTION__; |
77 DCHECK(task_runner_->BelongsToCurrentThread()); | 78 DCHECK(task_runner_->BelongsToCurrentThread()); |
78 DCHECK(!rendering_); | 79 DCHECK(!rendering_); |
79 rendering_ = true; | 80 rendering_ = true; |
80 | 81 |
81 base::AutoLock auto_lock(lock_); | 82 base::AutoLock auto_lock(lock_); |
82 // Wait for an eventual call to SetPlaybackRate() to start rendering. | 83 // Wait for an eventual call to SetPlaybackRate() to start rendering. |
83 if (algorithm_->playback_rate() == 0) { | 84 if (playback_rate_ == 0) { |
84 DCHECK(!sink_playing_); | 85 DCHECK(!sink_playing_); |
85 return; | 86 return; |
86 } | 87 } |
87 | 88 |
88 StartRendering_Locked(); | 89 StartRendering_Locked(); |
89 } | 90 } |
90 | 91 |
91 void AudioRendererImpl::StartRendering_Locked() { | 92 void AudioRendererImpl::StartRendering_Locked() { |
92 DVLOG(1) << __FUNCTION__; | 93 DVLOG(1) << __FUNCTION__; |
93 DCHECK(task_runner_->BelongsToCurrentThread()); | 94 DCHECK(task_runner_->BelongsToCurrentThread()); |
94 DCHECK_EQ(state_, kPlaying); | 95 DCHECK_EQ(state_, kPlaying); |
95 DCHECK(!sink_playing_); | 96 DCHECK(!sink_playing_); |
96 DCHECK_NE(algorithm_->playback_rate(), 0); | 97 DCHECK_NE(playback_rate_, 0); |
97 lock_.AssertAcquired(); | 98 lock_.AssertAcquired(); |
98 | 99 |
99 sink_playing_ = true; | 100 sink_playing_ = true; |
100 | 101 |
101 base::AutoUnlock auto_unlock(lock_); | 102 base::AutoUnlock auto_unlock(lock_); |
102 sink_->Play(); | 103 sink_->Play(); |
103 } | 104 } |
104 | 105 |
105 void AudioRendererImpl::StopRendering() { | 106 void AudioRendererImpl::StopRendering() { |
106 DVLOG(1) << __FUNCTION__; | 107 DVLOG(1) << __FUNCTION__; |
107 DCHECK(task_runner_->BelongsToCurrentThread()); | 108 DCHECK(task_runner_->BelongsToCurrentThread()); |
108 DCHECK(rendering_); | 109 DCHECK(rendering_); |
109 rendering_ = false; | 110 rendering_ = false; |
110 | 111 |
111 base::AutoLock auto_lock(lock_); | 112 base::AutoLock auto_lock(lock_); |
112 // Rendering should have already been stopped with a zero playback rate. | 113 // Rendering should have already been stopped with a zero playback rate. |
113 if (algorithm_->playback_rate() == 0) { | 114 if (playback_rate_ == 0) { |
114 DCHECK(!sink_playing_); | 115 DCHECK(!sink_playing_); |
115 return; | 116 return; |
116 } | 117 } |
117 | 118 |
118 StopRendering_Locked(); | 119 StopRendering_Locked(); |
119 } | 120 } |
120 | 121 |
121 void AudioRendererImpl::StopRendering_Locked() { | 122 void AudioRendererImpl::StopRendering_Locked() { |
122 DCHECK(task_runner_->BelongsToCurrentThread()); | 123 DCHECK(task_runner_->BelongsToCurrentThread()); |
123 DCHECK_EQ(state_, kPlaying); | 124 DCHECK_EQ(state_, kPlaying); |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 return; | 337 return; |
337 } | 338 } |
338 | 339 |
339 if (expecting_config_changes_) | 340 if (expecting_config_changes_) |
340 buffer_converter_.reset(new AudioBufferConverter(audio_parameters_)); | 341 buffer_converter_.reset(new AudioBufferConverter(audio_parameters_)); |
341 splicer_.reset(new AudioSplicer(audio_parameters_.sample_rate())); | 342 splicer_.reset(new AudioSplicer(audio_parameters_.sample_rate())); |
342 | 343 |
343 // We're all good! Continue initializing the rest of the audio renderer | 344 // We're all good! Continue initializing the rest of the audio renderer |
344 // based on the decoder format. | 345 // based on the decoder format. |
345 algorithm_.reset(new AudioRendererAlgorithm()); | 346 algorithm_.reset(new AudioRendererAlgorithm()); |
346 algorithm_->Initialize(0, audio_parameters_); | 347 algorithm_->Initialize(audio_parameters_); |
347 | 348 |
348 ChangeState_Locked(kFlushed); | 349 ChangeState_Locked(kFlushed); |
349 | 350 |
350 HistogramRendererEvent(INITIALIZED); | 351 HistogramRendererEvent(INITIALIZED); |
351 | 352 |
352 { | 353 { |
353 base::AutoUnlock auto_unlock(lock_); | 354 base::AutoUnlock auto_unlock(lock_); |
354 sink_->Initialize(audio_parameters_, this); | 355 sink_->Initialize(audio_parameters_, this); |
355 sink_->Start(); | 356 sink_->Start(); |
356 | 357 |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
523 DVLOG(1) << __FUNCTION__ << "(" << playback_rate << ")"; | 524 DVLOG(1) << __FUNCTION__ << "(" << playback_rate << ")"; |
524 DCHECK(task_runner_->BelongsToCurrentThread()); | 525 DCHECK(task_runner_->BelongsToCurrentThread()); |
525 DCHECK_GE(playback_rate, 0); | 526 DCHECK_GE(playback_rate, 0); |
526 DCHECK(sink_); | 527 DCHECK(sink_); |
527 | 528 |
528 base::AutoLock auto_lock(lock_); | 529 base::AutoLock auto_lock(lock_); |
529 | 530 |
530 // We have two cases here: | 531 // We have two cases here: |
531 // Play: current_playback_rate == 0 && playback_rate != 0 | 532 // Play: current_playback_rate == 0 && playback_rate != 0 |
532 // Pause: current_playback_rate != 0 && playback_rate == 0 | 533 // Pause: current_playback_rate != 0 && playback_rate == 0 |
533 float current_playback_rate = algorithm_->playback_rate(); | 534 float current_playback_rate = playback_rate_; |
534 algorithm_->SetPlaybackRate(playback_rate); | 535 playback_rate_ = playback_rate; |
535 | 536 |
536 if (!rendering_) | 537 if (!rendering_) |
537 return; | 538 return; |
538 | 539 |
539 if (current_playback_rate == 0 && playback_rate != 0) { | 540 if (current_playback_rate == 0 && playback_rate != 0) { |
540 StartRendering_Locked(); | 541 StartRendering_Locked(); |
541 return; | 542 return; |
542 } | 543 } |
543 | 544 |
544 if (current_playback_rate != 0 && playback_rate == 0) { | 545 if (current_playback_rate != 0 && playback_rate == 0) { |
(...skipping 20 matching lines...) Expand all Loading... |
565 base::Closure time_cb; | 566 base::Closure time_cb; |
566 { | 567 { |
567 base::AutoLock auto_lock(lock_); | 568 base::AutoLock auto_lock(lock_); |
568 | 569 |
569 // Ensure Stop() hasn't destroyed our |algorithm_| on the pipeline thread. | 570 // Ensure Stop() hasn't destroyed our |algorithm_| on the pipeline thread. |
570 if (!algorithm_) { | 571 if (!algorithm_) { |
571 audio_clock_->WroteSilence(requested_frames, delay_frames); | 572 audio_clock_->WroteSilence(requested_frames, delay_frames); |
572 return 0; | 573 return 0; |
573 } | 574 } |
574 | 575 |
575 float playback_rate = algorithm_->playback_rate(); | 576 if (playback_rate_ == 0) { |
576 if (playback_rate == 0) { | |
577 audio_clock_->WroteSilence(requested_frames, delay_frames); | 577 audio_clock_->WroteSilence(requested_frames, delay_frames); |
578 return 0; | 578 return 0; |
579 } | 579 } |
580 | 580 |
581 // Mute audio by returning 0 when not playing. | 581 // Mute audio by returning 0 when not playing. |
582 if (state_ != kPlaying) { | 582 if (state_ != kPlaying) { |
583 audio_clock_->WroteSilence(requested_frames, delay_frames); | 583 audio_clock_->WroteSilence(requested_frames, delay_frames); |
584 return 0; | 584 return 0; |
585 } | 585 } |
586 | 586 |
587 // We use the following conditions to determine end of playback: | 587 // We use the following conditions to determine end of playback: |
588 // 1) Algorithm can not fill the audio callback buffer | 588 // 1) Algorithm can not fill the audio callback buffer |
589 // 2) We received an end of stream buffer | 589 // 2) We received an end of stream buffer |
590 // 3) We haven't already signalled that we've ended | 590 // 3) We haven't already signalled that we've ended |
591 // 4) We've played all known audio data sent to hardware | 591 // 4) We've played all known audio data sent to hardware |
592 // | 592 // |
593 // We use the following conditions to determine underflow: | 593 // We use the following conditions to determine underflow: |
594 // 1) Algorithm can not fill the audio callback buffer | 594 // 1) Algorithm can not fill the audio callback buffer |
595 // 2) We have NOT received an end of stream buffer | 595 // 2) We have NOT received an end of stream buffer |
596 // 3) We are in the kPlaying state | 596 // 3) We are in the kPlaying state |
597 // | 597 // |
598 // Otherwise the buffer has data we can send to the device. | 598 // Otherwise the buffer has data we can send to the device. |
599 const base::TimeDelta media_timestamp_before_filling = | 599 const base::TimeDelta media_timestamp_before_filling = |
600 audio_clock_->CurrentMediaTimestamp(base::TimeDelta()); | 600 audio_clock_->CurrentMediaTimestamp(base::TimeDelta()); |
601 if (algorithm_->frames_buffered() > 0) { | 601 if (algorithm_->frames_buffered() > 0) { |
602 frames_written = algorithm_->FillBuffer(audio_bus, requested_frames); | 602 frames_written = |
| 603 algorithm_->FillBuffer(audio_bus, requested_frames, playback_rate_); |
603 audio_clock_->WroteAudio( | 604 audio_clock_->WroteAudio( |
604 frames_written, delay_frames, playback_rate, algorithm_->GetTime()); | 605 frames_written, delay_frames, playback_rate_, algorithm_->GetTime()); |
605 } | 606 } |
606 audio_clock_->WroteSilence(requested_frames - frames_written, delay_frames); | 607 audio_clock_->WroteSilence(requested_frames - frames_written, delay_frames); |
607 | 608 |
608 if (frames_written == 0) { | 609 if (frames_written == 0) { |
609 if (received_end_of_stream_ && !rendered_end_of_stream_ && | 610 if (received_end_of_stream_ && !rendered_end_of_stream_ && |
610 audio_clock_->CurrentMediaTimestamp(base::TimeDelta()) == | 611 audio_clock_->CurrentMediaTimestamp(base::TimeDelta()) == |
611 audio_clock_->last_endpoint_timestamp()) { | 612 audio_clock_->last_endpoint_timestamp()) { |
612 rendered_end_of_stream_ = true; | 613 rendered_end_of_stream_ = true; |
613 ended_cb_.Run(); | 614 ended_cb_.Run(); |
614 } else if (!received_end_of_stream_ && state_ == kPlaying) { | 615 } else if (!received_end_of_stream_ && state_ == kPlaying) { |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 << buffering_state; | 711 << buffering_state; |
711 DCHECK_NE(buffering_state_, buffering_state); | 712 DCHECK_NE(buffering_state_, buffering_state); |
712 lock_.AssertAcquired(); | 713 lock_.AssertAcquired(); |
713 buffering_state_ = buffering_state; | 714 buffering_state_ = buffering_state; |
714 | 715 |
715 task_runner_->PostTask(FROM_HERE, | 716 task_runner_->PostTask(FROM_HERE, |
716 base::Bind(buffering_state_cb_, buffering_state_)); | 717 base::Bind(buffering_state_cb_, buffering_state_)); |
717 } | 718 } |
718 | 719 |
719 } // namespace media | 720 } // namespace media |
OLD | NEW |