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

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: Unittest 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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 112
113 void AudioOutputController::DoCreate(bool is_for_device_change) { 113 void AudioOutputController::DoCreate(bool is_for_device_change) {
114 DCHECK(message_loop_->BelongsToCurrentThread()); 114 DCHECK(message_loop_->BelongsToCurrentThread());
115 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.CreateTime"); 115 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.CreateTime");
116 TRACE_EVENT0("audio", "AudioOutputController::DoCreate"); 116 TRACE_EVENT0("audio", "AudioOutputController::DoCreate");
117 117
118 // Close() can be called before DoCreate() is executed. 118 // Close() can be called before DoCreate() is executed.
119 if (state_ == kClosed) 119 if (state_ == kClosed)
120 return; 120 return;
121 121
122 DoStopCloseAndClearStream(); // Calls RemoveOutputDeviceChangeListener(). 122 // Calls RemoveOutputDeviceChangeListener().
123 DoStopCloseAndClearStream();
miu 2016/05/06 22:29:50 nit: Comment can go at end-of-line (like it was be
qiangchen 2016/05/10 22:36:53 Done.
123 DCHECK_EQ(kEmpty, state_); 124 DCHECK_EQ(kEmpty, state_);
124 125
125 stream_ = diverting_to_stream_ ? 126 stream_ = diverting_to_stream_ ?
126 diverting_to_stream_ : 127 diverting_to_stream_ :
127 audio_manager_->MakeAudioOutputStreamProxy(params_, output_device_id_); 128 audio_manager_->MakeAudioOutputStreamProxy(params_, output_device_id_);
128 if (!stream_) { 129 if (!stream_) {
129 state_ = kError; 130 state_ = kError;
130 handler_->OnError(); 131 handler_->OnError();
131 return; 132 return;
132 } 133 }
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 // thread starts, its safe to compare and then increment. 295 // thread starts, its safe to compare and then increment.
295 if (base::AtomicRefCountIsZero(&on_more_io_data_called_)) 296 if (base::AtomicRefCountIsZero(&on_more_io_data_called_))
296 base::AtomicRefCountInc(&on_more_io_data_called_); 297 base::AtomicRefCountInc(&on_more_io_data_called_);
297 298
298 sync_reader_->Read(dest); 299 sync_reader_->Read(dest);
299 300
300 const int frames = dest->frames(); 301 const int frames = dest->frames();
301 sync_reader_->UpdatePendingBytes( 302 sync_reader_->UpdatePendingBytes(
302 total_bytes_delay + frames * params_.GetBytesPerFrame(), frames_skipped); 303 total_bytes_delay + frames * params_.GetBytesPerFrame(), frames_skipped);
303 304
305 if (!duplication_targets_.empty()) {
306 const base::TimeTicks reference_time =
307 base::TimeTicks::Now() +
308 base::TimeDelta::FromMicroseconds(base::Time::kMicrosecondsPerSecond *
309 total_bytes_delay /
310 params_.GetBytesPerSecond());
311 for (AudioPushSink* target : duplication_targets_) {
miu 2016/05/06 22:37:06 Oh, I just realized something critical here: This
DaleCurtis 2016/05/09 18:53:25 I'm more worried about what each target may do wit
qiangchen 2016/05/10 22:36:53 Thanks for suggestions. After my investigation, w
312 target->OnData(*dest, reference_time);
313 }
314 }
315
304 if (will_monitor_audio_levels()) 316 if (will_monitor_audio_levels())
305 power_monitor_.Scan(*dest, frames); 317 power_monitor_.Scan(*dest, frames);
306 318
307 return frames; 319 return frames;
308 } 320 }
309 321
310 void AudioOutputController::OnError(AudioOutputStream* stream) { 322 void AudioOutputController::OnError(AudioOutputStream* stream) {
311 { 323 {
312 base::AutoLock auto_lock(error_lock_); 324 base::AutoLock auto_lock(error_lock_);
313 if (ignore_errors_during_stop_close_) 325 if (ignore_errors_during_stop_close_)
(...skipping 15 matching lines...) Expand all
329 ignore_errors_during_stop_close_ = true; 341 ignore_errors_during_stop_close_ = true;
330 } 342 }
331 343
332 // De-register from state change callbacks if stream_ was created via 344 // De-register from state change callbacks if stream_ was created via
333 // AudioManager. 345 // AudioManager.
334 if (stream_ != diverting_to_stream_) 346 if (stream_ != diverting_to_stream_)
335 audio_manager_->RemoveOutputDeviceChangeListener(this); 347 audio_manager_->RemoveOutputDeviceChangeListener(this);
336 348
337 StopStream(); 349 StopStream();
338 stream_->Close(); 350 stream_->Close();
351
339 if (stream_ == diverting_to_stream_) 352 if (stream_ == diverting_to_stream_)
340 diverting_to_stream_ = NULL; 353 diverting_to_stream_ = NULL;
341 stream_ = NULL; 354 stream_ = NULL;
342 355
343 // Since the stream is no longer running, no lock is necessary. 356 // Since the stream is no longer running, no lock is necessary.
344 ignore_errors_during_stop_close_ = false; 357 ignore_errors_during_stop_close_ = false;
345 } 358 }
346 359
347 state_ = kEmpty; 360 state_ = kEmpty;
348 } 361 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 message_loop_->PostTask( 398 message_loop_->PostTask(
386 FROM_HERE, 399 FROM_HERE,
387 base::Bind(&AudioOutputController::DoStartDiverting, this, to_stream)); 400 base::Bind(&AudioOutputController::DoStartDiverting, this, to_stream));
388 } 401 }
389 402
390 void AudioOutputController::StopDiverting() { 403 void AudioOutputController::StopDiverting() {
391 message_loop_->PostTask( 404 message_loop_->PostTask(
392 FROM_HERE, base::Bind(&AudioOutputController::DoStopDiverting, this)); 405 FROM_HERE, base::Bind(&AudioOutputController::DoStopDiverting, this));
393 } 406 }
394 407
408 void AudioOutputController::StartDuplicating(AudioPushSink* sink) {
409 message_loop_->PostTask(
410 FROM_HERE,
411 base::Bind(&AudioOutputController::DoStartDuplicating, this, sink));
412 }
413
414 void AudioOutputController::StopDuplicating(AudioPushSink* sink) {
415 message_loop_->PostTask(
416 FROM_HERE,
417 base::Bind(&AudioOutputController::DoStopDuplicating, this, sink));
418 }
419
395 void AudioOutputController::DoStartDiverting(AudioOutputStream* to_stream) { 420 void AudioOutputController::DoStartDiverting(AudioOutputStream* to_stream) {
396 DCHECK(message_loop_->BelongsToCurrentThread()); 421 DCHECK(message_loop_->BelongsToCurrentThread());
397 422
398 if (state_ == kClosed) 423 if (state_ == kClosed)
399 return; 424 return;
400 425
401 DCHECK(!diverting_to_stream_); 426 DCHECK(!diverting_to_stream_);
402 diverting_to_stream_ = to_stream; 427 diverting_to_stream_ = to_stream;
403 // Note: OnDeviceChange() will engage the "re-create" process, which will 428 // Note: OnDeviceChange() will engage the "re-create" process, which will
404 // detect and use the alternate AudioOutputStream rather than create a new one 429 // detect and use the alternate AudioOutputStream rather than create a new one
405 // via AudioManager. 430 // via AudioManager.
406 OnDeviceChange(); 431 OnDeviceChange();
407 } 432 }
408 433
409 void AudioOutputController::DoStopDiverting() { 434 void AudioOutputController::DoStopDiverting() {
410 DCHECK(message_loop_->BelongsToCurrentThread()); 435 DCHECK(message_loop_->BelongsToCurrentThread());
411 436
412 if (state_ == kClosed) 437 if (state_ == kClosed)
413 return; 438 return;
414 439
415 // Note: OnDeviceChange() will cause the existing stream (the consumer of the 440 // 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 441 // diverted audio data) to be closed, and diverting_to_stream_ will be set
417 // back to NULL. 442 // back to NULL.
418 OnDeviceChange(); 443 OnDeviceChange();
419 DCHECK(!diverting_to_stream_); 444 DCHECK(!diverting_to_stream_);
420 } 445 }
421 446
447 void AudioOutputController::DoStartDuplicating(AudioPushSink* to_stream) {
448 DCHECK(message_loop_->BelongsToCurrentThread());
449 if (state_ == kClosed)
450 return;
451
452 // Already serving the stream.
453 if (duplication_targets_.find(to_stream) != duplication_targets_.end())
454 return;
455
456 duplication_targets_.insert(to_stream);
457 }
458
459 void AudioOutputController::DoStopDuplicating(AudioPushSink* to_stream) {
460 DCHECK(message_loop_->BelongsToCurrentThread());
461
462 to_stream->Close();
463 if (state_ == kClosed)
464 return;
465
466 duplication_targets_.erase(to_stream);
467 }
468
422 std::pair<float, bool> AudioOutputController::ReadCurrentPowerAndClip() { 469 std::pair<float, bool> AudioOutputController::ReadCurrentPowerAndClip() {
423 DCHECK(will_monitor_audio_levels()); 470 DCHECK(will_monitor_audio_levels());
424 return power_monitor_.ReadCurrentPowerAndClip(); 471 return power_monitor_.ReadCurrentPowerAndClip();
425 } 472 }
426 473
427 void AudioOutputController::WedgeCheck() { 474 void AudioOutputController::WedgeCheck() {
428 DCHECK(message_loop_->BelongsToCurrentThread()); 475 DCHECK(message_loop_->BelongsToCurrentThread());
429 476
430 // If we should be playing and we haven't, that's a wedge. 477 // If we should be playing and we haven't, that's a wedge.
431 if (state_ == kPlaying) { 478 if (state_ == kPlaying) {
432 UMA_HISTOGRAM_BOOLEAN("Media.AudioOutputControllerPlaybackStartupSuccess", 479 UMA_HISTOGRAM_BOOLEAN("Media.AudioOutputControllerPlaybackStartupSuccess",
433 base::AtomicRefCountIsOne(&on_more_io_data_called_)); 480 base::AtomicRefCountIsOne(&on_more_io_data_called_));
434 } 481 }
435 } 482 }
436 483
437 } // namespace media 484 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698