summaryrefslogtreecommitdiffstats
path: root/chrome/renderer/media/audio_renderer_impl.cc
diff options
context:
space:
mode:
authorhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-10 22:40:31 +0000
committerhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-10 22:40:31 +0000
commit8db216ee756d4e06fbd05676b045784da3a5928c (patch)
tree36b7bf2b42bf6ccb1fab70cfbe35dd29514c9cb7 /chrome/renderer/media/audio_renderer_impl.cc
parente00e0cc2284c3a8e0b74841ace6b9dad9bd1df94 (diff)
downloadchromium_src-8db216ee756d4e06fbd05676b045784da3a5928c.zip
chromium_src-8db216ee756d4e06fbd05676b045784da3a5928c.tar.gz
chromium_src-8db216ee756d4e06fbd05676b045784da3a5928c.tar.bz2
Implemented AudioRendererImpl in renderer process using API
provided by RenderView for accessing audio device in the browser using IPC, subclassing from media::AudioRendererBase for buffer filling. Review URL: http://codereview.chromium.org/28081 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@11392 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer/media/audio_renderer_impl.cc')
-rw-r--r--chrome/renderer/media/audio_renderer_impl.cc150
1 files changed, 130 insertions, 20 deletions
diff --git a/chrome/renderer/media/audio_renderer_impl.cc b/chrome/renderer/media/audio_renderer_impl.cc
index 9dbd392..5df76ba 100644
--- a/chrome/renderer/media/audio_renderer_impl.cc
+++ b/chrome/renderer/media/audio_renderer_impl.cc
@@ -3,50 +3,160 @@
// LICENSE file.
#include "chrome/renderer/media/audio_renderer_impl.h"
+#include "chrome/renderer/render_view.h"
+#include "chrome/renderer/render_thread.h"
+#include "chrome/renderer/webmediaplayer_delegate_impl.h"
+#include "media/base/filter_host.h"
+
+// We'll try to fill 4096 samples per buffer, which is roughly ~92ms of audio
+// data for a 44.1kHz audio source.
+static const size_t kSamplesPerBuffer = 4096;
AudioRendererImpl::AudioRendererImpl(WebMediaPlayerDelegateImpl* delegate)
- : delegate_(delegate) {
+ : AudioRendererBase(kDefaultMaxQueueSize),
+ delegate_(delegate),
+ stream_id_(0),
+ shared_memory_(NULL),
+ shared_memory_size_(0),
+ packet_requested_(false),
+ render_loop_(RenderThread::current()->message_loop()),
+ resource_release_event_(true, false) {
+ // TODO(hclam): do we need to move this method call to render thread?
+ delegate_->SetAudioRenderer(this);
}
AudioRendererImpl::~AudioRendererImpl() {
}
-void AudioRendererImpl::Stop() {
- // TODO(scherkus): implement Stop.
- NOTIMPLEMENTED();
+bool AudioRendererImpl::IsMediaFormatSupported(
+ const media::MediaFormat* media_format) {
+ int channels;
+ int sample_rate;
+ int sample_bits;
+ return ParseMediaFormat(media_format, &channels, &sample_rate, &sample_bits);
}
-bool AudioRendererImpl::Initialize(media::AudioDecoder* decoder) {
- // TODO(scherkus): implement Initialize.
- NOTIMPLEMENTED();
- return false;
+bool AudioRendererImpl::OnInitialize(const media::MediaFormat* media_format) {
+ // Parse integer values in MediaFormat.
+ int channels;
+ int sample_rate;
+ int sample_bits;
+ if (!ParseMediaFormat(media_format, &channels, &sample_rate, &sample_bits)) {
+ return false;
+ }
+
+ // Create the audio output stream in browser process.
+ size_t packet_size = kSamplesPerBuffer * channels * sample_bits / 8;
+ render_loop_->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &AudioRendererImpl::OnCreateAudioStream,
+ AudioManager::AUDIO_PCM_LINEAR, channels, sample_rate, sample_bits,
+ packet_size));
+ return true;
}
-void AudioRendererImpl::SetVolume(float volume) {
- // TODO(scherkus): implement SetVolume.
- NOTIMPLEMENTED();
+void AudioRendererImpl::OnStop() {
+ if (!resource_release_event_.IsSignaled()) {
+ render_loop_->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &AudioRendererImpl::ReleaseRendererResources));
+ resource_release_event_.Wait();
+ }
}
-bool AudioRendererImpl::IsMediaFormatSupported(
- const media::MediaFormat* format) {
- // TODO(hclam): check the format correct.
- return true;
+void AudioRendererImpl::OnAssignment(media::Buffer* buffer_in) {
+ // Use the base class to queue the buffer.
+ AudioRendererBase::OnAssignment(buffer_in);
+ // Post a task to render thread to notify a packet reception.
+ render_loop_->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &AudioRendererImpl::OnNotifyAudioPacketReady));
}
-void AudioRendererImpl::OnRequestPacket() {
- // TODO(hclam): implement this.
+void AudioRendererImpl::SetPlaybackRate(float rate) {
+ // TODO(hclam): handle playback rates not equal to 1.0.
+ if (rate == 1.0f) {
+ // TODO(hclam): what should I do here? OnCreated has fired StartAudioStream
+ // in the browser process, it seems there's nothing to do here.
+ } else {
+ NOTIMPLEMENTED();
+ }
+}
+
+void AudioRendererImpl::SetVolume(float volume) {
+ // TODO(hclam): change this to multichannel if possible.
+ render_loop_->PostTask(FROM_HERE,
+ NewRunnableMethod(
+ this, &AudioRendererImpl::OnSetAudioVolume, volume, volume));
}
void AudioRendererImpl::OnCreated(base::SharedMemoryHandle handle,
size_t length) {
- // TODO(hclam): implement this.
+ shared_memory_.reset(new base::SharedMemory(handle, false));
+ shared_memory_size_ = length;
+ // TODO(hclam): is there any better place to do this?
+ OnStartAudioStream();
+}
+
+void AudioRendererImpl::OnRequestPacket() {
+ packet_requested_ = true;
}
void AudioRendererImpl::OnStateChanged(AudioOutputStream::State state,
int info) {
- // TODO(hclam): implement this.
+ switch (state) {
+ case AudioOutputStream::STATE_ERROR:
+ host_->Error(media::PIPELINE_ERROR_AUDIO_HARDWARE);
+ break;
+ // TODO(hclam): handle these events.
+ case AudioOutputStream::STATE_STARTED:
+ case AudioOutputStream::STATE_PAUSED:
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
}
void AudioRendererImpl::OnVolume(double left, double right) {
- // TODO(hclam): implement this.
+ // TODO(hclam): decide whether we need to report the current volume to
+ // pipeline.
+}
+
+void AudioRendererImpl::ReleaseRendererResources() {
+ OnCloseAudioStream();
+ resource_release_event_.Signal();
+}
+
+void AudioRendererImpl::OnCreateAudioStream(
+ AudioManager::Format format, int channels, int sample_rate,
+ int bits_per_sample, size_t packet_size) {
+ stream_id_ = delegate_->view()->CreateAudioStream(
+ this, format, channels, sample_rate, bits_per_sample, packet_size);
+}
+
+void AudioRendererImpl::OnStartAudioStream() {
+ delegate_->view()->StartAudioStream(stream_id_);
+}
+
+void AudioRendererImpl::OnCloseAudioStream() {
+ // Unregister ourself from RenderView, we will not be called anymore.
+ delegate_->view()->CloseAudioStream(stream_id_);
+}
+
+void AudioRendererImpl::OnSetAudioVolume(double left, double right) {
+ delegate_->view()->SetAudioVolume(stream_id_, left, right);
+}
+
+void AudioRendererImpl::OnNotifyAudioPacketReady() {
+ if (packet_requested_) {
+ DCHECK(shared_memory_.get());
+ // Fill into the shared memory.
+ size_t filled = FillBuffer(static_cast<uint8*>(shared_memory_->memory()),
+ shared_memory_size_);
+ packet_requested_ = false;
+ // Then tell browser process we are done filling into the buffer.
+ delegate_->view()->NotifyAudioPacketReady(stream_id_, filled);
+ }
+}
+
+const media::MediaFormat* AudioRendererImpl::GetMediaFormat() {
+ return &media_format_;
}