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 |