Chromium Code Reviews| 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 "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 <algorithm> | 9 #include <algorithm> |
| 10 #include <limits> | 10 #include <limits> |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 27 EventHandler* handler, | 27 EventHandler* handler, |
| 28 const AudioParameters& params, | 28 const AudioParameters& params, |
| 29 const std::string& output_device_id, | 29 const std::string& output_device_id, |
| 30 SyncReader* sync_reader) | 30 SyncReader* sync_reader) |
| 31 : audio_manager_(audio_manager), | 31 : audio_manager_(audio_manager), |
| 32 params_(params), | 32 params_(params), |
| 33 handler_(handler), | 33 handler_(handler), |
| 34 output_device_id_(output_device_id), | 34 output_device_id_(output_device_id), |
| 35 stream_(NULL), | 35 stream_(NULL), |
| 36 diverting_to_stream_(NULL), | 36 diverting_to_stream_(NULL), |
| 37 should_duplicate_(0), | |
| 37 volume_(1.0), | 38 volume_(1.0), |
| 38 state_(kEmpty), | 39 state_(kEmpty), |
| 39 sync_reader_(sync_reader), | 40 sync_reader_(sync_reader), |
| 40 message_loop_(audio_manager->GetTaskRunner()), | 41 message_loop_(audio_manager->GetTaskRunner()), |
| 41 power_monitor_( | 42 power_monitor_( |
| 42 params.sample_rate(), | 43 params.sample_rate(), |
| 43 TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMillis)), | 44 TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMillis)), |
| 44 on_more_io_data_called_(0), | 45 on_more_io_data_called_(0), |
| 45 ignore_errors_during_stop_close_(false) { | 46 ignore_errors_during_stop_close_(false) { |
| 46 DCHECK(audio_manager); | 47 DCHECK(audio_manager); |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 265 if (base::AtomicRefCountIsZero(&on_more_io_data_called_)) | 266 if (base::AtomicRefCountIsZero(&on_more_io_data_called_)) |
| 266 base::AtomicRefCountInc(&on_more_io_data_called_); | 267 base::AtomicRefCountInc(&on_more_io_data_called_); |
| 267 | 268 |
| 268 sync_reader_->Read(dest); | 269 sync_reader_->Read(dest); |
| 269 | 270 |
| 270 const int frames = dest->frames(); | 271 const int frames = dest->frames(); |
| 271 delay += AudioTimestampHelper::FramesToTime(frames, params_.sample_rate()); | 272 delay += AudioTimestampHelper::FramesToTime(frames, params_.sample_rate()); |
| 272 | 273 |
| 273 sync_reader_->RequestMoreData(delay, delay_timestamp, prior_frames_skipped); | 274 sync_reader_->RequestMoreData(delay, delay_timestamp, prior_frames_skipped); |
| 274 | 275 |
| 275 bool need_to_duplicate = false; | 276 if (base::AtomicRefCountIsOne(&should_duplicate_)) { |
| 276 { | |
| 277 base::AutoLock lock(duplication_targets_lock_); | |
| 278 need_to_duplicate = !duplication_targets_.empty(); | |
| 279 } | |
| 280 if (need_to_duplicate) { | |
| 281 const base::TimeTicks reference_time = delay_timestamp + delay; | 277 const base::TimeTicks reference_time = delay_timestamp + delay; |
| 282 std::unique_ptr<AudioBus> copy(AudioBus::Create(params_)); | 278 std::unique_ptr<AudioBus> copy(AudioBus::Create(params_)); |
|
miu
2017/05/18 03:06:29
BTW--The call to AudioBus::Create() here could als
| |
| 283 dest->CopyTo(copy.get()); | 279 dest->CopyTo(copy.get()); |
| 284 message_loop_->PostTask( | 280 message_loop_->PostTask( |
| 285 FROM_HERE, | 281 FROM_HERE, |
| 286 base::BindOnce( | 282 base::BindOnce( |
| 287 &AudioOutputController::BroadcastDataToDuplicationTargets, this, | 283 &AudioOutputController::BroadcastDataToDuplicationTargets, this, |
| 288 std::move(copy), reference_time)); | 284 std::move(copy), reference_time)); |
| 289 } | 285 } |
| 290 | 286 |
| 291 if (will_monitor_audio_levels()) | 287 if (will_monitor_audio_levels()) |
| 292 power_monitor_.Scan(*dest, frames); | 288 power_monitor_.Scan(*dest, frames); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 436 // back to NULL. | 432 // back to NULL. |
| 437 OnDeviceChange(); | 433 OnDeviceChange(); |
| 438 DCHECK(!diverting_to_stream_); | 434 DCHECK(!diverting_to_stream_); |
| 439 } | 435 } |
| 440 | 436 |
| 441 void AudioOutputController::DoStartDuplicating(AudioPushSink* to_stream) { | 437 void AudioOutputController::DoStartDuplicating(AudioPushSink* to_stream) { |
| 442 DCHECK(message_loop_->BelongsToCurrentThread()); | 438 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 443 if (state_ == kClosed) | 439 if (state_ == kClosed) |
| 444 return; | 440 return; |
| 445 | 441 |
| 446 base::AutoLock lock(duplication_targets_lock_); | 442 if (duplication_targets_.empty()) |
| 443 base::AtomicRefCountInc(&should_duplicate_); | |
| 444 | |
| 447 duplication_targets_.insert(to_stream); | 445 duplication_targets_.insert(to_stream); |
| 448 } | 446 } |
| 449 | 447 |
| 450 void AudioOutputController::DoStopDuplicating(AudioPushSink* to_stream) { | 448 void AudioOutputController::DoStopDuplicating(AudioPushSink* to_stream) { |
| 451 DCHECK(message_loop_->BelongsToCurrentThread()); | 449 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 452 to_stream->Close(); | 450 to_stream->Close(); |
| 453 | 451 |
| 454 base::AutoLock lock(duplication_targets_lock_); | |
| 455 duplication_targets_.erase(to_stream); | 452 duplication_targets_.erase(to_stream); |
| 453 if (duplication_targets_.empty()) { | |
| 454 const bool is_nonzero = base::AtomicRefCountDec(&should_duplicate_); | |
| 455 DCHECK(!is_nonzero); | |
| 456 } | |
| 456 } | 457 } |
| 457 | 458 |
| 458 std::pair<float, bool> AudioOutputController::ReadCurrentPowerAndClip() { | 459 std::pair<float, bool> AudioOutputController::ReadCurrentPowerAndClip() { |
| 459 DCHECK(will_monitor_audio_levels()); | 460 DCHECK(will_monitor_audio_levels()); |
| 460 return power_monitor_.ReadCurrentPowerAndClip(); | 461 return power_monitor_.ReadCurrentPowerAndClip(); |
| 461 } | 462 } |
| 462 | 463 |
| 463 void AudioOutputController::WedgeCheck() { | 464 void AudioOutputController::WedgeCheck() { |
| 464 DCHECK(message_loop_->BelongsToCurrentThread()); | 465 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 465 | 466 |
| 466 // If we should be playing and we haven't, that's a wedge. | 467 // If we should be playing and we haven't, that's a wedge. |
| 467 if (state_ == kPlaying) { | 468 if (state_ == kPlaying) { |
| 468 UMA_HISTOGRAM_BOOLEAN("Media.AudioOutputControllerPlaybackStartupSuccess", | 469 UMA_HISTOGRAM_BOOLEAN("Media.AudioOutputControllerPlaybackStartupSuccess", |
| 469 base::AtomicRefCountIsOne(&on_more_io_data_called_)); | 470 base::AtomicRefCountIsOne(&on_more_io_data_called_)); |
| 470 } | 471 } |
| 471 } | 472 } |
| 472 | 473 |
| 473 } // namespace media | 474 } // namespace media |
| OLD | NEW |