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

Side by Side Diff: media/audio/audio_output_controller.cc

Issue 1897953003: Unmute Tab Audio For Desktop Share (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Resolving Comments Created 4 years, 7 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 (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/audio/audio_output_controller.h" 5 #include "media/audio/audio_output_controller.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <limits> 9 #include <limits>
10 10
(...skipping 30 matching lines...) Expand all
41 TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMillis)), 41 TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMillis)),
42 on_more_io_data_called_(0), 42 on_more_io_data_called_(0),
43 ignore_errors_during_stop_close_(false) { 43 ignore_errors_during_stop_close_(false) {
44 DCHECK(audio_manager); 44 DCHECK(audio_manager);
45 DCHECK(handler_); 45 DCHECK(handler_);
46 DCHECK(sync_reader_); 46 DCHECK(sync_reader_);
47 DCHECK(message_loop_.get()); 47 DCHECK(message_loop_.get());
48 } 48 }
49 49
50 AudioOutputController::~AudioOutputController() { 50 AudioOutputController::~AudioOutputController() {
51 DCHECK_EQ(kClosed, state_); 51 DCHECK_EQ(kClosed, state_);
miu 2016/05/28 02:45:00 For safety, consider adding: DCHECK(duplication_ta
qiangchen 2016/05/31 21:17:33 Done.
52 } 52 }
53 53
54 // static 54 // static
55 scoped_refptr<AudioOutputController> AudioOutputController::Create( 55 scoped_refptr<AudioOutputController> AudioOutputController::Create(
56 AudioManager* audio_manager, 56 AudioManager* audio_manager,
57 EventHandler* event_handler, 57 EventHandler* event_handler,
58 const AudioParameters& params, 58 const AudioParameters& params,
59 const std::string& output_device_id, 59 const std::string& output_device_id,
60 SyncReader* sync_reader) { 60 SyncReader* sync_reader) {
61 DCHECK(audio_manager); 61 DCHECK(audio_manager);
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 // thread starts, its safe to compare and then increment. 294 // thread starts, its safe to compare and then increment.
295 if (base::AtomicRefCountIsZero(&on_more_io_data_called_)) 295 if (base::AtomicRefCountIsZero(&on_more_io_data_called_))
296 base::AtomicRefCountInc(&on_more_io_data_called_); 296 base::AtomicRefCountInc(&on_more_io_data_called_);
297 297
298 sync_reader_->Read(dest); 298 sync_reader_->Read(dest);
299 299
300 const int frames = dest->frames(); 300 const int frames = dest->frames();
301 sync_reader_->UpdatePendingBytes( 301 sync_reader_->UpdatePendingBytes(
302 total_bytes_delay + frames * params_.GetBytesPerFrame(), frames_skipped); 302 total_bytes_delay + frames * params_.GetBytesPerFrame(), frames_skipped);
303 303
304 {
305 base::AutoLock lock(duplication_targets_lock_);
306 if (!duplication_targets_.empty()) {
307 const base::TimeTicks reference_time =
308 base::TimeTicks::Now() +
309 base::TimeDelta::FromMicroseconds(base::Time::kMicrosecondsPerSecond *
310 total_bytes_delay /
311 params_.GetBytesPerSecond());
312 for (AudioPushSink* target : duplication_targets_) {
313 target->OnData(*dest, reference_time);
miu 2016/05/28 02:45:00 This is going to have the real-time audio thread e
qiangchen 2016/05/31 21:17:33 Done.
314 }
315 }
316 }
317
304 if (will_monitor_audio_levels()) 318 if (will_monitor_audio_levels())
305 power_monitor_.Scan(*dest, frames); 319 power_monitor_.Scan(*dest, frames);
306 320
307 return frames; 321 return frames;
308 } 322 }
309 323
310 void AudioOutputController::OnError(AudioOutputStream* stream) { 324 void AudioOutputController::OnError(AudioOutputStream* stream) {
311 { 325 {
312 base::AutoLock auto_lock(error_lock_); 326 base::AutoLock auto_lock(error_lock_);
313 if (ignore_errors_during_stop_close_) 327 if (ignore_errors_during_stop_close_)
(...skipping 15 matching lines...) Expand all
329 ignore_errors_during_stop_close_ = true; 343 ignore_errors_during_stop_close_ = true;
330 } 344 }
331 345
332 // De-register from state change callbacks if stream_ was created via 346 // De-register from state change callbacks if stream_ was created via
333 // AudioManager. 347 // AudioManager.
334 if (stream_ != diverting_to_stream_) 348 if (stream_ != diverting_to_stream_)
335 audio_manager_->RemoveOutputDeviceChangeListener(this); 349 audio_manager_->RemoveOutputDeviceChangeListener(this);
336 350
337 StopStream(); 351 StopStream();
338 stream_->Close(); 352 stream_->Close();
353
339 if (stream_ == diverting_to_stream_) 354 if (stream_ == diverting_to_stream_)
340 diverting_to_stream_ = NULL; 355 diverting_to_stream_ = NULL;
341 stream_ = NULL; 356 stream_ = NULL;
342 357
343 // Since the stream is no longer running, no lock is necessary. 358 // Since the stream is no longer running, no lock is necessary.
344 ignore_errors_during_stop_close_ = false; 359 ignore_errors_during_stop_close_ = false;
345 } 360 }
346 361
347 state_ = kEmpty; 362 state_ = kEmpty;
348 } 363 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 message_loop_->PostTask( 400 message_loop_->PostTask(
386 FROM_HERE, 401 FROM_HERE,
387 base::Bind(&AudioOutputController::DoStartDiverting, this, to_stream)); 402 base::Bind(&AudioOutputController::DoStartDiverting, this, to_stream));
388 } 403 }
389 404
390 void AudioOutputController::StopDiverting() { 405 void AudioOutputController::StopDiverting() {
391 message_loop_->PostTask( 406 message_loop_->PostTask(
392 FROM_HERE, base::Bind(&AudioOutputController::DoStopDiverting, this)); 407 FROM_HERE, base::Bind(&AudioOutputController::DoStopDiverting, this));
393 } 408 }
394 409
410 void AudioOutputController::StartDuplicating(AudioPushSink* sink) {
411 message_loop_->PostTask(
412 FROM_HERE,
413 base::Bind(&AudioOutputController::DoStartDuplicating, this, sink));
414 }
415
416 void AudioOutputController::StopDuplicating(AudioPushSink* sink) {
417 message_loop_->PostTask(
418 FROM_HERE,
419 base::Bind(&AudioOutputController::DoStopDuplicating, this, sink));
420 }
421
395 void AudioOutputController::DoStartDiverting(AudioOutputStream* to_stream) { 422 void AudioOutputController::DoStartDiverting(AudioOutputStream* to_stream) {
396 DCHECK(message_loop_->BelongsToCurrentThread()); 423 DCHECK(message_loop_->BelongsToCurrentThread());
397 424
398 if (state_ == kClosed) 425 if (state_ == kClosed)
399 return; 426 return;
400 427
401 DCHECK(!diverting_to_stream_); 428 DCHECK(!diverting_to_stream_);
402 diverting_to_stream_ = to_stream; 429 diverting_to_stream_ = to_stream;
403 // Note: OnDeviceChange() will engage the "re-create" process, which will 430 // Note: OnDeviceChange() will engage the "re-create" process, which will
404 // detect and use the alternate AudioOutputStream rather than create a new one 431 // detect and use the alternate AudioOutputStream rather than create a new one
405 // via AudioManager. 432 // via AudioManager.
406 OnDeviceChange(); 433 OnDeviceChange();
407 } 434 }
408 435
409 void AudioOutputController::DoStopDiverting() { 436 void AudioOutputController::DoStopDiverting() {
410 DCHECK(message_loop_->BelongsToCurrentThread()); 437 DCHECK(message_loop_->BelongsToCurrentThread());
411 438
412 if (state_ == kClosed) 439 if (state_ == kClosed)
413 return; 440 return;
414 441
415 // Note: OnDeviceChange() will cause the existing stream (the consumer of the 442 // Note: OnDeviceChange() will cause the existing stream (the consumer of the
416 // diverted audio data) to be closed, and diverting_to_stream_ will be set 443 // diverted audio data) to be closed, and diverting_to_stream_ will be set
417 // back to NULL. 444 // back to NULL.
418 OnDeviceChange(); 445 OnDeviceChange();
419 DCHECK(!diverting_to_stream_); 446 DCHECK(!diverting_to_stream_);
420 } 447 }
421 448
449 void AudioOutputController::DoStartDuplicating(AudioPushSink* to_stream) {
450 DCHECK(message_loop_->BelongsToCurrentThread());
451 if (state_ == kClosed)
452 return;
453
454 base::AutoLock lock(duplication_targets_lock_);
455
456 // Already serving the stream.
457 if (duplication_targets_.find(to_stream) != duplication_targets_.end())
miu 2016/05/28 02:45:00 This isn't necessary since you're inserting into a
qiangchen 2016/05/31 21:17:33 Done.
458 return;
459
460 duplication_targets_.insert(to_stream);
461 }
462
463 void AudioOutputController::DoStopDuplicating(AudioPushSink* to_stream) {
464 DCHECK(message_loop_->BelongsToCurrentThread());
465 to_stream->Close();
466 if (state_ == kClosed)
miu 2016/05/28 02:45:00 I'd suggest omitting this early return when state_
qiangchen 2016/05/31 21:17:33 Done.
467 return;
468
469 base::AutoLock lock(duplication_targets_lock_);
470 duplication_targets_.erase(to_stream);
471 }
472
422 std::pair<float, bool> AudioOutputController::ReadCurrentPowerAndClip() { 473 std::pair<float, bool> AudioOutputController::ReadCurrentPowerAndClip() {
423 DCHECK(will_monitor_audio_levels()); 474 DCHECK(will_monitor_audio_levels());
424 return power_monitor_.ReadCurrentPowerAndClip(); 475 return power_monitor_.ReadCurrentPowerAndClip();
425 } 476 }
426 477
427 void AudioOutputController::WedgeCheck() { 478 void AudioOutputController::WedgeCheck() {
428 DCHECK(message_loop_->BelongsToCurrentThread()); 479 DCHECK(message_loop_->BelongsToCurrentThread());
429 480
430 // If we should be playing and we haven't, that's a wedge. 481 // If we should be playing and we haven't, that's a wedge.
431 if (state_ == kPlaying) { 482 if (state_ == kPlaying) {
432 UMA_HISTOGRAM_BOOLEAN("Media.AudioOutputControllerPlaybackStartupSuccess", 483 UMA_HISTOGRAM_BOOLEAN("Media.AudioOutputControllerPlaybackStartupSuccess",
433 base::AtomicRefCountIsOne(&on_more_io_data_called_)); 484 base::AtomicRefCountIsOne(&on_more_io_data_called_));
434 } 485 }
435 } 486 }
436 487
437 } // namespace media 488 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698