summaryrefslogtreecommitdiffstats
path: root/media/audio/fake_audio_output_stream.cc
diff options
context:
space:
mode:
authordalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-18 22:12:05 +0000
committerdalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-18 22:12:05 +0000
commit2b392e59ab9a72858d224bad9e422fe40a696a69 (patch)
tree124296c1b0473baa88c55a66f95d22b3e4623f04 /media/audio/fake_audio_output_stream.cc
parentc9b6e6a5b77de034a13c5d26b9084c40bb0e74c7 (diff)
downloadchromium_src-2b392e59ab9a72858d224bad9e422fe40a696a69.zip
chromium_src-2b392e59ab9a72858d224bad9e422fe40a696a69.tar.gz
chromium_src-2b392e59ab9a72858d224bad9e422fe40a696a69.tar.bz2
Simulate an audio output stream when a real one isn't available.
Upgrades FakeAudioOutputStream to fake OnMoreData calls using a PostDelayedTask approach similar to NullAudioSink. This is necessary for playback of HTML5 videos when a real audio device is not present. I.e. over remote desktop w/ remote audio disabled on on some of the Buildbot machines (this should allow us to remove --disable-audio from many of our tests). This is a two fold change: 1. AudioOutputResampler will now request an AUDIO_FAKE device when invalid output parameters are provided. 2. AudioManagerBase will check for AUDIO_FAKE as it always has but will additionally check if there are any output devices and if not return a fake stream. 2 is necessary for HTML5 audio since it doesn't use the low latency output path. BUG=120749 TEST=unittests. HTML5/Flash video playback over Remote Desktop w/o Remote Audio works. Review URL: https://chromiumcodereview.appspot.com/10987087 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@162810 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio/fake_audio_output_stream.cc')
-rw-r--r--media/audio/fake_audio_output_stream.cc84
1 files changed, 48 insertions, 36 deletions
diff --git a/media/audio/fake_audio_output_stream.cc b/media/audio/fake_audio_output_stream.cc
index f09fe5d..fe03859 100644
--- a/media/audio/fake_audio_output_stream.cc
+++ b/media/audio/fake_audio_output_stream.cc
@@ -4,69 +4,81 @@
#include "media/audio/fake_audio_output_stream.h"
-#include "base/at_exit.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/logging.h"
#include "media/audio/audio_manager_base.h"
namespace media {
-FakeAudioOutputStream* FakeAudioOutputStream::current_fake_stream_ = NULL;
-
// static
AudioOutputStream* FakeAudioOutputStream::MakeFakeStream(
- AudioManagerBase* manager,
- const AudioParameters& params) {
- FakeAudioOutputStream* new_stream = new FakeAudioOutputStream(manager,
- params);
- DCHECK(current_fake_stream_ == NULL);
- current_fake_stream_ = new_stream;
- return new_stream;
+ AudioManagerBase* manager, const AudioParameters& params) {
+ return new FakeAudioOutputStream(manager, params);
}
-bool FakeAudioOutputStream::Open() {
- return true;
+FakeAudioOutputStream::FakeAudioOutputStream(AudioManagerBase* manager,
+ const AudioParameters& params)
+ : audio_manager_(manager),
+ callback_(NULL),
+ audio_bus_(AudioBus::Create(params)),
+ frames_per_millisecond_(
+ params.sample_rate() / static_cast<float>(
+ base::Time::kMillisecondsPerSecond)),
+ ALLOW_THIS_IN_INITIALIZER_LIST(weak_this_(this)) {
}
-// static
-FakeAudioOutputStream* FakeAudioOutputStream::GetCurrentFakeStream() {
- return current_fake_stream_;
+FakeAudioOutputStream::~FakeAudioOutputStream() {
+ DCHECK(!callback_);
+}
+
+bool FakeAudioOutputStream::Open() {
+ DCHECK(audio_manager_->GetMessageLoop()->BelongsToCurrentThread());
+ return true;
}
void FakeAudioOutputStream::Start(AudioSourceCallback* callback) {
+ DCHECK(audio_manager_->GetMessageLoop()->BelongsToCurrentThread());
callback_ = callback;
- audio_bus_->Zero();
- callback_->OnMoreData(audio_bus_.get(), AudioBuffersState(0, 0));
+ audio_manager_->GetMessageLoop()->PostTask(FROM_HERE, base::Bind(
+ &FakeAudioOutputStream::OnMoreDataTask, weak_this_.GetWeakPtr()));
}
void FakeAudioOutputStream::Stop() {
+ DCHECK(audio_manager_->GetMessageLoop()->BelongsToCurrentThread());
callback_ = NULL;
}
-void FakeAudioOutputStream::SetVolume(double volume) {
- volume_ = volume;
+void FakeAudioOutputStream::Close() {
+ DCHECK(!callback_);
+ DCHECK(audio_manager_->GetMessageLoop()->BelongsToCurrentThread());
+ weak_this_.InvalidateWeakPtrs();
+ audio_manager_->ReleaseOutputStream(this);
}
+void FakeAudioOutputStream::SetVolume(double volume) {};
+
void FakeAudioOutputStream::GetVolume(double* volume) {
- *volume = volume_;
-}
+ *volume = 0;
+};
-void FakeAudioOutputStream::Close() {
- closed_ = true;
- audio_manager_->ReleaseOutputStream(this);
-}
+void FakeAudioOutputStream::OnMoreDataTask() {
+ DCHECK(audio_manager_->GetMessageLoop()->BelongsToCurrentThread());
-FakeAudioOutputStream::FakeAudioOutputStream(AudioManagerBase* manager,
- const AudioParameters& params)
- : audio_manager_(manager),
- volume_(0),
- callback_(NULL),
- closed_(false) {
- audio_bus_ = AudioBus::Create(params);
-}
+ audio_bus_->Zero();
+ int frames_received = audio_bus_->frames();
+ if (callback_) {
+ frames_received = callback_->OnMoreData(
+ audio_bus_.get(), AudioBuffersState());
+ }
-FakeAudioOutputStream::~FakeAudioOutputStream() {
- if (current_fake_stream_ == this)
- current_fake_stream_ = NULL;
+ // Calculate our sleep duration for simulated playback. Sleep for at least
+ // one millisecond so we don't spin the CPU.
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE, base::Bind(
+ &FakeAudioOutputStream::OnMoreDataTask, weak_this_.GetWeakPtr()),
+ base::TimeDelta::FromMilliseconds(
+ std::max(1.0f, frames_received / frames_per_millisecond_)));
}
} // namespace media