| 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 | 
|---|