summaryrefslogtreecommitdiffstats
path: root/media/audio/null_audio_sink.cc
diff options
context:
space:
mode:
authordalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-15 04:34:16 +0000
committerdalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-15 04:34:16 +0000
commit8754d953bfca98c6dcc0d716dd8408afe5199248 (patch)
treea397bfaf171848d4b4020d09318c2e49a7b0d2a8 /media/audio/null_audio_sink.cc
parentb8ad39b6f840b7cb91a6d86f101ed1671a7e009f (diff)
downloadchromium_src-8754d953bfca98c6dcc0d716dd8408afe5199248.zip
chromium_src-8754d953bfca98c6dcc0d716dd8408afe5199248.tar.gz
chromium_src-8754d953bfca98c6dcc0d716dd8408afe5199248.tar.bz2
Refactor FakeAudioOutputStream, NullAudioSink into FakeAudioConsumer.
We have two fake audio consumers: FakeAudioOutputStream on the browser side and NullAudioSink on the renderer side. At present we can't remove NullAudioSink since its used for PipelineIntegrationTests. This change collapses the common functionality between both consumers and as an added bonus replaces NullAudioSink's private thread in favor of sharing the MediaThread. BUG=none TEST=unit tests, remote desktop session w/o audio, --disable-audio. Review URL: https://chromiumcodereview.appspot.com/12334061 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@188251 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio/null_audio_sink.cc')
-rw-r--r--media/audio/null_audio_sink.cc129
1 files changed, 52 insertions, 77 deletions
diff --git a/media/audio/null_audio_sink.cc b/media/audio/null_audio_sink.cc
index c93ceb1..37d3ce0 100644
--- a/media/audio/null_audio_sink.cc
+++ b/media/audio/null_audio_sink.cc
@@ -5,30 +5,34 @@
#include "media/audio/null_audio_sink.h"
#include "base/bind.h"
+#include "base/message_loop_proxy.h"
#include "base/stringprintf.h"
#include "base/sys_byteorder.h"
-#include "base/threading/platform_thread.h"
+#include "media/audio/fake_audio_consumer.h"
namespace media {
-NullAudioSink::NullAudioSink()
+NullAudioSink::NullAudioSink(
+ const scoped_refptr<base::MessageLoopProxy>& message_loop)
: initialized_(false),
- playing_(false),
callback_(NULL),
- thread_("NullAudioThread"),
- hash_audio_for_testing_(false) {
+ hash_audio_for_testing_(false),
+ channels_(0),
+ message_loop_(message_loop) {
}
+NullAudioSink::~NullAudioSink() {}
+
void NullAudioSink::Initialize(const AudioParameters& params,
RenderCallback* callback) {
DCHECK(!initialized_);
- params_ = params;
- audio_bus_ = AudioBus::Create(params_);
+ fake_consumer_.reset(new FakeAudioConsumer(message_loop_, params));
if (hash_audio_for_testing_) {
- md5_channel_contexts_.reset(new base::MD5Context[params_.channels()]);
- for (int i = 0; i < params_.channels(); i++)
+ channels_ = params.channels();
+ md5_channel_contexts_.reset(new base::MD5Context[params.channels()]);
+ for (int i = 0; i < params.channels(); i++)
base::MD5Init(&md5_channel_contexts_[i]);
}
@@ -37,24 +41,27 @@ void NullAudioSink::Initialize(const AudioParameters& params,
}
void NullAudioSink::Start() {
- if (!thread_.Start())
- return;
-
- thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
- &NullAudioSink::FillBufferTask, this));
+ DCHECK(message_loop_->BelongsToCurrentThread());
}
void NullAudioSink::Stop() {
- SetPlaying(false);
- thread_.Stop();
+ DCHECK(message_loop_->BelongsToCurrentThread());
+
+ // Stop may be called at any time, so we have to check before stopping.
+ if (fake_consumer_)
+ fake_consumer_->Stop();
}
void NullAudioSink::Play() {
- SetPlaying(true);
+ DCHECK(message_loop_->BelongsToCurrentThread());
+ DCHECK(initialized_);
+ fake_consumer_->Start(base::Bind(
+ &NullAudioSink::CallRender, base::Unretained(this)));
}
void NullAudioSink::Pause(bool /* flush */) {
- SetPlaying(false);
+ DCHECK(message_loop_->BelongsToCurrentThread());
+ fake_consumer_->Stop();
}
bool NullAudioSink::SetVolume(double volume) {
@@ -62,54 +69,24 @@ bool NullAudioSink::SetVolume(double volume) {
return volume == 0.0;
}
-void NullAudioSink::SetPlaying(bool is_playing) {
- base::AutoLock auto_lock(lock_);
- playing_ = is_playing;
-}
+void NullAudioSink::CallRender(AudioBus* audio_bus) {
+ DCHECK(message_loop_->BelongsToCurrentThread());
-NullAudioSink::~NullAudioSink() {
- DCHECK(!thread_.IsRunning());
-}
+ int frames_received = callback_->Render(audio_bus, 0);
+ if (!hash_audio_for_testing_ || frames_received <= 0)
+ return;
-void NullAudioSink::FillBufferTask() {
- base::AutoLock auto_lock(lock_);
-
- base::TimeDelta delay;
- // Only consume buffers when actually playing.
- if (playing_) {
- int frames_received = callback_->Render(audio_bus_.get(), 0);
- int frames_per_millisecond =
- params_.sample_rate() / base::Time::kMillisecondsPerSecond;
-
- if (hash_audio_for_testing_ && frames_received > 0) {
- DCHECK_EQ(sizeof(float), sizeof(uint32));
- int channels = audio_bus_->channels();
- for (int channel_idx = 0; channel_idx < channels; ++channel_idx) {
- float* channel = audio_bus_->channel(channel_idx);
- for (int frame_idx = 0; frame_idx < frames_received; frame_idx++) {
- // Convert float to uint32 w/o conversion loss.
- uint32 frame = base::ByteSwapToLE32(
- bit_cast<uint32>(channel[frame_idx]));
- base::MD5Update(
- &md5_channel_contexts_[channel_idx], base::StringPiece(
- reinterpret_cast<char*>(&frame), sizeof(frame)));
- }
- }
+ DCHECK_EQ(sizeof(float), sizeof(uint32));
+ int channels = audio_bus->channels();
+ for (int channel_idx = 0; channel_idx < channels; ++channel_idx) {
+ float* channel = audio_bus->channel(channel_idx);
+ for (int frame_idx = 0; frame_idx < frames_received; frame_idx++) {
+ // Convert float to uint32 w/o conversion loss.
+ uint32 frame = base::ByteSwapToLE32(bit_cast<uint32>(channel[frame_idx]));
+ base::MD5Update(&md5_channel_contexts_[channel_idx], base::StringPiece(
+ reinterpret_cast<char*>(&frame), sizeof(frame)));
}
-
- // Calculate our sleep duration.
- delay = base::TimeDelta::FromMilliseconds(
- frames_received / frames_per_millisecond);
- } else {
- // If paused, sleep for 10 milliseconds before polling again.
- delay = base::TimeDelta::FromMilliseconds(10);
}
-
- // Sleep for at least one millisecond so we don't spin the CPU.
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- base::Bind(&NullAudioSink::FillBufferTask, this),
- std::max(delay, base::TimeDelta::FromMilliseconds(1)));
}
void NullAudioSink::StartAudioHashForTesting() {
@@ -120,24 +97,22 @@ void NullAudioSink::StartAudioHashForTesting() {
std::string NullAudioSink::GetAudioHashForTesting() {
DCHECK(hash_audio_for_testing_);
- // If initialize failed or was never called, ensure we return an empty hash.
- int channels = 1;
- if (!initialized_) {
- md5_channel_contexts_.reset(new base::MD5Context[1]);
- base::MD5Init(&md5_channel_contexts_[0]);
- } else {
- channels = audio_bus_->channels();
- }
-
- // Hash all channels into the first channel.
base::MD5Digest digest;
- for (int i = 1; i < channels; i++) {
- base::MD5Final(&digest, &md5_channel_contexts_[i]);
- base::MD5Update(&md5_channel_contexts_[0], base::StringPiece(
- reinterpret_cast<char*>(&digest), sizeof(base::MD5Digest)));
+ if (channels_ == 0) {
+ // If initialize failed or was never called, ensure we return an empty hash.
+ base::MD5Context context;
+ base::MD5Init(&context);
+ base::MD5Final(&digest, &context);
+ } else {
+ // Hash all channels into the first channel.
+ for (int i = 1; i < channels_; i++) {
+ base::MD5Final(&digest, &md5_channel_contexts_[i]);
+ base::MD5Update(&md5_channel_contexts_[0], base::StringPiece(
+ reinterpret_cast<char*>(&digest), sizeof(base::MD5Digest)));
+ }
+ base::MD5Final(&digest, &md5_channel_contexts_[0]);
}
- base::MD5Final(&digest, &md5_channel_contexts_[0]);
return base::MD5DigestToBase16(digest);
}