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 |