Chromium Code Reviews| 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 "content/renderer/media/webrtc_audio_capturer.h" | 5 #include "content/renderer/media/webrtc_audio_capturer.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 127 } | 127 } |
| 128 | 128 |
| 129 // Tell all sinks which format we use. | 129 // Tell all sinks which format we use. |
| 130 for (SinkList::const_iterator it = sinks.begin(); it != sinks.end(); ++it) | 130 for (SinkList::const_iterator it = sinks.begin(); it != sinks.end(); ++it) |
| 131 (*it)->SetCaptureFormat(new_buffer->params()); | 131 (*it)->SetCaptureFormat(new_buffer->params()); |
| 132 | 132 |
| 133 return true; | 133 return true; |
| 134 } | 134 } |
| 135 | 135 |
| 136 bool WebRtcAudioCapturer::Initialize(media::ChannelLayout channel_layout, | 136 bool WebRtcAudioCapturer::Initialize(media::ChannelLayout channel_layout, |
| 137 int sample_rate) { | 137 int sample_rate, |
| 138 int session_id) { | |
| 138 DCHECK(thread_checker_.CalledOnValidThread()); | 139 DCHECK(thread_checker_.CalledOnValidThread()); |
| 139 DCHECK(!sinks_.empty()); | 140 DCHECK(!sinks_.empty()); |
| 140 DVLOG(1) << "WebRtcAudioCapturer::Initialize()"; | 141 DVLOG(1) << "WebRtcAudioCapturer::Initialize()"; |
| 141 | 142 |
| 142 DVLOG(1) << "Audio input hardware channel layout: " << channel_layout; | 143 DVLOG(1) << "Audio input hardware channel layout: " << channel_layout; |
| 143 UMA_HISTOGRAM_ENUMERATION("WebRTC.AudioInputChannelLayout", | 144 UMA_HISTOGRAM_ENUMERATION("WebRTC.AudioInputChannelLayout", |
| 144 channel_layout, media::CHANNEL_LAYOUT_MAX); | 145 channel_layout, media::CHANNEL_LAYOUT_MAX); |
| 145 | 146 |
| 147 session_id_ = session_id; | |
| 148 | |
| 146 // Verify that the reported input channel configuration is supported. | 149 // Verify that the reported input channel configuration is supported. |
| 147 if (channel_layout != media::CHANNEL_LAYOUT_MONO && | 150 if (channel_layout != media::CHANNEL_LAYOUT_MONO && |
| 148 channel_layout != media::CHANNEL_LAYOUT_STEREO) { | 151 channel_layout != media::CHANNEL_LAYOUT_STEREO) { |
| 149 DLOG(ERROR) << channel_layout | 152 DLOG(ERROR) << channel_layout |
| 150 << " is not a supported input channel configuration."; | 153 << " is not a supported input channel configuration."; |
| 151 return false; | 154 return false; |
| 152 } | 155 } |
| 153 | 156 |
| 154 DVLOG(1) << "Audio input hardware sample rate: " << sample_rate; | 157 DVLOG(1) << "Audio input hardware sample rate: " << sample_rate; |
| 155 UMA_HISTOGRAM_ENUMERATION("WebRTC.AudioInputSampleRate", | 158 UMA_HISTOGRAM_ENUMERATION("WebRTC.AudioInputSampleRate", |
| 156 sample_rate, media::kUnexpectedAudioSampleRate); | 159 sample_rate, media::kUnexpectedAudioSampleRate); |
| 157 | 160 |
| 158 // Verify that the reported input hardware sample rate is supported | 161 // Verify that the reported input hardware sample rate is supported |
| 159 // on the current platform. | 162 // on the current platform. |
| 160 if (std::find(&kValidInputRates[0], | 163 if (std::find(&kValidInputRates[0], |
| 161 &kValidInputRates[0] + arraysize(kValidInputRates), | 164 &kValidInputRates[0] + arraysize(kValidInputRates), |
| 162 sample_rate) == | 165 sample_rate) == |
| 163 &kValidInputRates[arraysize(kValidInputRates)]) { | 166 &kValidInputRates[arraysize(kValidInputRates)]) { |
| 164 DLOG(ERROR) << sample_rate << " is not a supported input rate."; | 167 DLOG(ERROR) << sample_rate << " is not a supported input rate."; |
| 165 return false; | 168 return false; |
| 166 } | 169 } |
| 167 | 170 |
| 168 if (!Reconfigure(sample_rate, channel_layout)) | 171 if (!Reconfigure(sample_rate, channel_layout)) |
| 169 return false; | 172 return false; |
| 170 | 173 |
| 171 // Create and configure the default audio capturing source. The |source_| | 174 // Create and configure the default audio capturing source. The |source_| |
| 172 // will be overwritten if an external client later calls SetCapturerSource() | 175 // will be overwritten if an external client later calls SetCapturerSource() |
| 173 // providing an alternaive media::AudioCapturerSource. | 176 // providing an alternative media::AudioCapturerSource. |
| 174 SetCapturerSource(AudioDeviceFactory::NewInputDevice(), | 177 SetCapturerSource(AudioDeviceFactory::NewInputDevice(), |
| 175 channel_layout, | 178 channel_layout, |
| 176 static_cast<float>(sample_rate)); | 179 static_cast<float>(sample_rate)); |
| 177 | 180 |
| 178 return true; | 181 return true; |
| 179 } | 182 } |
| 180 | 183 |
| 181 WebRtcAudioCapturer::WebRtcAudioCapturer() | 184 WebRtcAudioCapturer::WebRtcAudioCapturer() |
| 182 : main_loop_(base::MessageLoopProxy::current()), | 185 : source_(NULL), |
| 183 source_(NULL), | |
| 184 running_(false), | 186 running_(false), |
| 185 agc_is_enabled_(false) { | 187 agc_is_enabled_(false), |
| 188 session_id_(0) { | |
| 186 DVLOG(1) << "WebRtcAudioCapturer::WebRtcAudioCapturer()"; | 189 DVLOG(1) << "WebRtcAudioCapturer::WebRtcAudioCapturer()"; |
| 187 } | 190 } |
| 188 | 191 |
| 189 WebRtcAudioCapturer::~WebRtcAudioCapturer() { | 192 WebRtcAudioCapturer::~WebRtcAudioCapturer() { |
| 190 DCHECK(thread_checker_.CalledOnValidThread()); | 193 DCHECK(thread_checker_.CalledOnValidThread()); |
| 191 DCHECK(sinks_.empty()); | 194 DCHECK(sinks_.empty()); |
| 192 DVLOG(1) << "WebRtcAudioCapturer::~WebRtcAudioCapturer()"; | 195 DVLOG(1) << "WebRtcAudioCapturer::~WebRtcAudioCapturer()"; |
| 193 } | 196 } |
| 194 | 197 |
| 195 void WebRtcAudioCapturer::AddCapturerSink(WebRtcAudioCapturerSink* sink) { | 198 void WebRtcAudioCapturer::AddCapturerSink(WebRtcAudioCapturerSink* sink) { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 210 break; | 213 break; |
| 211 } | 214 } |
| 212 } | 215 } |
| 213 } | 216 } |
| 214 | 217 |
| 215 void WebRtcAudioCapturer::SetCapturerSource( | 218 void WebRtcAudioCapturer::SetCapturerSource( |
| 216 const scoped_refptr<media::AudioCapturerSource>& source, | 219 const scoped_refptr<media::AudioCapturerSource>& source, |
| 217 media::ChannelLayout channel_layout, | 220 media::ChannelLayout channel_layout, |
| 218 float sample_rate) { | 221 float sample_rate) { |
| 219 DCHECK(thread_checker_.CalledOnValidThread()); | 222 DCHECK(thread_checker_.CalledOnValidThread()); |
| 223 DCHECK_GT(session_id_, 0); | |
|
palmer
2013/03/14 21:05:14
Perhaps this should be a run-time check.
no longer working on chromium
2013/03/15 14:52:11
sgtm, making it a CHECK
| |
| 220 DVLOG(1) << "SetCapturerSource(channel_layout=" << channel_layout << "," | 224 DVLOG(1) << "SetCapturerSource(channel_layout=" << channel_layout << "," |
| 221 << "sample_rate=" << sample_rate << ")"; | 225 << "sample_rate=" << sample_rate << ")"; |
| 222 scoped_refptr<media::AudioCapturerSource> old_source; | 226 scoped_refptr<media::AudioCapturerSource> old_source; |
| 223 scoped_refptr<ConfiguredBuffer> current_buffer; | 227 scoped_refptr<ConfiguredBuffer> current_buffer; |
| 224 { | 228 { |
| 225 base::AutoLock auto_lock(lock_); | 229 base::AutoLock auto_lock(lock_); |
| 226 if (source_ == source) | 230 if (source_ == source) |
| 227 return; | 231 return; |
| 228 | 232 |
| 229 source_.swap(old_source); | 233 source_.swap(old_source); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 249 return; | 253 return; |
| 250 } else { | 254 } else { |
| 251 // The buffer has been reconfigured. Update |current_buffer|. | 255 // The buffer has been reconfigured. Update |current_buffer|. |
| 252 base::AutoLock auto_lock(lock_); | 256 base::AutoLock auto_lock(lock_); |
| 253 current_buffer = buffer_; | 257 current_buffer = buffer_; |
| 254 } | 258 } |
| 255 } | 259 } |
| 256 | 260 |
| 257 if (source) { | 261 if (source) { |
| 258 // Make sure to grab the new parameters in case they were reconfigured. | 262 // Make sure to grab the new parameters in case they were reconfigured. |
| 259 source->Initialize(current_buffer->params(), this, this); | 263 source->Initialize(current_buffer->params(), this, session_id_); |
| 260 } | 264 } |
| 261 } | 265 } |
| 262 | 266 |
| 263 void WebRtcAudioCapturer::Start() { | 267 void WebRtcAudioCapturer::Start() { |
| 264 DVLOG(1) << "WebRtcAudioCapturer::Start()"; | 268 DVLOG(1) << "WebRtcAudioCapturer::Start()"; |
| 265 base::AutoLock auto_lock(lock_); | 269 base::AutoLock auto_lock(lock_); |
| 266 if (running_) | 270 if (running_) |
| 267 return; | 271 return; |
| 268 | 272 |
| 269 // Start the data source, i.e., start capturing data from the current source. | 273 // Start the data source, i.e., start capturing data from the current source. |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 298 source->Stop(); | 302 source->Stop(); |
| 299 } | 303 } |
| 300 | 304 |
| 301 void WebRtcAudioCapturer::SetVolume(double volume) { | 305 void WebRtcAudioCapturer::SetVolume(double volume) { |
| 302 DVLOG(1) << "WebRtcAudioCapturer::SetVolume()"; | 306 DVLOG(1) << "WebRtcAudioCapturer::SetVolume()"; |
| 303 base::AutoLock auto_lock(lock_); | 307 base::AutoLock auto_lock(lock_); |
| 304 if (source_) | 308 if (source_) |
| 305 source_->SetVolume(volume); | 309 source_->SetVolume(volume); |
| 306 } | 310 } |
| 307 | 311 |
| 308 void WebRtcAudioCapturer::SetDevice(int session_id) { | |
| 309 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 310 DVLOG(1) << "WebRtcAudioCapturer::SetDevice(" << session_id << ")"; | |
| 311 base::AutoLock auto_lock(lock_); | |
| 312 if (source_) | |
| 313 source_->SetDevice(session_id); | |
| 314 } | |
| 315 | |
| 316 void WebRtcAudioCapturer::SetAutomaticGainControl(bool enable) { | 312 void WebRtcAudioCapturer::SetAutomaticGainControl(bool enable) { |
| 317 base::AutoLock auto_lock(lock_); | 313 base::AutoLock auto_lock(lock_); |
| 318 // Store the setting since SetAutomaticGainControl() can be called before | 314 // Store the setting since SetAutomaticGainControl() can be called before |
| 319 // Initialize(), in this case stored setting will be applied in Start(). | 315 // Initialize(), in this case stored setting will be applied in Start(). |
| 320 agc_is_enabled_ = enable; | 316 agc_is_enabled_ = enable; |
| 321 | 317 |
| 322 if (source_) | 318 if (source_) |
| 323 source_->SetAutomaticGainControl(enable); | 319 source_->SetAutomaticGainControl(enable); |
| 324 } | 320 } |
| 325 | 321 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 358 (*it)->CaptureData(buffer_ref_while_calling->buffer(), | 354 (*it)->CaptureData(buffer_ref_while_calling->buffer(), |
| 359 audio_source->channels(), audio_source->frames(), | 355 audio_source->channels(), audio_source->frames(), |
| 360 audio_delay_milliseconds, volume); | 356 audio_delay_milliseconds, volume); |
| 361 } | 357 } |
| 362 } | 358 } |
| 363 | 359 |
| 364 void WebRtcAudioCapturer::OnCaptureError() { | 360 void WebRtcAudioCapturer::OnCaptureError() { |
| 365 NOTIMPLEMENTED(); | 361 NOTIMPLEMENTED(); |
| 366 } | 362 } |
| 367 | 363 |
| 368 void WebRtcAudioCapturer::OnDeviceStarted(const std::string& device_id) { | |
| 369 device_id_ = device_id; | |
| 370 } | |
| 371 | |
| 372 void WebRtcAudioCapturer::OnDeviceStopped() { | |
| 373 DCHECK_EQ(MessageLoop::current(), ChildProcess::current()->io_message_loop()); | |
| 374 main_loop_->PostTask( | |
| 375 FROM_HERE, base::Bind(&WebRtcAudioCapturer::DoOnDeviceStopped, this)); | |
| 376 } | |
| 377 | |
| 378 void WebRtcAudioCapturer::DoOnDeviceStopped() { | |
| 379 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 380 DVLOG(1) << "WebRtcAudioCapturer::DoOnDeviceStopped()"; | |
| 381 { | |
| 382 base::AutoLock auto_lock(lock_); | |
| 383 running_ = false; | |
| 384 } | |
| 385 | |
| 386 SinkList sinks; | |
| 387 { | |
| 388 base::AutoLock auto_lock(lock_); | |
| 389 sinks = sinks_; | |
| 390 } | |
| 391 | |
| 392 // Inform registered sinks about the stopped device so they can take | |
| 393 // appropriate actions. | |
| 394 for (SinkList::const_iterator it = sinks.begin(); it != sinks.end(); ++it) | |
| 395 (*it)->OnCaptureDeviceStopped(); | |
| 396 } | |
| 397 | |
| 398 media::AudioParameters WebRtcAudioCapturer::audio_parameters() const { | 364 media::AudioParameters WebRtcAudioCapturer::audio_parameters() const { |
| 399 base::AutoLock auto_lock(lock_); | 365 base::AutoLock auto_lock(lock_); |
| 400 return buffer_->params(); | 366 return buffer_->params(); |
| 401 } | 367 } |
| 402 | 368 |
| 403 } // namespace content | 369 } // namespace content |
| OLD | NEW |