summaryrefslogtreecommitdiffstats
path: root/media/audio
diff options
context:
space:
mode:
authormiu@chromium.org <miu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-11 22:46:22 +0000
committermiu@chromium.org <miu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-11 22:46:22 +0000
commitaed46f19468defa557502a01c4b4ea09ee378280 (patch)
treed85e07aa63783c20b4506a7ae4c7ef9942158c96 /media/audio
parentfb357889be3b84e8c78cacfde16870a2da92c1c1 (diff)
downloadchromium_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.cc44
-rw-r--r--media/audio/audio_output_controller.h13
-rw-r--r--media/audio/audio_output_controller_unittest.cc8
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.