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

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

Issue 1721273002: MediaStream audio object graph untangling and clean-ups. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 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"
(...skipping 152 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()->GetInputFormat().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 WebRtcAudioCapturer 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 = capturers_.back()->GetInputFormat();
387 *sample_rate = static_cast<uint32_t>( 377 *sample_rate = static_cast<uint32_t>(params.sample_rate());
388 capturer->source_audio_parameters().sample_rate());
389 return 0; 378 return 0;
390 } 379 }
391 380
392 int32_t WebRtcAudioDeviceImpl::PlayoutSampleRate( 381 int32_t WebRtcAudioDeviceImpl::PlayoutSampleRate(
393 uint32_t* sample_rate) const { 382 uint32_t* sample_rate) const {
394 DCHECK(signaling_thread_checker_.CalledOnValidThread()); 383 DCHECK(signaling_thread_checker_.CalledOnValidThread());
395 *sample_rate = renderer_.get() ? renderer_->sample_rate() : 0; 384 *sample_rate = renderer_.get() ? renderer_->sample_rate() : 0;
396 return 0; 385 return 0;
397 } 386 }
398 387
(...skipping 27 matching lines...) Expand all
426 audio_renderer_thread_checker_.DetachFromThread(); 415 audio_renderer_thread_checker_.DetachFromThread();
427 416
428 // We acquire |lock_| again and assert our precondition, since we are 417 // We acquire |lock_| again and assert our precondition, since we are
429 // accessing the internal state again. 418 // accessing the internal state again.
430 base::AutoLock auto_lock(lock_); 419 base::AutoLock auto_lock(lock_);
431 DCHECK(!renderer_.get()); 420 DCHECK(!renderer_.get());
432 renderer_ = renderer; 421 renderer_ = renderer;
433 return true; 422 return true;
434 } 423 }
435 424
436 void WebRtcAudioDeviceImpl::AddAudioCapturer( 425 void WebRtcAudioDeviceImpl::AddAudioCapturer(WebRtcAudioCapturer* capturer) {
437 const scoped_refptr<WebRtcAudioCapturer>& capturer) {
438 DCHECK(main_thread_checker_.CalledOnValidThread()); 426 DCHECK(main_thread_checker_.CalledOnValidThread());
439 DVLOG(1) << "WebRtcAudioDeviceImpl::AddAudioCapturer()"; 427 DVLOG(1) << "WebRtcAudioDeviceImpl::AddAudioCapturer()";
440 DCHECK(capturer.get()); 428 DCHECK(capturer);
441 DCHECK(!capturer->device_id().empty()); 429 DCHECK(!capturer->device_info().device.id.empty());
442 430
443 base::AutoLock auto_lock(lock_); 431 base::AutoLock auto_lock(lock_);
444 DCHECK(std::find(capturers_.begin(), capturers_.end(), capturer) == 432 DCHECK(std::find(capturers_.begin(), capturers_.end(), capturer) ==
445 capturers_.end()); 433 capturers_.end());
446 capturers_.push_back(capturer); 434 capturers_.push_back(capturer);
447 } 435 }
448 436
449 void WebRtcAudioDeviceImpl::RemoveAudioCapturer( 437 void WebRtcAudioDeviceImpl::RemoveAudioCapturer(WebRtcAudioCapturer* capturer) {
450 const scoped_refptr<WebRtcAudioCapturer>& capturer) {
451 DCHECK(main_thread_checker_.CalledOnValidThread()); 438 DCHECK(main_thread_checker_.CalledOnValidThread());
452 DVLOG(1) << "WebRtcAudioDeviceImpl::AddAudioCapturer()"; 439 DVLOG(1) << "WebRtcAudioDeviceImpl::RemoveAudioCapturer()";
453 DCHECK(capturer.get()); 440 DCHECK(capturer);
454 base::AutoLock auto_lock(lock_); 441 base::AutoLock auto_lock(lock_);
455 capturers_.remove(capturer); 442 capturers_.remove(capturer);
456 } 443 }
457 444
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( 445 void WebRtcAudioDeviceImpl::AddPlayoutSink(
473 WebRtcPlayoutDataSource::Sink* sink) { 446 WebRtcPlayoutDataSource::Sink* sink) {
474 DCHECK(main_thread_checker_.CalledOnValidThread()); 447 DCHECK(main_thread_checker_.CalledOnValidThread());
475 DCHECK(sink); 448 DCHECK(sink);
476 base::AutoLock auto_lock(lock_); 449 base::AutoLock auto_lock(lock_);
477 DCHECK(std::find(playout_sinks_.begin(), playout_sinks_.end(), sink) == 450 DCHECK(std::find(playout_sinks_.begin(), playout_sinks_.end(), sink) ==
478 playout_sinks_.end()); 451 playout_sinks_.end());
479 playout_sinks_.push_back(sink); 452 playout_sinks_.push_back(sink);
480 } 453 }
481 454
482 void WebRtcAudioDeviceImpl::RemovePlayoutSink( 455 void WebRtcAudioDeviceImpl::RemovePlayoutSink(
483 WebRtcPlayoutDataSource::Sink* sink) { 456 WebRtcPlayoutDataSource::Sink* sink) {
484 DCHECK(main_thread_checker_.CalledOnValidThread()); 457 DCHECK(main_thread_checker_.CalledOnValidThread());
485 DCHECK(sink); 458 DCHECK(sink);
486 base::AutoLock auto_lock(lock_); 459 base::AutoLock auto_lock(lock_);
487 playout_sinks_.remove(sink); 460 playout_sinks_.remove(sink);
488 } 461 }
489 462
490 bool WebRtcAudioDeviceImpl::GetAuthorizedDeviceInfoForAudioRenderer( 463 bool WebRtcAudioDeviceImpl::GetAuthorizedDeviceInfoForAudioRenderer(
491 int* session_id, 464 int* session_id,
492 int* output_sample_rate, 465 int* output_sample_rate,
493 int* output_frames_per_buffer) { 466 int* output_frames_per_buffer) {
494 DCHECK(main_thread_checker_.CalledOnValidThread()); 467 DCHECK(main_thread_checker_.CalledOnValidThread());
495 base::AutoLock lock(lock_); 468 base::AutoLock lock(lock_);
496 // If there is no capturer or there are more than one open capture devices, 469 // If there is no capturer or there are more than one open capture devices,
497 // return false. 470 // return false.
498 if (capturers_.size() != 1) 471 if (capturers_.size() != 1)
499 return false; 472 return false;
500 473
501 return capturers_.back()->GetPairedOutputParameters( 474 // Don't set output parameters unless all of them are valid.
502 session_id, output_sample_rate, output_frames_per_buffer); 475 const StreamDeviceInfo& device_info = capturers_.back()->device_info();
476 if (device_info.session_id <= 0 ||
477 !device_info.device.matched_output.sample_rate ||
478 !device_info.device.matched_output.frames_per_buffer)
479 return false;
480
481 *session_id = device_info.session_id;
482 *output_sample_rate = device_info.device.matched_output.sample_rate;
483 *output_frames_per_buffer =
484 device_info.device.matched_output.frames_per_buffer;
485
486 return true;
503 } 487 }
504 488
505 } // namespace content 489 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698