summaryrefslogtreecommitdiffstats
path: root/media/audio/audio_power_monitor.h
diff options
context:
space:
mode:
authormiu@chromium.org <miu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-13 00:50:15 +0000
committermiu@chromium.org <miu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-13 00:50:15 +0000
commita49a7affa8d97883291227304f5399ee6728ec69 (patch)
tree081a4f306632a7c6e0fb3bb4aea6021ccd6f23e7 /media/audio/audio_power_monitor.h
parentf4860129978c4927c19265be1c4e18f0f099c7b2 (diff)
downloadchromium_src-a49a7affa8d97883291227304f5399ee6728ec69.zip
chromium_src-a49a7affa8d97883291227304f5399ee6728ec69.tar.gz
chromium_src-a49a7affa8d97883291227304f5399ee6728ec69.tar.bz2
Crash fix: Remove MessageLoop from AudioPowerMonitor and instead use MessageLoopProxy in AudioOutputController.
Root cause: AudioPowerMonitor held a reference to the audio thread's MessageLoop and erroneously assumed it would be valid until after the audio stream is closed. However, at browser shutdown, it's possible for audio streams to be closed by the correct thread, but *after* the MessageLoop associated with the thread is destroyed. BUG=268629 TEST=media_unittests and manual confirmation by running a browser with the --enable-audible-notifications command-line flag. Review URL: https://chromiumcodereview.appspot.com/22339024 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@217142 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio/audio_power_monitor.h')
-rw-r--r--media/audio/audio_power_monitor.h53
1 files changed, 22 insertions, 31 deletions
diff --git a/media/audio/audio_power_monitor.h b/media/audio/audio_power_monitor.h
index b65fb13..f840bbf 100644
--- a/media/audio/audio_power_monitor.h
+++ b/media/audio/audio_power_monitor.h
@@ -6,8 +6,10 @@
#define MEDIA_AUDIO_AUDIO_POWER_MONITOR_H_
#include <limits>
+#include <utility>
#include "base/callback.h"
+#include "base/synchronization/lock.h"
#include "media/base/media_export.h"
// An audio signal power monitor. It is periodically provided an AudioBus by
@@ -24,7 +26,6 @@
// undetermined/unbounded amount of run-time.
namespace base {
-class MessageLoop;
class TimeDelta;
}
@@ -34,31 +35,28 @@ class AudioBus;
class MEDIA_EXPORT AudioPowerMonitor {
public:
- // Reports power level in terms of dBFS (see zero_power() and max_power()
- // below). |clipped| is true if any *one* sample exceeded maximum amplitude
- // since the last invocation.
- typedef base::Callback<void(float power_dbfs, bool clipped)>
- PowerMeasurementCallback;
-
// |sample_rate| is the audio signal sample rate (Hz). |time_constant|
// characterizes how samples are averaged over time to determine the power
// level; and is the amount of time it takes a zero power level to increase to
- // ~63.2% of maximum given a step input signal. |measurement_period| is the
- // time length of signal to analyze before invoking the callback to report the
- // current power level. |message_loop| is where the |callback| task will be
- // posted.
- AudioPowerMonitor(int sample_rate,
- const base::TimeDelta& time_constant,
- const base::TimeDelta& measurement_period,
- base::MessageLoop* message_loop,
- const PowerMeasurementCallback& callback);
+ // ~63.2% of maximum given a step input signal.
+ AudioPowerMonitor(int sample_rate, const base::TimeDelta& time_constant);
~AudioPowerMonitor();
+ // Reset power monitor to initial state (zero power level). This should not
+ // be called while another thread is scanning.
+ void Reset();
+
// Scan more |frames| of audio data from |buffer|. It is safe to call this
// from a real-time priority thread.
void Scan(const AudioBus& buffer, int frames);
+ // Returns the current power level in dBFS and clip status. Clip status is
+ // true whenever any *one* sample scanned exceeded maximum amplitude since
+ // this method's last invocation. It is safe to call this method from any
+ // thread.
+ std::pair<float, bool> ReadCurrentPowerAndClip();
+
// dBFS value corresponding to zero power in the audio signal.
static float zero_power() { return -std::numeric_limits<float>::infinity(); }
@@ -70,23 +68,16 @@ class MEDIA_EXPORT AudioPowerMonitor {
// |sample_rate| and |time_constant|.
const float sample_weight_;
- // Number of audio frames to be scanned before reporting the current power
- // level via callback, as computed from |sample_rate| and
- // |measurement_period|.
- const int num_frames_per_callback_;
-
- // MessageLoop and callback used to notify of the current power level.
- base::MessageLoop* const message_loop_;
- const PowerMeasurementCallback power_level_callback_;
-
- // Accumulated results over one or more calls to Scan().
+ // Accumulated results over one or more calls to Scan(). These should only be
+ // touched by the thread invoking Scan().
float average_power_;
- bool clipped_since_last_notification_;
- int frames_since_last_notification_;
+ bool has_clipped_;
- // Keep track of last reported results to forgo making redundant callbacks.
- float last_reported_power_;
- bool last_reported_clipped_;
+ // Copies of power and clip status, used to deliver results synchronously
+ // across threads.
+ base::Lock reading_lock_;
+ float power_reading_;
+ bool clipped_reading_;
DISALLOW_COPY_AND_ASSIGN(AudioPowerMonitor);
};