Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(524)

Side by Side Diff: content/renderer/media/webrtc_audio_device_impl.cc

Issue 1647773002: MediaStream audio sourcing: Bypass audio processing for non-WebRTC cases. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: NOT FOR REVIEW -- This will be broken-up across multiple CLs. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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_device_impl.h" 5 #include "content/renderer/media/webrtc_audio_device_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "base/strings/string_util.h" 9 #include "base/strings/string_util.h"
10 #include "base/win/windows_version.h" 10 #include "base/win/windows_version.h"
11 #include "content/renderer/media/media_stream_audio_processor.h" 11 #include "content/renderer/media/media_stream_audio_processor.h"
12 #include "content/renderer/media/webrtc_audio_capturer.h" 12 #include "content/renderer/media/webrtc/processed_local_audio_source.h"
13 #include "content/renderer/media/webrtc_audio_renderer.h" 13 #include "content/renderer/media/webrtc_audio_renderer.h"
14 #include "content/renderer/render_thread_impl.h" 14 #include "content/renderer/render_thread_impl.h"
15 #include "media/audio/audio_parameters.h" 15 #include "media/audio/audio_parameters.h"
16 #include "media/audio/sample_rates.h" 16 #include "media/audio/sample_rates.h"
17 17
18 using media::AudioParameters; 18 using media::AudioParameters;
19 using media::ChannelLayout; 19 using media::ChannelLayout;
20 20
21 namespace content { 21 namespace content {
22 22
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 // Calling Terminate() multiple times in a row is OK. 163 // Calling Terminate() multiple times in a row is OK.
164 if (!initialized_) 164 if (!initialized_)
165 return 0; 165 return 0;
166 166
167 StopRecording(); 167 StopRecording();
168 StopPlayout(); 168 StopPlayout();
169 169
170 DCHECK(!renderer_.get() || !renderer_->IsStarted()) 170 DCHECK(!renderer_.get() || !renderer_->IsStarted())
171 << "The shared audio renderer shouldn't be running"; 171 << "The shared audio renderer shouldn't be running";
172 172
173 // Stop all the capturers to ensure no further OnData() and 173 {
174 // RemoveAudioCapturer() callback. 174 base::AutoLock auto_lock(lock_);
175 // Cache the capturers in a local list since WebRtcAudioCapturer::Stop() 175 capturers_.clear();
176 // will trigger RemoveAudioCapturer() callback.
177 CapturerList capturers;
178 capturers.swap(capturers_);
179 for (CapturerList::const_iterator iter = capturers.begin();
180 iter != capturers.end(); ++iter) {
181 (*iter)->Stop();
182 } 176 }
183 177
184 initialized_ = false; 178 initialized_ = false;
185 return 0; 179 return 0;
186 } 180 }
187 181
188 bool WebRtcAudioDeviceImpl::Initialized() const { 182 bool WebRtcAudioDeviceImpl::Initialized() const {
189 DCHECK(signaling_thread_checker_.CalledOnValidThread()); 183 DCHECK(signaling_thread_checker_.CalledOnValidThread());
190 return initialized_; 184 return initialized_;
191 } 185 }
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 return recording_; 281 return recording_;
288 } 282 }
289 283
290 int32_t WebRtcAudioDeviceImpl::SetMicrophoneVolume(uint32_t volume) { 284 int32_t WebRtcAudioDeviceImpl::SetMicrophoneVolume(uint32_t volume) {
291 DVLOG(1) << "WebRtcAudioDeviceImpl::SetMicrophoneVolume(" << volume << ")"; 285 DVLOG(1) << "WebRtcAudioDeviceImpl::SetMicrophoneVolume(" << volume << ")";
292 DCHECK(signaling_thread_checker_.CalledOnValidThread()); 286 DCHECK(signaling_thread_checker_.CalledOnValidThread());
293 DCHECK(initialized_); 287 DCHECK(initialized_);
294 288
295 // Only one microphone is supported at the moment, which is represented by 289 // Only one microphone is supported at the moment, which is represented by
296 // the default capturer. 290 // the default capturer.
297 scoped_refptr<WebRtcAudioCapturer> capturer(GetDefaultCapturer()); 291 base::AutoLock auto_lock(lock_);
298 if (!capturer.get()) 292 if (capturers_.empty())
299 return -1; 293 return -1;
300 294 capturers_.back()->SetVolume(volume);
301 capturer->SetVolume(volume);
302 return 0; 295 return 0;
303 } 296 }
304 297
305 // TODO(henrika): sort out calling thread once we start using this API. 298 // TODO(henrika): sort out calling thread once we start using this API.
306 int32_t WebRtcAudioDeviceImpl::MicrophoneVolume(uint32_t* volume) const { 299 int32_t WebRtcAudioDeviceImpl::MicrophoneVolume(uint32_t* volume) const {
307 DVLOG(1) << "WebRtcAudioDeviceImpl::MicrophoneVolume()"; 300 DVLOG(1) << "WebRtcAudioDeviceImpl::MicrophoneVolume()";
308 DCHECK(signaling_thread_checker_.CalledOnValidThread()); 301 DCHECK(signaling_thread_checker_.CalledOnValidThread());
309 // We only support one microphone now, which is accessed via the default 302 // We only support one microphone now, which is accessed via the default
310 // capturer. 303 // capturer.
311 DCHECK(initialized_); 304 DCHECK(initialized_);
312 scoped_refptr<WebRtcAudioCapturer> capturer(GetDefaultCapturer()); 305 base::AutoLock auto_lock(lock_);
313 if (!capturer.get()) 306 if (capturers_.empty())
314 return -1; 307 return -1;
315 308 *volume = static_cast<uint32_t>(capturers_.back()->Volume());
316 *volume = static_cast<uint32_t>(capturer->Volume());
317
318 return 0; 309 return 0;
319 } 310 }
320 311
321 int32_t WebRtcAudioDeviceImpl::MaxMicrophoneVolume(uint32_t* max_volume) const { 312 int32_t WebRtcAudioDeviceImpl::MaxMicrophoneVolume(uint32_t* max_volume) const {
322 DCHECK(initialized_); 313 DCHECK(initialized_);
323 DCHECK(signaling_thread_checker_.CalledOnValidThread()); 314 DCHECK(signaling_thread_checker_.CalledOnValidThread());
324 *max_volume = kMaxVolumeLevel; 315 *max_volume = kMaxVolumeLevel;
325 return 0; 316 return 0;
326 } 317 }
327 318
(...skipping 17 matching lines...) Expand all
345 int32_t WebRtcAudioDeviceImpl::StereoRecordingIsAvailable( 336 int32_t WebRtcAudioDeviceImpl::StereoRecordingIsAvailable(
346 bool* available) const { 337 bool* available) const {
347 DCHECK(initialized_); 338 DCHECK(initialized_);
348 // This method is called during initialization on the signaling thread and 339 // This method is called during initialization on the signaling thread and
349 // then later on the worker thread. Due to this we cannot DCHECK on what 340 // then later on the worker thread. Due to this we cannot DCHECK on what
350 // thread we're on since it might incorrectly initialize the 341 // thread we're on since it might incorrectly initialize the
351 // worker_thread_checker_. 342 // worker_thread_checker_.
352 343
353 // TODO(xians): These kind of hardware methods do not make much sense since we 344 // TODO(xians): These kind of hardware methods do not make much sense since we
354 // support multiple sources. Remove or figure out new APIs for such methods. 345 // support multiple sources. Remove or figure out new APIs for such methods.
355 scoped_refptr<WebRtcAudioCapturer> capturer(GetDefaultCapturer()); 346 base::AutoLock auto_lock(lock_);
356 if (!capturer.get()) 347 if (capturers_.empty())
357 return -1; 348 return -1;
358 349 *available = (capturers_.back()->GetInputAudioParameters().channels() == 2);
359 *available = (capturer->source_audio_parameters().channels() == 2);
360 return 0; 350 return 0;
361 } 351 }
362 352
363 int32_t WebRtcAudioDeviceImpl::PlayoutDelay(uint16_t* delay_ms) const { 353 int32_t WebRtcAudioDeviceImpl::PlayoutDelay(uint16_t* delay_ms) const {
364 DCHECK(worker_thread_checker_.CalledOnValidThread()); 354 DCHECK(worker_thread_checker_.CalledOnValidThread());
365 base::AutoLock auto_lock(lock_); 355 base::AutoLock auto_lock(lock_);
366 *delay_ms = static_cast<uint16_t>(output_delay_ms_); 356 *delay_ms = static_cast<uint16_t>(output_delay_ms_);
367 return 0; 357 return 0;
368 } 358 }
369 359
370 int32_t WebRtcAudioDeviceImpl::RecordingDelay(uint16_t* delay_ms) const { 360 int32_t WebRtcAudioDeviceImpl::RecordingDelay(uint16_t* delay_ms) const {
371 DCHECK(signaling_thread_checker_.CalledOnValidThread()); 361 DCHECK(signaling_thread_checker_.CalledOnValidThread());
372 362
373 // There is no way to report a correct delay value to WebRTC since there 363 // There is no way to report a correct delay value to WebRTC since there
374 // might be multiple WebRtcAudioCapturer instances. 364 // might be multiple ProcessedLocalAudioSource instances.
375 NOTREACHED(); 365 NOTREACHED();
376 return -1; 366 return -1;
377 } 367 }
378 368
379 int32_t WebRtcAudioDeviceImpl::RecordingSampleRate( 369 int32_t WebRtcAudioDeviceImpl::RecordingSampleRate(
380 uint32_t* sample_rate) const { 370 uint32_t* sample_rate) const {
381 DCHECK(signaling_thread_checker_.CalledOnValidThread()); 371 DCHECK(signaling_thread_checker_.CalledOnValidThread());
382 // We use the default capturer as the recording sample rate. 372 // We use the default capturer as the recording sample rate.
383 scoped_refptr<WebRtcAudioCapturer> capturer(GetDefaultCapturer()); 373 base::AutoLock auto_lock(lock_);
384 if (!capturer.get()) 374 if (capturers_.empty())
385 return -1; 375 return -1;
386 376 const media::AudioParameters& params =
387 *sample_rate = static_cast<uint32_t>( 377 capturers_.back()->GetInputAudioParameters();
388 capturer->source_audio_parameters().sample_rate()); 378 if (!params.IsValid())
379 return -1;
380 *sample_rate = static_cast<uint32_t>(params.sample_rate());
389 return 0; 381 return 0;
390 } 382 }
391 383
392 int32_t WebRtcAudioDeviceImpl::PlayoutSampleRate( 384 int32_t WebRtcAudioDeviceImpl::PlayoutSampleRate(
393 uint32_t* sample_rate) const { 385 uint32_t* sample_rate) const {
394 DCHECK(signaling_thread_checker_.CalledOnValidThread()); 386 DCHECK(signaling_thread_checker_.CalledOnValidThread());
395 *sample_rate = renderer_.get() ? renderer_->sample_rate() : 0; 387 *sample_rate = renderer_.get() ? renderer_->sample_rate() : 0;
396 return 0; 388 return 0;
397 } 389 }
398 390
(...skipping 28 matching lines...) Expand all
427 419
428 // We acquire |lock_| again and assert our precondition, since we are 420 // We acquire |lock_| again and assert our precondition, since we are
429 // accessing the internal state again. 421 // accessing the internal state again.
430 base::AutoLock auto_lock(lock_); 422 base::AutoLock auto_lock(lock_);
431 DCHECK(!renderer_.get()); 423 DCHECK(!renderer_.get());
432 renderer_ = renderer; 424 renderer_ = renderer;
433 return true; 425 return true;
434 } 426 }
435 427
436 void WebRtcAudioDeviceImpl::AddAudioCapturer( 428 void WebRtcAudioDeviceImpl::AddAudioCapturer(
437 const scoped_refptr<WebRtcAudioCapturer>& capturer) { 429 ProcessedLocalAudioSource* capturer) {
438 DCHECK(main_thread_checker_.CalledOnValidThread()); 430 DCHECK(main_thread_checker_.CalledOnValidThread());
439 DVLOG(1) << "WebRtcAudioDeviceImpl::AddAudioCapturer()"; 431 DVLOG(1) << "WebRtcAudioDeviceImpl::AddAudioCapturer()";
440 DCHECK(capturer.get()); 432 DCHECK(capturer);
441 DCHECK(!capturer->device_id().empty());
442 433
443 base::AutoLock auto_lock(lock_); 434 base::AutoLock auto_lock(lock_);
444 DCHECK(std::find(capturers_.begin(), capturers_.end(), capturer) == 435 DCHECK(std::find(capturers_.begin(), capturers_.end(), capturer) ==
445 capturers_.end()); 436 capturers_.end());
446 capturers_.push_back(capturer); 437 capturers_.push_back(capturer);
447 } 438 }
448 439
449 void WebRtcAudioDeviceImpl::RemoveAudioCapturer( 440 void WebRtcAudioDeviceImpl::RemoveAudioCapturer(
450 const scoped_refptr<WebRtcAudioCapturer>& capturer) { 441 ProcessedLocalAudioSource* capturer) {
451 DCHECK(main_thread_checker_.CalledOnValidThread()); 442 DCHECK(main_thread_checker_.CalledOnValidThread());
452 DVLOG(1) << "WebRtcAudioDeviceImpl::AddAudioCapturer()"; 443 DVLOG(1) << "WebRtcAudioDeviceImpl::AddAudioCapturer()";
453 DCHECK(capturer.get()); 444 DCHECK(capturer);
454 base::AutoLock auto_lock(lock_); 445 base::AutoLock auto_lock(lock_);
455 capturers_.remove(capturer); 446 capturers_.remove(capturer);
456 } 447 }
457 448
458 scoped_refptr<WebRtcAudioCapturer>
459 WebRtcAudioDeviceImpl::GetDefaultCapturer() const {
460 // Called on the signaling thread (during initialization), worker
461 // thread during capture or main thread for a WebAudio source.
462 // We can't DCHECK on those three checks here since GetDefaultCapturer
463 // may be the first call and therefore could incorrectly initialize the
464 // thread checkers.
465 DCHECK(initialized_);
466 base::AutoLock auto_lock(lock_);
467 // Use the last |capturer| which is from the latest getUserMedia call as
468 // the default capture device.
469 return capturers_.empty() ? NULL : capturers_.back();
470 }
471
472 void WebRtcAudioDeviceImpl::AddPlayoutSink( 449 void WebRtcAudioDeviceImpl::AddPlayoutSink(
473 WebRtcPlayoutDataSource::Sink* sink) { 450 WebRtcPlayoutDataSource::Sink* sink) {
474 DCHECK(main_thread_checker_.CalledOnValidThread()); 451 DCHECK(main_thread_checker_.CalledOnValidThread());
475 DCHECK(sink); 452 DCHECK(sink);
476 base::AutoLock auto_lock(lock_); 453 base::AutoLock auto_lock(lock_);
477 DCHECK(std::find(playout_sinks_.begin(), playout_sinks_.end(), sink) == 454 DCHECK(std::find(playout_sinks_.begin(), playout_sinks_.end(), sink) ==
478 playout_sinks_.end()); 455 playout_sinks_.end());
479 playout_sinks_.push_back(sink); 456 playout_sinks_.push_back(sink);
480 } 457 }
481 458
482 void WebRtcAudioDeviceImpl::RemovePlayoutSink( 459 void WebRtcAudioDeviceImpl::RemovePlayoutSink(
483 WebRtcPlayoutDataSource::Sink* sink) { 460 WebRtcPlayoutDataSource::Sink* sink) {
484 DCHECK(main_thread_checker_.CalledOnValidThread()); 461 DCHECK(main_thread_checker_.CalledOnValidThread());
485 DCHECK(sink); 462 DCHECK(sink);
486 base::AutoLock auto_lock(lock_); 463 base::AutoLock auto_lock(lock_);
487 playout_sinks_.remove(sink); 464 playout_sinks_.remove(sink);
488 } 465 }
489 466
490 bool WebRtcAudioDeviceImpl::GetAuthorizedDeviceInfoForAudioRenderer( 467 bool WebRtcAudioDeviceImpl::GetAuthorizedDeviceInfoForAudioRenderer(
491 int* session_id, 468 int* session_id,
492 int* output_sample_rate, 469 int* output_sample_rate,
493 int* output_frames_per_buffer) { 470 int* output_frames_per_buffer) {
494 DCHECK(main_thread_checker_.CalledOnValidThread()); 471 DCHECK(main_thread_checker_.CalledOnValidThread());
495 base::AutoLock lock(lock_); 472 base::AutoLock lock(lock_);
496 // If there is no capturer or there are more than one open capture devices, 473 // If there is no capturer or there are more than one open capture devices,
497 // return false. 474 // return false.
498 if (capturers_.size() != 1) 475 if (capturers_.size() != 1)
499 return false; 476 return false;
500 477
501 return capturers_.back()->GetPairedOutputParameters( 478 // Don't set output parameters unless all of them are valid.
502 session_id, output_sample_rate, output_frames_per_buffer); 479 const StreamDeviceInfo& device_info = capturers_.back()->device_info();
480 if (device_info.session_id <= 0 ||
481 !device_info.device.matched_output.sample_rate ||
482 !device_info.device.matched_output.frames_per_buffer)
483 return false;
484
485 *session_id = device_info.session_id;
486 *output_sample_rate = device_info.device.matched_output.sample_rate;
487 *output_frames_per_buffer =
488 device_info.device.matched_output.frames_per_buffer;
489
490 return true;
503 } 491 }
504 492
505 } // namespace content 493 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/webrtc_audio_device_impl.h ('k') | content/renderer/media/webrtc_audio_renderer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698