diff options
author | miu@chromium.org <miu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-11 22:46:22 +0000 |
---|---|---|
committer | miu@chromium.org <miu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-11 22:46:22 +0000 |
commit | aed46f19468defa557502a01c4b4ea09ee378280 (patch) | |
tree | d85e07aa63783c20b4506a7ae4c7ef9942158c96 /media/audio | |
parent | fb357889be3b84e8c78cacfde16870a2da92c1c1 (diff) | |
download | chromium_src-aed46f19468defa557502a01c4b4ea09ee378280.zip chromium_src-aed46f19468defa557502a01c4b4ea09ee378280.tar.gz chromium_src-aed46f19468defa557502a01c4b4ea09ee378280.tar.bz2 |
Replumb audible playback detection to use a poll-based approach.
The previous approach involved hopping across three threads for every data update, and was riddled with a number of other warts. This change contains a rewrite of AudioStreamIndicator (now called AudioStreamMonitor) to: 1) use an efficient polling-based approach for audible tab detection; 2) resolve bug 339133 by using simple debouncing logic; 3) solve the problem of massively redundantly notifying the tab UI when no state changes occur. Also, this functionality now has unit tests where it did not before.
Other changes:
1. Adding miu@ to OWNERS for tab media indicator-related code.
2. While making interface changes in MediaObserver, I did a little work to help migrate from render view IDs to render frame IDs.
BUG=339133
TEST=New AudioStreamMonitorTest's in unit_tests. Also, manually confirmed behavior fixes using repro steps in bug 339133.
Review URL: https://codereview.chromium.org/135013008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@256346 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio')
-rw-r--r-- | media/audio/audio_output_controller.cc | 44 | ||||
-rw-r--r-- | media/audio/audio_output_controller.h | 13 | ||||
-rw-r--r-- | media/audio/audio_output_controller_unittest.cc | 8 |
3 files changed, 17 insertions, 48 deletions
diff --git a/media/audio/audio_output_controller.cc b/media/audio/audio_output_controller.cc index 30ea33d..381452e 100644 --- a/media/audio/audio_output_controller.cc +++ b/media/audio/audio_output_controller.cc @@ -21,10 +21,6 @@ namespace media { // Time constant for AudioPowerMonitor. See AudioPowerMonitor ctor comments for // semantics. This value was arbitrarily chosen, but seems to work well. static const int kPowerMeasurementTimeConstantMillis = 10; - -// Desired frequency of calls to EventHandler::OnPowerMeasured() for reporting -// power levels in the audio signal. -static const int kPowerMeasurementsPerSecond = 4; #endif // Polling-related constants. @@ -183,16 +179,6 @@ void AudioOutputController::DoPlay() { state_ = kPlaying; -#if defined(AUDIO_POWER_MONITORING) - power_monitor_.Reset(); - power_poll_callback_.Reset( - base::Bind(&AudioOutputController::ReportPowerMeasurementPeriodically, - this)); - // Run the callback to send an initial notification that we're starting in - // silence, and to schedule periodic callbacks. - power_poll_callback_.callback().Run(); -#endif - stream_->Start(this); // For UMA tracking purposes, start the wedge detection timer. This allows us @@ -214,18 +200,6 @@ void AudioOutputController::DoPlay() { handler_->OnPlaying(); } -#if defined(AUDIO_POWER_MONITORING) -void AudioOutputController::ReportPowerMeasurementPeriodically() { - DCHECK(message_loop_->BelongsToCurrentThread()); - const std::pair<float, bool>& reading = - power_monitor_.ReadCurrentPowerAndClip(); - handler_->OnPowerMeasured(reading.first, reading.second); - message_loop_->PostDelayedTask( - FROM_HERE, power_poll_callback_.callback(), - TimeDelta::FromSeconds(1) / kPowerMeasurementsPerSecond); -} -#endif - void AudioOutputController::StopStream() { DCHECK(message_loop_->BelongsToCurrentThread()); @@ -234,7 +208,9 @@ void AudioOutputController::StopStream() { stream_->Stop(); #if defined(AUDIO_POWER_MONITORING) - power_poll_callback_.Cancel(); + // A stopped stream is silent, and power_montior_.Scan() is no longer being + // called; so we must reset the power monitor. + power_monitor_.Reset(); #endif state_ = kPaused; @@ -256,11 +232,6 @@ void AudioOutputController::DoPause() { // a better way to know when it should exit PPB_Audio_Shared::Run(). sync_reader_->UpdatePendingBytes(-1); -#if defined(AUDIO_POWER_MONITORING) - // Paused means silence follows. - handler_->OnPowerMeasured(AudioPowerMonitor::zero_power(), false); -#endif - handler_->OnPaused(); } @@ -455,6 +426,15 @@ void AudioOutputController::DoStopDiverting() { DCHECK(!diverting_to_stream_); } +std::pair<float, bool> AudioOutputController::ReadCurrentPowerAndClip() { +#if defined(AUDIO_POWER_MONITORING) + return power_monitor_.ReadCurrentPowerAndClip(); +#else + NOTREACHED(); + return std::make_pair(AudioPowerMonitor::zero_power(), false); +#endif +} + void AudioOutputController::WedgeCheck() { DCHECK(message_loop_->BelongsToCurrentThread()); diff --git a/media/audio/audio_output_controller.h b/media/audio/audio_output_controller.h index 4110c07..1a64d63 100644 --- a/media/audio/audio_output_controller.h +++ b/media/audio/audio_output_controller.h @@ -7,7 +7,6 @@ #include "base/atomic_ref_count.h" #include "base/callback.h" -#include "base/cancelable_callback.h" #include "base/memory/ref_counted.h" #include "base/timer/timer.h" #include "media/audio/audio_io.h" @@ -70,7 +69,6 @@ class MEDIA_EXPORT AudioOutputController public: virtual void OnCreated() = 0; virtual void OnPlaying() = 0; - virtual void OnPowerMeasured(float power_dbfs, bool clipped) = 0; virtual void OnPaused() = 0; virtual void OnError() = 0; virtual void OnDeviceChange(int new_buffer_size, int new_sample_rate) = 0; @@ -169,6 +167,10 @@ class MEDIA_EXPORT AudioOutputController virtual void StartDiverting(AudioOutputStream* to_stream) OVERRIDE; virtual void StopDiverting() OVERRIDE; + // Accessor for AudioPowerMonitor::ReadCurrentPowerAndClip(). See comments in + // audio_power_monitor.h for usage. This may be called on any thread. + std::pair<float, bool> ReadCurrentPowerAndClip(); + protected: // Internal state of the source. enum State { @@ -205,10 +207,6 @@ class MEDIA_EXPORT AudioOutputController void DoStartDiverting(AudioOutputStream* to_stream); void DoStopDiverting(); - // Calls EventHandler::OnPowerMeasured() with the current power level and then - // schedules itself to be called again later. - void ReportPowerMeasurementPeriodically(); - // Helper method that stops the physical stream. void StopStream(); @@ -253,9 +251,6 @@ class MEDIA_EXPORT AudioOutputController #if defined(AUDIO_POWER_MONITORING) // Scans audio samples from OnMoreIOData() as input to compute power levels. AudioPowerMonitor power_monitor_; - - // Periodic callback to report power levels during playback. - base::CancelableClosure power_poll_callback_; #endif // Flags when we've asked for a stream to start but it never did. diff --git a/media/audio/audio_output_controller_unittest.cc b/media/audio/audio_output_controller_unittest.cc index b4270e6..9d3cc4ef 100644 --- a/media/audio/audio_output_controller_unittest.cc +++ b/media/audio/audio_output_controller_unittest.cc @@ -39,7 +39,6 @@ class MockAudioOutputControllerEventHandler MOCK_METHOD0(OnCreated, void()); MOCK_METHOD0(OnPlaying, void()); - MOCK_METHOD2(OnPowerMeasured, void(float power_dbfs, bool clipped)); MOCK_METHOD0(OnPaused, void()); MOCK_METHOD0(OnError, void()); MOCK_METHOD2(OnDeviceChange, void(int new_buffer_size, int new_sample_rate)); @@ -129,14 +128,9 @@ class AudioOutputControllerTest : public testing::Test { } void Play() { - // Expect the event handler to receive one OnPlaying() call and one or more - // OnPowerMeasured() calls. + // Expect the event handler to receive one OnPlaying() call. EXPECT_CALL(mock_event_handler_, OnPlaying()) .WillOnce(SignalEvent(&play_event_)); -#if defined(AUDIO_POWER_MONITORING) - EXPECT_CALL(mock_event_handler_, OnPowerMeasured(_, false)) - .Times(AtLeast(1)); -#endif // During playback, the mock pretends to provide audio data rendered and // sent from the render process. |