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 |