| 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 "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
| 9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
| 10 #include "base/task_runner_util.h" | 10 #include "base/task_runner_util.h" |
| 11 #include "base/threading/platform_thread.h" | 11 #include "base/threading/platform_thread.h" |
| 12 #include "base/time/time.h" | 12 #include "base/time/time.h" |
| 13 #include "build/build_config.h" | 13 #include "build/build_config.h" |
| 14 #include "media/base/scoped_histogram_timer.h" | 14 #include "media/base/scoped_histogram_timer.h" |
| 15 | 15 |
| 16 using base::TimeDelta; | 16 using base::TimeDelta; |
| 17 | 17 |
| 18 namespace media { | 18 namespace media { |
| 19 | 19 |
| 20 #if defined(AUDIO_POWER_MONITORING) |
| 21 // Time constant for AudioPowerMonitor. See AudioPowerMonitor ctor comments for |
| 22 // semantics. This value was arbitrarily chosen, but seems to work well. |
| 23 static const int kPowerMeasurementTimeConstantMillis = 10; |
| 24 #endif |
| 25 |
| 20 AudioOutputController::AudioOutputController( | 26 AudioOutputController::AudioOutputController( |
| 21 AudioManager* audio_manager, | 27 AudioManager* audio_manager, |
| 22 EventHandler* handler, | 28 EventHandler* handler, |
| 23 const AudioParameters& params, | 29 const AudioParameters& params, |
| 24 const std::string& output_device_id, | 30 const std::string& output_device_id, |
| 25 SyncReader* sync_reader) | 31 SyncReader* sync_reader) |
| 26 : audio_manager_(audio_manager), | 32 : audio_manager_(audio_manager), |
| 27 params_(params), | 33 params_(params), |
| 28 handler_(handler), | 34 handler_(handler), |
| 29 output_device_id_(output_device_id), | 35 output_device_id_(output_device_id), |
| 30 stream_(NULL), | 36 stream_(NULL), |
| 31 diverting_to_stream_(NULL), | 37 diverting_to_stream_(NULL), |
| 32 volume_(1.0), | 38 volume_(1.0), |
| 33 state_(kEmpty), | 39 state_(kEmpty), |
| 34 sync_reader_(sync_reader), | 40 sync_reader_(sync_reader), |
| 35 message_loop_(audio_manager->GetTaskRunner()), | 41 message_loop_(audio_manager->GetTaskRunner()), |
| 42 #if defined(AUDIO_POWER_MONITORING) |
| 36 power_monitor_( | 43 power_monitor_( |
| 37 params.sample_rate(), | 44 params.sample_rate(), |
| 38 TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMillis)), | 45 TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMillis)), |
| 46 #endif |
| 39 on_more_io_data_called_(0) { | 47 on_more_io_data_called_(0) { |
| 40 DCHECK(audio_manager); | 48 DCHECK(audio_manager); |
| 41 DCHECK(handler_); | 49 DCHECK(handler_); |
| 42 DCHECK(sync_reader_); | 50 DCHECK(sync_reader_); |
| 43 DCHECK(message_loop_.get()); | 51 DCHECK(message_loop_.get()); |
| 44 } | 52 } |
| 45 | 53 |
| 46 AudioOutputController::~AudioOutputController() { | 54 AudioOutputController::~AudioOutputController() { |
| 47 DCHECK_EQ(kClosed, state_); | 55 DCHECK_EQ(kClosed, state_); |
| 48 } | 56 } |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 handler_->OnPlaying(); | 193 handler_->OnPlaying(); |
| 186 } | 194 } |
| 187 | 195 |
| 188 void AudioOutputController::StopStream() { | 196 void AudioOutputController::StopStream() { |
| 189 DCHECK(message_loop_->BelongsToCurrentThread()); | 197 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 190 | 198 |
| 191 if (state_ == kPlaying) { | 199 if (state_ == kPlaying) { |
| 192 wedge_timer_.reset(); | 200 wedge_timer_.reset(); |
| 193 stream_->Stop(); | 201 stream_->Stop(); |
| 194 | 202 |
| 203 #if defined(AUDIO_POWER_MONITORING) |
| 195 // A stopped stream is silent, and power_montior_.Scan() is no longer being | 204 // A stopped stream is silent, and power_montior_.Scan() is no longer being |
| 196 // called; so we must reset the power monitor. | 205 // called; so we must reset the power monitor. |
| 197 power_monitor_.Reset(); | 206 power_monitor_.Reset(); |
| 207 #endif |
| 198 | 208 |
| 199 state_ = kPaused; | 209 state_ = kPaused; |
| 200 } | 210 } |
| 201 } | 211 } |
| 202 | 212 |
| 203 void AudioOutputController::DoPause() { | 213 void AudioOutputController::DoPause() { |
| 204 DCHECK(message_loop_->BelongsToCurrentThread()); | 214 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 205 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.PauseTime"); | 215 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.PauseTime"); |
| 206 TRACE_EVENT0("audio", "AudioOutputController::DoPause"); | 216 TRACE_EVENT0("audio", "AudioOutputController::DoPause"); |
| 207 | 217 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 // thread starts, its safe to compare and then increment. | 299 // thread starts, its safe to compare and then increment. |
| 290 if (base::AtomicRefCountIsZero(&on_more_io_data_called_)) | 300 if (base::AtomicRefCountIsZero(&on_more_io_data_called_)) |
| 291 base::AtomicRefCountInc(&on_more_io_data_called_); | 301 base::AtomicRefCountInc(&on_more_io_data_called_); |
| 292 | 302 |
| 293 sync_reader_->Read(dest); | 303 sync_reader_->Read(dest); |
| 294 | 304 |
| 295 const int frames = dest->frames(); | 305 const int frames = dest->frames(); |
| 296 sync_reader_->UpdatePendingBytes( | 306 sync_reader_->UpdatePendingBytes( |
| 297 buffers_state.total_bytes() + frames * params_.GetBytesPerFrame()); | 307 buffers_state.total_bytes() + frames * params_.GetBytesPerFrame()); |
| 298 | 308 |
| 299 if (will_monitor_audio_levels()) | 309 #if defined(AUDIO_POWER_MONITORING) |
| 300 power_monitor_.Scan(*dest, frames); | 310 power_monitor_.Scan(*dest, frames); |
| 311 #endif |
| 301 | 312 |
| 302 return frames; | 313 return frames; |
| 303 } | 314 } |
| 304 | 315 |
| 305 void AudioOutputController::OnError(AudioOutputStream* stream) { | 316 void AudioOutputController::OnError(AudioOutputStream* stream) { |
| 306 // Handle error on the audio controller thread. | 317 // Handle error on the audio controller thread. |
| 307 message_loop_->PostTask(FROM_HERE, base::Bind( | 318 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 308 &AudioOutputController::DoReportError, this)); | 319 &AudioOutputController::DoReportError, this)); |
| 309 } | 320 } |
| 310 | 321 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 return; | 405 return; |
| 395 | 406 |
| 396 // Note: OnDeviceChange() will cause the existing stream (the consumer of the | 407 // Note: OnDeviceChange() will cause the existing stream (the consumer of the |
| 397 // diverted audio data) to be closed, and diverting_to_stream_ will be set | 408 // diverted audio data) to be closed, and diverting_to_stream_ will be set |
| 398 // back to NULL. | 409 // back to NULL. |
| 399 OnDeviceChange(); | 410 OnDeviceChange(); |
| 400 DCHECK(!diverting_to_stream_); | 411 DCHECK(!diverting_to_stream_); |
| 401 } | 412 } |
| 402 | 413 |
| 403 std::pair<float, bool> AudioOutputController::ReadCurrentPowerAndClip() { | 414 std::pair<float, bool> AudioOutputController::ReadCurrentPowerAndClip() { |
| 404 DCHECK(will_monitor_audio_levels()); | 415 #if defined(AUDIO_POWER_MONITORING) |
| 405 return power_monitor_.ReadCurrentPowerAndClip(); | 416 return power_monitor_.ReadCurrentPowerAndClip(); |
| 417 #else |
| 418 NOTREACHED(); |
| 419 return std::make_pair(AudioPowerMonitor::zero_power(), false); |
| 420 #endif |
| 406 } | 421 } |
| 407 | 422 |
| 408 void AudioOutputController::WedgeCheck() { | 423 void AudioOutputController::WedgeCheck() { |
| 409 DCHECK(message_loop_->BelongsToCurrentThread()); | 424 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 410 | 425 |
| 411 // If we should be playing and we haven't, that's a wedge. | 426 // If we should be playing and we haven't, that's a wedge. |
| 412 if (state_ == kPlaying) { | 427 if (state_ == kPlaying) { |
| 413 UMA_HISTOGRAM_BOOLEAN("Media.AudioOutputControllerPlaybackStartupSuccess", | 428 UMA_HISTOGRAM_BOOLEAN("Media.AudioOutputControllerPlaybackStartupSuccess", |
| 414 base::AtomicRefCountIsOne(&on_more_io_data_called_)); | 429 base::AtomicRefCountIsOne(&on_more_io_data_called_)); |
| 415 } | 430 } |
| 416 } | 431 } |
| 417 | 432 |
| 418 } // namespace media | 433 } // namespace media |
| OLD | NEW |