| 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/base/audio_renderer_mixer_input.h" | 5 #include "media/base/audio_renderer_mixer_input.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 started_ = true; | 59 started_ = true; |
| 60 mixer_ = mixer_pool_->GetMixer(owner_id_, params_, latency_, device_id_, | 60 mixer_ = mixer_pool_->GetMixer(owner_id_, params_, latency_, device_id_, |
| 61 security_origin_, nullptr); | 61 security_origin_, nullptr); |
| 62 if (!mixer_) { | 62 if (!mixer_) { |
| 63 callback_->OnRenderError(); | 63 callback_->OnRenderError(); |
| 64 return; | 64 return; |
| 65 } | 65 } |
| 66 | 66 |
| 67 // Note: OnRenderError() may be called immediately after this call returns. | 67 // Note: OnRenderError() may be called immediately after this call returns. |
| 68 mixer_->AddErrorCallback(error_cb_); | 68 mixer_->AddErrorCallback(error_cb_); |
| 69 | |
| 70 if (!pending_switch_callback_.is_null()) { | |
| 71 SwitchOutputDevice(pending_switch_device_id_, | |
| 72 pending_switch_security_origin_, | |
| 73 base::ResetAndReturn(&pending_switch_callback_)); | |
| 74 } | |
| 75 } | 69 } |
| 76 | 70 |
| 77 void AudioRendererMixerInput::Stop() { | 71 void AudioRendererMixerInput::Stop() { |
| 78 // Stop() may be called at any time, if Pause() hasn't been called we need to | 72 // Stop() may be called at any time, if Pause() hasn't been called we need to |
| 79 // remove our mixer input before shutdown. | 73 // remove our mixer input before shutdown. |
| 80 Pause(); | 74 Pause(); |
| 81 | 75 |
| 82 if (mixer_) { | 76 if (mixer_) { |
| 83 // TODO(dalecurtis): This is required so that |callback_| isn't called after | 77 // TODO(dalecurtis): This is required so that |callback_| isn't called after |
| 84 // Stop() by an error event since it may outlive this ref-counted object. We | 78 // Stop() by an error event since it may outlive this ref-counted object. We |
| 85 // should instead have sane ownership semantics: http://crbug.com/151051 | 79 // should instead have sane ownership semantics: http://crbug.com/151051 |
| 86 mixer_->RemoveErrorCallback(error_cb_); | 80 mixer_->RemoveErrorCallback(error_cb_); |
| 87 mixer_pool_->ReturnMixer(mixer_); | 81 mixer_pool_->ReturnMixer(mixer_); |
| 88 mixer_ = nullptr; | 82 mixer_ = nullptr; |
| 89 } | 83 } |
| 90 | 84 |
| 91 started_ = false; | 85 started_ = false; |
| 92 | |
| 93 if (!pending_switch_callback_.is_null()) { | |
| 94 base::ResetAndReturn(&pending_switch_callback_) | |
| 95 .Run(OUTPUT_DEVICE_STATUS_ERROR_INTERNAL); | |
| 96 } | |
| 97 } | 86 } |
| 98 | 87 |
| 99 void AudioRendererMixerInput::Play() { | 88 void AudioRendererMixerInput::Play() { |
| 100 if (playing_ || !mixer_) | 89 if (playing_ || !mixer_) |
| 101 return; | 90 return; |
| 102 | 91 |
| 103 mixer_->AddMixerInput(params_, this); | 92 mixer_->AddMixerInput(params_, this); |
| 104 playing_ = true; | 93 playing_ = true; |
| 105 } | 94 } |
| 106 | 95 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 126 } | 115 } |
| 127 | 116 |
| 128 bool AudioRendererMixerInput::CurrentThreadIsRenderingThread() { | 117 bool AudioRendererMixerInput::CurrentThreadIsRenderingThread() { |
| 129 return mixer_->CurrentThreadIsRenderingThread(); | 118 return mixer_->CurrentThreadIsRenderingThread(); |
| 130 } | 119 } |
| 131 | 120 |
| 132 void AudioRendererMixerInput::SwitchOutputDevice( | 121 void AudioRendererMixerInput::SwitchOutputDevice( |
| 133 const std::string& device_id, | 122 const std::string& device_id, |
| 134 const url::Origin& security_origin, | 123 const url::Origin& security_origin, |
| 135 const OutputDeviceStatusCB& callback) { | 124 const OutputDeviceStatusCB& callback) { |
| 136 if (!mixer_) { | |
| 137 if (pending_switch_callback_.is_null()) { | |
| 138 pending_switch_callback_ = callback; | |
| 139 pending_switch_device_id_ = device_id; | |
| 140 pending_switch_security_origin_ = security_origin; | |
| 141 } else { | |
| 142 callback.Run(OUTPUT_DEVICE_STATUS_ERROR_INTERNAL); | |
| 143 } | |
| 144 | |
| 145 return; | |
| 146 } | |
| 147 | |
| 148 DCHECK(pending_switch_callback_.is_null()); | |
| 149 if (device_id == device_id_) { | 125 if (device_id == device_id_) { |
| 150 callback.Run(OUTPUT_DEVICE_STATUS_OK); | 126 callback.Run(OUTPUT_DEVICE_STATUS_OK); |
| 151 return; | 127 return; |
| 152 } | 128 } |
| 153 | 129 |
| 154 OutputDeviceStatus new_mixer_status = OUTPUT_DEVICE_STATUS_ERROR_INTERNAL; | 130 OutputDeviceStatus new_mixer_status = OUTPUT_DEVICE_STATUS_ERROR_INTERNAL; |
| 155 AudioRendererMixer* new_mixer = | 131 AudioRendererMixer* new_mixer = |
| 156 mixer_pool_->GetMixer(owner_id_, params_, latency_, device_id, | 132 mixer_pool_->GetMixer(owner_id_, params_, latency_, device_id, |
| 157 security_origin, &new_mixer_status); | 133 security_origin, &new_mixer_status); |
| 158 if (new_mixer_status != OUTPUT_DEVICE_STATUS_OK) { | 134 if (new_mixer_status != OUTPUT_DEVICE_STATUS_OK) { |
| 159 callback.Run(new_mixer_status); | 135 callback.Run(new_mixer_status); |
| 160 return; | 136 return; |
| 161 } | 137 } |
| 162 | 138 |
| 163 bool was_playing = playing_; | |
| 164 Stop(); | |
| 165 device_id_ = device_id; | 139 device_id_ = device_id; |
| 166 security_origin_ = security_origin; | 140 security_origin_ = security_origin; |
| 167 mixer_ = new_mixer; | |
| 168 mixer_->AddErrorCallback(error_cb_); | |
| 169 started_ = true; | |
| 170 | 141 |
| 171 if (was_playing) | 142 if (mixer_) { |
| 172 Play(); | 143 bool was_playing = playing_; |
| 144 Stop(); |
| 145 mixer_ = new_mixer; |
| 146 mixer_->AddErrorCallback(error_cb_); |
| 147 started_ = true; |
| 148 if (was_playing) |
| 149 Play(); |
| 150 } else { |
| 151 mixer_pool_->ReturnMixer(new_mixer); |
| 152 } |
| 173 | 153 |
| 174 callback.Run(OUTPUT_DEVICE_STATUS_OK); | 154 callback.Run(OUTPUT_DEVICE_STATUS_OK); |
| 175 } | 155 } |
| 176 | 156 |
| 177 double AudioRendererMixerInput::ProvideInput(AudioBus* audio_bus, | 157 double AudioRendererMixerInput::ProvideInput(AudioBus* audio_bus, |
| 178 uint32_t frames_delayed) { | 158 uint32_t frames_delayed) { |
| 179 TRACE_EVENT0("audio", "AudioRendererMixerInput::ProvideInput"); | 159 TRACE_EVENT0("audio", "AudioRendererMixerInput::ProvideInput"); |
| 180 int frames_filled = callback_->Render(audio_bus, frames_delayed, 0); | 160 int frames_filled = callback_->Render(audio_bus, frames_delayed, 0); |
| 181 | 161 |
| 182 // AudioConverter expects unfilled frames to be zeroed. | 162 // AudioConverter expects unfilled frames to be zeroed. |
| 183 if (frames_filled < audio_bus->frames()) { | 163 if (frames_filled < audio_bus->frames()) { |
| 184 audio_bus->ZeroFramesPartial( | 164 audio_bus->ZeroFramesPartial( |
| 185 frames_filled, audio_bus->frames() - frames_filled); | 165 frames_filled, audio_bus->frames() - frames_filled); |
| 186 } | 166 } |
| 187 | 167 |
| 188 // We're reading |volume_| from the audio device thread and must avoid racing | 168 // We're reading |volume_| from the audio device thread and must avoid racing |
| 189 // with the main/media thread calls to SetVolume(). See thread safety comment | 169 // with the main/media thread calls to SetVolume(). See thread safety comment |
| 190 // in the header file. | 170 // in the header file. |
| 191 { | 171 { |
| 192 base::AutoLock auto_lock(volume_lock_); | 172 base::AutoLock auto_lock(volume_lock_); |
| 193 return frames_filled > 0 ? volume_ : 0; | 173 return frames_filled > 0 ? volume_ : 0; |
| 194 } | 174 } |
| 195 } | 175 } |
| 196 | 176 |
| 197 void AudioRendererMixerInput::OnRenderError() { | 177 void AudioRendererMixerInput::OnRenderError() { |
| 198 callback_->OnRenderError(); | 178 callback_->OnRenderError(); |
| 199 } | 179 } |
| 200 | 180 |
| 201 } // namespace media | 181 } // namespace media |
| OLD | NEW |