Chromium Code Reviews| Index: content/renderer/media/audio_renderer_impl.cc |
| =================================================================== |
| --- content/renderer/media/audio_renderer_impl.cc (revision 114311) |
| +++ content/renderer/media/audio_renderer_impl.cc (working copy) |
| @@ -38,13 +38,17 @@ |
| AudioRendererImpl::AudioRendererImpl() |
| : AudioRendererBase(), |
| bytes_per_second_(0), |
| - stopped_(false) { |
| + stopped_(false), |
| + is_initialized_(false) { |
| // We create the AudioDevice here because it must be created in the |
| // main thread. But we don't yet know the audio format (sample-rate, etc.) |
| // at this point. Later, when OnInitialize() is called, we have |
| // the audio format information and call the AudioDevice::Initialize() |
| // method to fully initialize it. |
| audio_device_ = new AudioDevice(); |
| + |
| + // Assign the AudioDevice as the default audio sink. |
| + sink_ = audio_device_.get(); |
|
acolwell GONE FROM CHROMIUM
2011/12/19 23:01:49
How about passing the sink in via the constructor?
Chris Rogers
2011/12/19 23:28:14
We can't pass it in via the constructor because th
acolwell GONE FROM CHROMIUM
2011/12/20 01:04:06
Why can't we hide this fact from this code though?
Chris Rogers
2011/12/21 01:38:17
Done.
|
| } |
| AudioRendererImpl::~AudioRendererImpl() { |
| @@ -90,17 +94,20 @@ |
| bytes_per_second_ = audio_parameters_.GetBytesPerSecond(); |
| - DCHECK(audio_device_.get()); |
| + base::AutoLock auto_lock(sink_lock_); |
| - if (!audio_device_->IsInitialized()) { |
| - audio_device_->Initialize( |
| + DCHECK(sink_); |
| + |
| + if (!is_initialized_) { |
| + sink_->Initialize( |
| GetBufferSizeForSampleRate(sample_rate), |
| audio_parameters_.channels, |
| audio_parameters_.sample_rate, |
| audio_parameters_.format, |
| this); |
| - audio_device_->Start(); |
| + sink_->Start(); |
| + is_initialized_ = true; |
| } |
|
no longer working on chromium
2011/12/20 15:47:19
shall we returns false when it has been initialize
Chris Rogers
2011/12/21 01:38:17
Done.
|
| return true; |
| @@ -110,8 +117,9 @@ |
| if (stopped_) |
| return; |
| - DCHECK(audio_device_.get()); |
| - audio_device_->Stop(); |
| + base::AutoLock auto_lock(sink_lock_); |
| + DCHECK(sink_); |
| + sink_->Stop(); |
| stopped_ = true; |
| } |
| @@ -169,27 +177,31 @@ |
| void AudioRendererImpl::SetVolume(float volume) { |
| if (stopped_) |
| return; |
| - DCHECK(audio_device_.get()); |
| - audio_device_->SetVolume(volume); |
| + base::AutoLock auto_lock(sink_lock_); |
| + DCHECK(sink_); |
| + sink_->SetVolume(volume); |
| } |
| void AudioRendererImpl::DoPlay() { |
| earliest_end_time_ = base::Time::Now(); |
| - DCHECK(audio_device_.get()); |
| - audio_device_->Play(); |
| + base::AutoLock auto_lock(sink_lock_); |
| + DCHECK(sink_); |
| + sink_->Play(); |
| } |
| void AudioRendererImpl::DoPause() { |
| - DCHECK(audio_device_.get()); |
| - audio_device_->Pause(false); |
| + base::AutoLock auto_lock(sink_lock_); |
| + DCHECK(sink_); |
| + sink_->Pause(false); |
| } |
| void AudioRendererImpl::DoSeek() { |
| earliest_end_time_ = base::Time::Now(); |
| // Pause and flush the stream when we seek to a new location. |
| - DCHECK(audio_device_.get()); |
| - audio_device_->Pause(true); |
| + base::AutoLock auto_lock(sink_lock_); |
| + DCHECK(sink_); |
| + sink_->Pause(true); |
| } |
| void AudioRendererImpl::Render(const std::vector<float*>& audio_data, |
| @@ -245,3 +257,41 @@ |
| } |
| } |
| } |
| + |
| +void AudioRendererImpl::SetAudioRendererSink(media::AudioRendererSink* sink) { |
| + // NULL should be passed in to use the default AudioDevice sink. |
| + DCHECK_NE(sink, audio_device_.get()); |
| + |
| + // Synchronize with other uses of sink_ since we're messing with it here. |
| + base::AutoLock auto_lock(sink_lock_); |
| + |
| + if (sink && sink != sink_) { |
| + // We're switching rendering to a different sink than the AudioDevice. |
| + |
| + // Since we're no longer rendering to the AudioDevice, we don't want |
| + // it to make callbacks to us anymore. |
| + if (sink_ == audio_device_.get()) |
|
no longer working on chromium
2011/12/20 15:47:19
if sink_!=audio_device_.get(), do we also need to
Chris Rogers
2011/12/21 01:38:17
Yes, I've generalized this code.
On 2011/12/20 15
|
| + audio_device_->Pause(true); |
| + |
| + sink_ = sink; |
| + if (is_initialized_ && !stopped_) { |
| + // The sink needs to be notified of the audio format, if available. |
| + // If the format is not yet available, it will later be called |
| + // in OnInitialize(). |
| + sink_->Initialize( |
| + GetBufferSizeForSampleRate(audio_parameters_.sample_rate), |
| + audio_parameters_.channels, |
| + audio_parameters_.sample_rate, |
| + audio_parameters_.format, |
| + this); |
| + sink_->Start(); |
| + } |
| + } else if (!sink && sink_ != audio_device_.get()) { |
| + sink_->Stop(); |
| + // Revert from custom sink back to default sink. |
| + sink_ = audio_device_.get(); |
| + |
| + // TODO(crogers): We should call audio_device_->Play() if we're |
| + // in the playing state. |
| + } |
|
no longer working on chromium
2011/12/20 15:47:19
Just want to make sure what happens if sink==NULL
Chris Rogers
2011/12/21 01:38:17
If sink==NULL and sink_==audio_device_.get() then
|
| +} |