Commit d5ef7d4b authored by xians@chromium.org's avatar xians@chromium.org

Use audio thread for the fake input audio stream.

Previously the fake input stream is creating a new thread to pump the callbacks, this is unnecessary and FakeAudioInputStream::Stop() might take time to stop the thread. I suspect that this is one of the potential causes for the timeout in WebRtc content browser tests on Android bots.

This patch changes the code to use AudioManager audio thread instead, hopefully this can reduce the flakiness on Android tests.
Also it changes |beep_lock| from a global lock to a lock used only by BeepContext privately.

BUG=387895
TEST=bots

Review URL: https://codereview.chromium.org/399623008

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@283822 0039d316-1c4b-4281-b951-d872f2087c98
parent 90f0413f
...@@ -26,11 +26,31 @@ const int kAutomaticBeepIntervalInMs = 500; ...@@ -26,11 +26,31 @@ const int kAutomaticBeepIntervalInMs = 500;
// Automatic beep will be triggered every |kAutomaticBeepIntervalInMs| unless // Automatic beep will be triggered every |kAutomaticBeepIntervalInMs| unless
// users explicitly call BeepOnce(), which will disable the automatic beep. // users explicitly call BeepOnce(), which will disable the automatic beep.
struct BeepContext { class BeepContext {
BeepContext() : beep_once(false), automatic(true) {} public:
base::Lock beep_lock; BeepContext() : beep_once_(false), automatic_beep_(true) {}
bool beep_once;
bool automatic; void SetBeepOnce(bool enable) {
base::AutoLock auto_lock(lock_);
beep_once_ = enable;
// Disable the automatic beep if users explicit set |beep_once_| to true.
if (enable)
automatic_beep_ = false;
}
bool beep_once() const {
base::AutoLock auto_lock(lock_);
return beep_once_;
}
bool automatic_beep() const {
base::AutoLock auto_lock(lock_);
return automatic_beep_;
}
private:
mutable base::Lock lock_;
bool beep_once_;
bool automatic_beep_;
}; };
static base::LazyInstance<BeepContext> g_beep_context = static base::LazyInstance<BeepContext> g_beep_context =
...@@ -52,7 +72,7 @@ FakeAudioInputStream::FakeAudioInputStream(AudioManagerBase* manager, ...@@ -52,7 +72,7 @@ FakeAudioInputStream::FakeAudioInputStream(AudioManagerBase* manager,
params.frames_per_buffer()) / params.frames_per_buffer()) /
8), 8),
params_(params), params_(params),
thread_("FakeAudioRecordingThread"), task_runner_(manager->GetTaskRunner()),
callback_interval_(base::TimeDelta::FromMilliseconds( callback_interval_(base::TimeDelta::FromMilliseconds(
(params.frames_per_buffer() * 1000) / params.sample_rate())), (params.frames_per_buffer() * 1000) / params.sample_rate())),
beep_duration_in_buffers_(kBeepDurationMilliseconds * beep_duration_in_buffers_(kBeepDurationMilliseconds *
...@@ -62,12 +82,15 @@ FakeAudioInputStream::FakeAudioInputStream(AudioManagerBase* manager, ...@@ -62,12 +82,15 @@ FakeAudioInputStream::FakeAudioInputStream(AudioManagerBase* manager,
beep_generated_in_buffers_(0), beep_generated_in_buffers_(0),
beep_period_in_frames_(params.sample_rate() / kBeepFrequency), beep_period_in_frames_(params.sample_rate() / kBeepFrequency),
frames_elapsed_(0), frames_elapsed_(0),
audio_bus_(AudioBus::Create(params)) { audio_bus_(AudioBus::Create(params)),
weak_factory_(this) {
DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
} }
FakeAudioInputStream::~FakeAudioInputStream() {} FakeAudioInputStream::~FakeAudioInputStream() {}
bool FakeAudioInputStream::Open() { bool FakeAudioInputStream::Open() {
DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
buffer_.reset(new uint8[buffer_size_]); buffer_.reset(new uint8[buffer_size_]);
memset(buffer_.get(), 0, buffer_size_); memset(buffer_.get(), 0, buffer_size_);
audio_bus_->Zero(); audio_bus_->Zero();
...@@ -75,14 +98,13 @@ bool FakeAudioInputStream::Open() { ...@@ -75,14 +98,13 @@ bool FakeAudioInputStream::Open() {
} }
void FakeAudioInputStream::Start(AudioInputCallback* callback) { void FakeAudioInputStream::Start(AudioInputCallback* callback) {
DCHECK(!thread_.IsRunning()); DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
DCHECK(!callback_); DCHECK(!callback_);
callback_ = callback; callback_ = callback;
last_callback_time_ = TimeTicks::Now(); last_callback_time_ = TimeTicks::Now();
thread_.Start(); task_runner_->PostDelayedTask(
thread_.message_loop()->PostDelayedTask(
FROM_HERE, FROM_HERE,
base::Bind(&FakeAudioInputStream::DoCallback, base::Unretained(this)), base::Bind(&FakeAudioInputStream::DoCallback, weak_factory_.GetWeakPtr()),
callback_interval_); callback_interval_);
} }
...@@ -108,8 +130,7 @@ void FakeAudioInputStream::DoCallback() { ...@@ -108,8 +130,7 @@ void FakeAudioInputStream::DoCallback() {
bool should_beep = false; bool should_beep = false;
{ {
BeepContext* beep_context = g_beep_context.Pointer(); BeepContext* beep_context = g_beep_context.Pointer();
base::AutoLock auto_lock(beep_context->beep_lock); if (beep_context->automatic_beep()) {
if (beep_context->automatic) {
base::TimeDelta delta = interval_from_last_beep_ - base::TimeDelta delta = interval_from_last_beep_ -
TimeDelta::FromMilliseconds(kAutomaticBeepIntervalInMs); TimeDelta::FromMilliseconds(kAutomaticBeepIntervalInMs);
if (delta > base::TimeDelta()) { if (delta > base::TimeDelta()) {
...@@ -117,8 +138,8 @@ void FakeAudioInputStream::DoCallback() { ...@@ -117,8 +138,8 @@ void FakeAudioInputStream::DoCallback() {
interval_from_last_beep_ = delta; interval_from_last_beep_ = delta;
} }
} else { } else {
should_beep = beep_context->beep_once; should_beep = beep_context->beep_once();
beep_context->beep_once = false; beep_context->SetBeepOnce(false);
} }
} }
...@@ -151,29 +172,34 @@ void FakeAudioInputStream::DoCallback() { ...@@ -151,29 +172,34 @@ void FakeAudioInputStream::DoCallback() {
callback_->OnData(this, audio_bus_.get(), buffer_size_, 1.0); callback_->OnData(this, audio_bus_.get(), buffer_size_, 1.0);
frames_elapsed_ += params_.frames_per_buffer(); frames_elapsed_ += params_.frames_per_buffer();
thread_.message_loop()->PostDelayedTask( task_runner_->PostDelayedTask(
FROM_HERE, FROM_HERE,
base::Bind(&FakeAudioInputStream::DoCallback, base::Unretained(this)), base::Bind(&FakeAudioInputStream::DoCallback, weak_factory_.GetWeakPtr()),
next_callback_time); next_callback_time);
} }
void FakeAudioInputStream::Stop() { void FakeAudioInputStream::Stop() {
thread_.Stop(); DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
weak_factory_.InvalidateWeakPtrs();
callback_ = NULL; callback_ = NULL;
} }
void FakeAudioInputStream::Close() { void FakeAudioInputStream::Close() {
DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
audio_manager_->ReleaseInputStream(this); audio_manager_->ReleaseInputStream(this);
} }
double FakeAudioInputStream::GetMaxVolume() { double FakeAudioInputStream::GetMaxVolume() {
DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
return 1.0; return 1.0;
} }
void FakeAudioInputStream::SetVolume(double volume) { void FakeAudioInputStream::SetVolume(double volume) {
DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
} }
double FakeAudioInputStream::GetVolume() { double FakeAudioInputStream::GetVolume() {
DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
return 1.0; return 1.0;
} }
...@@ -186,9 +212,7 @@ bool FakeAudioInputStream::GetAutomaticGainControl() { ...@@ -186,9 +212,7 @@ bool FakeAudioInputStream::GetAutomaticGainControl() {
// static // static
void FakeAudioInputStream::BeepOnce() { void FakeAudioInputStream::BeepOnce() {
BeepContext* beep_context = g_beep_context.Pointer(); BeepContext* beep_context = g_beep_context.Pointer();
base::AutoLock auto_lock(beep_context->beep_lock); beep_context->SetBeepOnce(true);
beep_context->beep_once = true;
beep_context->automatic = false;
} }
} // namespace media } // namespace media
...@@ -61,7 +61,7 @@ class MEDIA_EXPORT FakeAudioInputStream ...@@ -61,7 +61,7 @@ class MEDIA_EXPORT FakeAudioInputStream
scoped_ptr<uint8[]> buffer_; scoped_ptr<uint8[]> buffer_;
int buffer_size_; int buffer_size_;
AudioParameters params_; AudioParameters params_;
base::Thread thread_; const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
base::TimeTicks last_callback_time_; base::TimeTicks last_callback_time_;
base::TimeDelta callback_interval_; base::TimeDelta callback_interval_;
base::TimeDelta interval_from_last_beep_; base::TimeDelta interval_from_last_beep_;
...@@ -71,6 +71,10 @@ class MEDIA_EXPORT FakeAudioInputStream ...@@ -71,6 +71,10 @@ class MEDIA_EXPORT FakeAudioInputStream
int frames_elapsed_; int frames_elapsed_;
scoped_ptr<media::AudioBus> audio_bus_; scoped_ptr<media::AudioBus> audio_bus_;
// Allows us to run tasks on the FakeAudioInputStream instance which are
// bound by its lifetime.
base::WeakPtrFactory<FakeAudioInputStream> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(FakeAudioInputStream); DISALLOW_COPY_AND_ASSIGN(FakeAudioInputStream);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment