Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(776)

Unified Diff: media/audio/audio_output_controller.cc

Issue 14600025: Replace AudioSilenceDetector with an AudioPowerMonitor. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix subtle shutdown race condition. Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/audio/audio_output_controller.h ('k') | media/audio/audio_output_controller_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/audio/audio_output_controller.cc
diff --git a/media/audio/audio_output_controller.cc b/media/audio/audio_output_controller.cc
index 915ca35f400fd7a3efe7e8392332731fc4e441e1..329d3212d50a6db65c7f0843228b8a526a2c0b66 100644
--- a/media/audio/audio_output_controller.cc
+++ b/media/audio/audio_output_controller.cc
@@ -11,9 +11,10 @@
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "build/build_config.h"
-#include "media/audio/audio_silence_detector.h"
+#include "media/audio/audio_power_monitor.h"
#include "media/audio/audio_util.h"
#include "media/audio/shared_memory_util.h"
+#include "media/base/bind_to_loop.h"
#include "media/base/scoped_histogram_timer.h"
using base::Time;
@@ -21,16 +22,13 @@ using base::TimeDelta;
namespace media {
-// Amount of contiguous time where all audio is silent before considering the
-// stream to have transitioned and EventHandler::OnAudible() should be called.
-static const int kQuestionableSilencePeriodMillis = 50;
+// 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;
-// Sample value range below which audio is considered indistinguishably silent.
-//
-// TODO(miu): This value should be specified in dbFS units rather than full
-// scale. See TODO in audio_silence_detector.h.
-static const float kIndistinguishableSilenceThreshold =
- 1.0f / 4096.0f; // Note: This is approximately -72 dbFS.
+// Desired frequency of calls to EventHandler::OnPowerMeasured() for reporting
+// power levels in the audio signal.
+static const int kPowerMeasurementsPerSecond = 30;
// Polling-related constants.
const int AudioOutputController::kPollNumAttempts = 3;
@@ -95,8 +93,10 @@ void AudioOutputController::Pause() {
void AudioOutputController::Close(const base::Closure& closed_task) {
DCHECK(!closed_task.is_null());
- message_loop_->PostTaskAndReply(FROM_HERE, base::Bind(
- &AudioOutputController::DoClose, this), closed_task);
+ // See comment in DoClose(), which explains why this can't be a simple
+ // PostTaskAndReply() operation.
+ message_loop_->PostTask(FROM_HERE, base::Bind(
+ &AudioOutputController::DoClose, this, BindToCurrentLoop(closed_task)));
}
void AudioOutputController::SetVolume(double volume) {
@@ -158,20 +158,22 @@ void AudioOutputController::DoPlay() {
sync_reader_->UpdatePendingBytes(0);
state_ = kPlaying;
- silence_detector_.reset(new AudioSilenceDetector(
+
+ // Start monitoring power levels and send an initial notification that we're
+ // starting in silence.
+ handler_->OnPowerMeasured(AudioPowerMonitor::zero_power(), false);
+ power_monitor_.reset(new AudioPowerMonitor(
params_.sample_rate(),
- TimeDelta::FromMilliseconds(kQuestionableSilencePeriodMillis),
- kIndistinguishableSilenceThreshold));
+ TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMillis),
+ TimeDelta::FromSeconds(1) / kPowerMeasurementsPerSecond,
+ base::MessageLoop::current(),
+ base::Bind(&EventHandler::OnPowerMeasured, base::Unretained(handler_))));
// We start the AudioOutputStream lazily.
AllowEntryToOnMoreIOData();
stream_->Start(this);
- // Tell the event handler that we are now playing, and also start the silence
- // detection notifications.
handler_->OnPlaying();
- silence_detector_->Start(
- base::Bind(&EventHandler::OnAudible, base::Unretained(handler_)));
}
void AudioOutputController::StopStream() {
@@ -180,8 +182,9 @@ void AudioOutputController::StopStream() {
if (state_ == kPlaying) {
stream_->Stop();
DisallowEntryToOnMoreIOData();
- silence_detector_->Stop(true);
- silence_detector_.reset();
+ power_monitor_.reset();
+ // Send a final notification that we're ending in silence.
+ handler_->OnPowerMeasured(AudioPowerMonitor::zero_power(), false);
state_ = kPaused;
}
}
@@ -201,7 +204,7 @@ void AudioOutputController::DoPause() {
handler_->OnPaused();
}
-void AudioOutputController::DoClose() {
+void AudioOutputController::DoClose(const base::Closure& done_callback) {
DCHECK(message_loop_->BelongsToCurrentThread());
SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.CloseTime");
@@ -210,6 +213,13 @@ void AudioOutputController::DoClose() {
sync_reader_->Close();
state_ = kClosed;
}
+
+ // The AudioOutputController is now closed. Until a playing stream was fully
DaleCurtis 2013/07/22 17:27:21 Is it really necessary to send a zero during close
miu 2013/07/22 21:10:48 You're right, this is unnecessary since the final
+ // stopped, however, there may have been additional tasks posted to
+ // |message_loop_| (e.g., by the AudioPowerMonitor). Such tasks may attempt
+ // to invoke EventHandler methods. Therefore, ensure that |done_callback| is
+ // run *after* those tasks to guarantee EventHandler remains alive for them.
+ message_loop_->PostTask(FROM_HERE, done_callback);
}
void AudioOutputController::DoSetVolume(double volume) {
@@ -270,7 +280,7 @@ int AudioOutputController::OnMoreIOData(AudioBus* source,
sync_reader_->UpdatePendingBytes(
buffers_state.total_bytes() + frames * params_.GetBytesPerFrame());
- silence_detector_->Scan(dest, frames);
+ power_monitor_->Scan(*dest, frames);
AllowEntryToOnMoreIOData();
return frames;
« no previous file with comments | « media/audio/audio_output_controller.h ('k') | media/audio/audio_output_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698