summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/chrome.gyp12
-rw-r--r--chrome/renderer/audio_message_filter.cc109
-rw-r--r--chrome/renderer/audio_message_filter.h84
-rw-r--r--chrome/renderer/media/audio_renderer_impl.cc151
-rw-r--r--chrome/renderer/media/audio_renderer_impl.h134
-rw-r--r--chrome/renderer/render_view.cc105
-rw-r--r--chrome/renderer/render_view.h40
-rw-r--r--chrome/renderer/renderer.vcproj8
-rw-r--r--chrome/renderer/webmediaplayer_delegate_impl.cc16
-rw-r--r--chrome/renderer/webmediaplayer_delegate_impl.h4
10 files changed, 390 insertions, 273 deletions
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 1ccb9d8..8b869f9 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -1220,6 +1220,8 @@
'browser/views/options/content_page_view.h',
'browser/views/options/cookies_view.cc',
'browser/views/options/cookies_view.h',
+ 'browser/views/options/exceptions_page_view.cc',
+ 'browser/views/options/exceptions_page_view.h',
'browser/views/options/fonts_languages_window_view.cc',
'browser/views/options/fonts_languages_window_view.h',
'browser/views/options/fonts_page_view.cc',
@@ -1235,12 +1237,12 @@
'browser/views/options/options_page_view.cc',
'browser/views/options/options_page_view.h',
'browser/views/options/options_window_view.cc',
+ 'browser/views/options/passwords_exceptions_window_view.cc',
+ 'browser/views/options/passwords_exceptions_window_view.h',
+ 'browser/views/options/passwords_page_view.cc',
+ 'browser/views/options/passwords_page_view.h',
'browser/views/page_info_window.cc',
'browser/views/page_info_window.h',
- 'browser/views/password_manager_exceptions_view.cc',
- 'browser/views/password_manager_exceptions_view.h',
- 'browser/views/password_manager_view.cc',
- 'browser/views/password_manager_view.h',
'browser/views/repost_form_warning_view.cc',
'browser/views/repost_form_warning_view.h',
'browser/views/restart_message_box.cc',
@@ -1459,6 +1461,8 @@
'renderer/net/render_dns_queue.h',
'renderer/about_handler.cc',
'renderer/about_handler.h',
+ 'renderer/audio_message_filter.cc',
+ 'renderer/audio_message_filter.h',
'renderer/debug_message_handler.cc',
'renderer/debug_message_handler.h',
'renderer/devtools_agent.cc',
diff --git a/chrome/renderer/audio_message_filter.cc b/chrome/renderer/audio_message_filter.cc
new file mode 100644
index 0000000..6e22bbd
--- /dev/null
+++ b/chrome/renderer/audio_message_filter.cc
@@ -0,0 +1,109 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/message_loop.h"
+#include "chrome/common/render_messages.h"
+#include "chrome/renderer/audio_message_filter.h"
+
+AudioMessageFilter::AudioMessageFilter(int32 route_id)
+ : channel_(NULL),
+ route_id_(route_id),
+ message_loop_(NULL) {
+}
+
+AudioMessageFilter::~AudioMessageFilter() {
+}
+
+// Called on the IPC thread.
+bool AudioMessageFilter::Send(IPC::Message* message) {
+ if (!channel_) {
+ delete message;
+ return false;
+ }
+ message->set_routing_id(route_id_);
+ return channel_->Send(message);
+}
+
+bool AudioMessageFilter::OnMessageReceived(const IPC::Message& message) {
+ if (message.routing_id() != route_id_)
+ return false;
+
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(AudioMessageFilter, message)
+ IPC_MESSAGE_HANDLER(ViewMsg_RequestAudioPacket, OnRequestPacket)
+ IPC_MESSAGE_HANDLER(ViewMsg_NotifyAudioStreamCreated, OnStreamCreated)
+ IPC_MESSAGE_HANDLER(ViewMsg_NotifyAudioStreamStateChanged,
+ OnStreamStateChanged)
+ IPC_MESSAGE_HANDLER(ViewMsg_NotifyAudioStreamVolume, OnStreamVolume)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void AudioMessageFilter::OnFilterAdded(IPC::Channel* channel) {
+ // Captures the message loop for IPC.
+ message_loop_ = MessageLoop::current();
+ channel_ = channel;
+}
+
+void AudioMessageFilter::OnFilterRemoved() {
+ channel_ = NULL;
+}
+
+void AudioMessageFilter::OnChannelClosing() {
+ channel_ = NULL;
+}
+
+void AudioMessageFilter::OnRequestPacket(int stream_id) {
+ Delegate* delegate = delegates_.Lookup(stream_id);
+ if (!delegate) {
+ DLOG(WARNING) << "Got audio packet request for a non-existent or removed"
+ " audio renderer.";
+ return;
+ }
+ delegate->OnRequestPacket();
+}
+
+void AudioMessageFilter::OnStreamCreated(int stream_id,
+ base::SharedMemoryHandle handle,
+ int length) {
+ Delegate* delegate = delegates_.Lookup(stream_id);
+ if (!delegate) {
+ DLOG(WARNING) << "Got audio stream event for a non-existent or removed"
+ " audio renderer.";
+ return;
+ }
+ delegate->OnCreated(handle, length);
+}
+
+void AudioMessageFilter::OnStreamStateChanged(int stream_id,
+ AudioOutputStream::State state,
+ int info) {
+ Delegate* delegate = delegates_.Lookup(stream_id);
+ if (!delegate) {
+ DLOG(WARNING) << "Got audio stream event for a non-existent or removed"
+ " audio renderer.";
+ return;
+ }
+ delegate->OnStateChanged(state, info);
+}
+
+void AudioMessageFilter::OnStreamVolume(int stream_id,
+ double left, double right) {
+ Delegate* delegate = delegates_.Lookup(stream_id);
+ if (!delegate) {
+ DLOG(WARNING) << "Got audio stream event for a non-existent or removed"
+ " audio renderer.";
+ return;
+ }
+ delegate->OnVolume(left, right);
+}
+
+int32 AudioMessageFilter::AddDelegate(Delegate* delegate) {
+ return delegates_.Add(delegate);
+}
+
+void AudioMessageFilter::RemoveDelegate(int32 id) {
+ delegates_.Remove(id);
+}
diff --git a/chrome/renderer/audio_message_filter.h b/chrome/renderer/audio_message_filter.h
new file mode 100644
index 0000000..8514c1e
--- /dev/null
+++ b/chrome/renderer/audio_message_filter.h
@@ -0,0 +1,84 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// MessageFilter that handles audio messages and delegates them to audio
+// renderers. Created on render thread, AudioMessageFilter is operated on
+// IO thread (main thread of render process), it intercepts audio messages
+// and process them on IO thread since these messages are time critical.
+
+#ifndef CHROME_RENDERER_AUDIO_MESSAGE_FILTER_H_
+#define CHROME_RENDERER_AUDIO_MESSAGE_FILTER_H_
+
+#include "base/id_map.h"
+#include "base/shared_memory.h"
+#include "chrome/common/ipc_channel_proxy.h"
+#include "media/audio/audio_output.h"
+
+class AudioMessageFilter : public IPC::ChannelProxy::MessageFilter {
+ public:
+ class Delegate {
+ public:
+ // Called when an audio packet is requested from the browser process.
+ virtual void OnRequestPacket() = 0;
+
+ // Called when state of an audio stream has changed in the browser process.
+ virtual void OnStateChanged(AudioOutputStream::State state, int info) = 0;
+
+ // Called when an audio stream has been created in the browser process.
+ virtual void OnCreated(base::SharedMemoryHandle handle, size_t length) = 0;
+
+ // Called when notification of stream volume is received from the browser
+ // process.
+ virtual void OnVolume(double left, double right) = 0;
+ };
+
+ AudioMessageFilter(int32 route_id);
+ ~AudioMessageFilter();
+
+ // Add a delegate to the map and return id of the entry.
+ int32 AddDelegate(Delegate* delegate);
+
+ // Remove a delegate referenced by |id| from the map.
+ void RemoveDelegate(int32 id);
+
+ // Sends an IPC message using |channel_|.
+ bool Send(IPC::Message* message);
+
+ MessageLoop* message_loop() { return message_loop_; }
+
+ private:
+ // IPC::ChannelProxy::MessageFilter override. Called on IO thread.
+ virtual bool OnMessageReceived(const IPC::Message& message);
+ virtual void OnFilterAdded(IPC::Channel* channel);
+ virtual void OnFilterRemoved();
+ virtual void OnChannelClosing();
+
+ // Received when browser process wants more audio packet.
+ void OnRequestPacket(int stream_id);
+
+ // Received when browser process has created an audio output stream.
+ void OnStreamCreated(int stream_id, base::SharedMemoryHandle handle,
+ int length);
+
+ // Received when internal state of browser process' audio output device has
+ // changed.
+ void OnStreamStateChanged(int stream_id, AudioOutputStream::State state,
+ int info);
+
+ // Notification of volume property of an audio output stream.
+ void OnStreamVolume(int stream_id, double left, double right);
+
+ // A map of stream ids to delegates.
+ IDMap<Delegate> delegates_;
+
+ IPC::Channel* channel_;
+
+ int32 route_id_;
+
+ MessageLoop* message_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(AudioMessageFilter);
+};
+
+#endif // CHROME_RENDERER_AUDIO_MESSAGE_FITLER_H_
diff --git a/chrome/renderer/media/audio_renderer_impl.cc b/chrome/renderer/media/audio_renderer_impl.cc
index a0b6ae3..4f0627c 100644
--- a/chrome/renderer/media/audio_renderer_impl.cc
+++ b/chrome/renderer/media/audio_renderer_impl.cc
@@ -2,32 +2,42 @@
// source code is governed by a BSD-style license that can be found in the
// LICENSE file.
+#include "chrome/common/render_messages.h"
+#include "chrome/renderer/audio_message_filter.h"
#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
+// We'll try to fill 8192 samples per buffer, which is roughly ~194ms of audio
// data for a 44.1kHz audio source.
-static const size_t kSamplesPerBuffer = 4096;
+static const size_t kSamplesPerBuffer = 8192;
-AudioRendererImpl::AudioRendererImpl(WebMediaPlayerDelegateImpl* delegate)
+AudioRendererImpl::AudioRendererImpl(AudioMessageFilter* filter)
: AudioRendererBase(kDefaultMaxQueueSize),
- delegate_(delegate),
+ filter_(filter),
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);
+ io_loop_(filter->message_loop()),
+ stopped_(false),
+ packet_request_event_(true, false) {
+ DCHECK(io_loop_);
}
AudioRendererImpl::~AudioRendererImpl() {
}
+bool AudioRendererImpl::HasStopped() {
+ AutoLock auto_lock(lock_);
+ return stopped_;
+}
+
+void AudioRendererImpl::SignalStop() {
+ AutoLock auto_lock(lock_);
+ stopped_ = true;
+}
+
bool AudioRendererImpl::IsMediaFormatSupported(
const media::MediaFormat& media_format) {
int channels;
@@ -47,32 +57,37 @@ bool AudioRendererImpl::OnInitialize(const media::MediaFormat& media_format) {
// 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,
+ io_loop_->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &AudioRendererImpl::OnCreateStream,
AudioManager::AUDIO_PCM_LINEAR, channels, sample_rate, sample_bits,
packet_size));
return true;
}
void AudioRendererImpl::OnStop() {
- delegate_->SetAudioRenderer(NULL);
- if (!resource_release_event_.IsSignaled()) {
- render_loop_->PostTask(FROM_HERE,
- NewRunnableMethod(this,
- &AudioRendererImpl::ReleaseResources, false));
- resource_release_event_.Wait();
- }
+ if (HasStopped())
+ return;
+
+ SignalStop();
+ io_loop_->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &AudioRendererImpl::OnDestroy));
}
void AudioRendererImpl::OnReadComplete(media::Buffer* buffer_in) {
+ if (HasStopped())
+ return;
+
// Use the base class to queue the buffer.
AudioRendererBase::OnReadComplete(buffer_in);
// Post a task to render thread to notify a packet reception.
- render_loop_->PostTask(FROM_HERE,
- NewRunnableMethod(this, &AudioRendererImpl::OnNotifyAudioPacketReady));
+ io_loop_->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &AudioRendererImpl::OnNotifyPacketReady));
}
void AudioRendererImpl::SetPlaybackRate(float rate) {
+ if (HasStopped())
+ return;
+
// 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
@@ -83,30 +98,45 @@ void AudioRendererImpl::SetPlaybackRate(float rate) {
}
void AudioRendererImpl::SetVolume(float volume) {
+ if (HasStopped())
+ return;
+
// TODO(hclam): change this to multichannel if possible.
- render_loop_->PostTask(FROM_HERE,
+ io_loop_->PostTask(FROM_HERE,
NewRunnableMethod(
- this, &AudioRendererImpl::OnSetAudioVolume, volume, volume));
+ this, &AudioRendererImpl::OnSetVolume, volume, volume));
}
void AudioRendererImpl::OnCreated(base::SharedMemoryHandle handle,
size_t length) {
+ DCHECK(MessageLoop::current() == io_loop_);
+
+ if (HasStopped())
+ return;
+
shared_memory_.reset(new base::SharedMemory(handle, false));
shared_memory_->Map(length);
shared_memory_size_ = length;
- // TODO(hclam): is there any better place to do this?
- OnStartAudioStream();
+
+ filter_->Send(new ViewHostMsg_StartAudioStream(0, stream_id_));
}
void AudioRendererImpl::OnRequestPacket() {
- packet_requested_ = true;
- // Post a task to render thread and try to grab a packet for sending back.
- render_loop_->PostTask(FROM_HERE,
- NewRunnableMethod(this, &AudioRendererImpl::OnNotifyAudioPacketReady));
+ DCHECK(MessageLoop::current() == io_loop_);
+
+ packet_request_event_.Signal();
+
+ // Try to fill in the fulfil the packet request.
+ OnNotifyPacketReady();
}
void AudioRendererImpl::OnStateChanged(AudioOutputStream::State state,
int info) {
+ DCHECK(MessageLoop::current() == io_loop_);
+
+ if (HasStopped())
+ return;
+
switch (state) {
case AudioOutputStream::STATE_ERROR:
host_->Error(media::PIPELINE_ERROR_AUDIO_HARDWARE);
@@ -122,46 +152,67 @@ void AudioRendererImpl::OnStateChanged(AudioOutputStream::State state,
}
void AudioRendererImpl::OnVolume(double left, double right) {
+ if (HasStopped())
+ return;
+
// TODO(hclam): decide whether we need to report the current volume to
// pipeline.
}
-void AudioRendererImpl::ReleaseResources(bool is_render_thread_dying) {
- if (!is_render_thread_dying)
- OnCloseAudioStream();
- resource_release_event_.Signal();
-}
-
-void AudioRendererImpl::OnCreateAudioStream(
+void AudioRendererImpl::OnCreateStream(
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);
-}
+ DCHECK(MessageLoop::current() == io_loop_);
+
+ if (HasStopped())
+ return;
-void AudioRendererImpl::OnStartAudioStream() {
- delegate_->view()->StartAudioStream(stream_id_);
+ // Make sure we don't call create more than once.
+ DCHECK_EQ(0, stream_id_);
+ stream_id_ = filter_->AddDelegate(this);
+
+ ViewHostMsg_Audio_CreateStream params;
+ params.format = format;
+ params.channels = channels;
+ params.sample_rate = sample_rate;
+ params.bits_per_sample = bits_per_sample;
+ params.packet_size = packet_size;
+
+ filter_->Send(new ViewHostMsg_CreateAudioStream(0, stream_id_, params));
}
-void AudioRendererImpl::OnCloseAudioStream() {
- // Unregister ourself from RenderView, we will not be called anymore.
- delegate_->view()->CloseAudioStream(stream_id_);
+void AudioRendererImpl::OnDestroy() {
+ DCHECK(MessageLoop::current() == io_loop_);
+
+ filter_->RemoveDelegate(stream_id_);
+ filter_->Send(new ViewHostMsg_CloseAudioStream(0, stream_id_));
}
-void AudioRendererImpl::OnSetAudioVolume(double left, double right) {
- delegate_->view()->SetAudioVolume(stream_id_, left, right);
+void AudioRendererImpl::OnSetVolume(double left, double right) {
+ DCHECK(MessageLoop::current() == io_loop_);
+
+ if (HasStopped())
+ return;
+
+ filter_->Send(new ViewHostMsg_SetAudioVolume(0, stream_id_, left, right));
}
-void AudioRendererImpl::OnNotifyAudioPacketReady() {
- if (packet_requested_) {
+void AudioRendererImpl::OnNotifyPacketReady() {
+ DCHECK(MessageLoop::current() == io_loop_);
+
+ if (HasStopped())
+ return;
+
+ if (packet_request_event_.IsSignaled()) {
DCHECK(shared_memory_.get());
// Fill into the shared memory.
size_t filled = FillBuffer(static_cast<uint8*>(shared_memory_->memory()),
shared_memory_size_);
if (filled > 0) {
- packet_requested_ = false;
+ packet_request_event_.Reset();
// Then tell browser process we are done filling into the buffer.
- delegate_->view()->NotifyAudioPacketReady(stream_id_, filled);
+ filter_->Send(
+ new ViewHostMsg_NotifyAudioPacketReady(0, stream_id_, filled));
}
}
}
diff --git a/chrome/renderer/media/audio_renderer_impl.h b/chrome/renderer/media/audio_renderer_impl.h
index 6945f8a..3628e44 100644
--- a/chrome/renderer/media/audio_renderer_impl.h
+++ b/chrome/renderer/media/audio_renderer_impl.h
@@ -7,27 +7,27 @@
//
// Relationship of classes.
//
-// AudioRendererHost AudioRendererImpl
-// ^ ^
-// | |
-// v IPC v
-// ResourceMessageFilter <---------> RenderView
+// AudioRendererHost AudioRendererImpl
+// ^ ^
+// | |
+// v IPC v
+// ResourceMessageFilter <---------> AudioMessageFilter
//
// Implementation of interface with audio device is in AudioRendererHost and
// it provides services and entry points in ResourceMessageFilter, allowing
-// usage of IPC calls to interact with audio device. RenderView acts as a portal
-// for IPC calls and does no more than delegation.
+// usage of IPC calls to interact with audio device. AudioMessageFilter acts
+// as a portal for IPC calls and does no more than delegation.
//
// Transportation of audio buffer is done by using shared memory, after
-// OnCreateAudioStream is executed, OnCreated would be called along with a
+// OnCreateStream is executed, OnCreated would be called along with a
// SharedMemoryHandle upon successful creation of audio output stream in the
// browser process. The same piece of shared memory would be used during the
// lifetime of this unit.
//
// This class lives inside three threads during it's lifetime, namely:
-// 1. Render thread
-// The thread within which this class is constructed and destroyed,
-// interfacing with RenderView should only happen here.
+// 1. IO thread.
+// The thread within which this class receives all the IPC messages and
+// IPC communications can only happen in this thread.
// 2. Pipeline thread
// Initialization of filter and proper stopping of filters happens here.
// Properties of this filter is also set in this thread.
@@ -39,32 +39,33 @@
// Render thread
// +-- CreateFactory()
// | Helper method for construction this class.
-// |-- IsMetidFormatSupported()
-// | Helper method to identify media formats accepted by this class for
-// | construction.
-// |-- OnCreateAudioStream()
-// | Calls RenderView::CreateAudioStream().
-// |-- OnStartAudioStream()
-// | Calls RenderView::StartAudioStream().
-// |-- OnCloseAudioStream()
-// | Calls RenderView::CloseAudioStream().
-// |-- OnSetAudioVolume()
-// | Calls RenderView::SetAudioVolume().
-// |-- OnNotifyAudioPacketReady
-// | Calls RenderView::NotifyAudioPacketReady().
+// \-- IsMediaFormatSupported()
+// Helper method to identify media formats accepted by this class for
+// construction.
+//
+// IO thread (Main thread in render process)
+// +-- OnCreateStream()
+// | Sends an IPC message to browser to create audio output stream and
+// | register this object with AudioMessageFilter.
+// |-- OnSetVolume()
+// | Sends an IPC message to browser to set volume.
+// |-- OnNotifyPacketReady
+// | Try to fill the shared memory with decoded audio packet and sends IPC
+// | messages to browser if packet is ready.
// |-- OnRequestPacket()
-// | Called from RenderView when an audio packet requested is received
-// | from browser process.
+// | Called from AudioMessageFilter when an audio packet requested is
+// | received from browser process.
// |-- OnStateChanged()
-// | Called from RenderView upon state change of the audio output stream
-// | in the browser process. Error of the output stream is reported here.
+// | Called from AudioMessageFilter upon state change of the audio output
+// | stream in the browser process. Error of the stream is reported here.
// |-- OnCreated()
-// | Called from RenderView upon successful creation of audio output stream
-// | in the browser process, called along with a SharedMemoryHandle.
+// | Called from AudioMessageFilter upon successful creation of audio output
+// | stream in the browser process, called along with a SharedMemoryHandle.
// |-- OnVolume()
-// | Called from RenderView about the volume of the audio output stream.
-// \-- ReleaseResource()
-// Release resources that live inside render thread.
+// | Called from AudioMessageFilter about the volume of the audio output
+// | stream.
+// \-- OnDestroy()
+// Release resources that live inside io thread.
//
// Pipeline thread
// +-- AudioRendererImpl()
@@ -90,38 +91,35 @@
#ifndef CHROME_RENDERER_MEDIA_AUDIO_RENDERER_IMPL_H_
#define CHROME_RENDERER_MEDIA_AUDIO_RENDERER_IMPL_H_
+#include "base/lock.h"
#include "base/shared_memory.h"
#include "base/waitable_event.h"
+#include "chrome/renderer/audio_message_filter.h"
#include "media/audio/audio_output.h"
#include "media/base/factory.h"
#include "media/base/filters.h"
#include "media/filters/audio_renderer_base.h"
-class WebMediaPlayerDelegateImpl;
+class AudioMessageFilter;
-class AudioRendererImpl : public media::AudioRendererBase {
+class AudioRendererImpl : public media::AudioRendererBase,
+ public AudioMessageFilter::Delegate {
public:
// Methods called on render thread ------------------------------------------
// Methods called during construction.
- static media::FilterFactory* CreateFactory(
- WebMediaPlayerDelegateImpl* delegate) {
+ static media::FilterFactory* CreateFactory(AudioMessageFilter* filter) {
return new media::FilterFactoryImpl1<AudioRendererImpl,
- WebMediaPlayerDelegateImpl*>(delegate);
+ AudioMessageFilter*>(filter);
}
static bool IsMediaFormatSupported(const media::MediaFormat& format);
- // Methods call from RenderView when audio related IPC messages are received
- // from browser process.
+ // Methods called on IO thread ----------------------------------------------
+ // AudioMessageFilter::Delegate methods, called by AudioMessageFilter.
void OnRequestPacket();
void OnStateChanged(AudioOutputStream::State state, int info);
void OnCreated(base::SharedMemoryHandle handle, size_t length);
void OnVolume(double left, double right);
- // Release resources that lives in renderer thread, i.e. audio output streams.
- // |render_thread_is_dying| tells us if render thread is being destroyed,
- // if true it's not safe to access any object that lives inside render thread.
- void ReleaseResources(bool render_thread_is_dying);
-
// Methods called on pipeline thread ----------------------------------------
// media::MediaFilter implementation.
virtual void SetPlaybackRate(float rate);
@@ -140,25 +138,26 @@ class AudioRendererImpl : public media::AudioRendererBase {
private:
friend class media::FilterFactoryImpl1<AudioRendererImpl,
- WebMediaPlayerDelegateImpl*>;
+ AudioMessageFilter*>;
- explicit AudioRendererImpl(WebMediaPlayerDelegateImpl* delegate);
+ explicit AudioRendererImpl(AudioMessageFilter* filter);
virtual ~AudioRendererImpl();
- // Methods call on render thread --------------------------------------------
- // The following methods are tasks posted on the render thread that needs to
- // be executed on that thread. They interact with WebMediaPlayerDelegateImpl
- // and the containing RenderView, because method calls to RenderView must be
- // executed on render thread.
- void OnCreateAudioStream(AudioManager::Format format, int channels,
- int sample_rate, int bits_per_sample,
- size_t packet_size);
- void OnStartAudioStream();
- void OnCloseAudioStream();
- void OnSetAudioVolume(double left, double right);
- void OnNotifyAudioPacketReady();
-
- WebMediaPlayerDelegateImpl* delegate_;
+ bool HasStopped();
+ void SignalStop();
+
+ // Methods call on IO thread ------------------------------------------------
+ // The following methods are tasks posted on the IO thread that needs to
+ // be executed on that thread. They interact with AudioMessageFilter and
+ // sends IPC messages on that thread.
+ void OnCreateStream(AudioManager::Format format, int channels,
+ int sample_rate, int bits_per_sample,
+ size_t packet_size);
+ void OnSetVolume(double left, double right);
+ void OnNotifyPacketReady();
+ void OnDestroy();
+
+ scoped_refptr<AudioMessageFilter> filter_;
// ID of the stream created in the browser process.
int32 stream_id_;
@@ -167,15 +166,12 @@ class AudioRendererImpl : public media::AudioRendererBase {
scoped_ptr<base::SharedMemory> shared_memory_;
size_t shared_memory_size_;
- // Flag that tells whether we have any unfulfilled packet request.
- bool packet_requested_;
-
- // Message loop for the render thread, it's the message loop where this class
- // is constructed.
- MessageLoop* render_loop_;
+ // Message loop for the io thread.
+ MessageLoop* io_loop_;
- // Event for releasing resources that live in render thread.
- base::WaitableEvent resource_release_event_;
+ Lock lock_;
+ bool stopped_;
+ base::WaitableEvent packet_request_event_;
DISALLOW_COPY_AND_ASSIGN(AudioRendererImpl);
};
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 967e2a1..f5ca189 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -28,6 +28,7 @@
#include "chrome/common/thumbnail_score.h"
#include "chrome/common/url_constants.h"
#include "chrome/renderer/about_handler.h"
+#include "chrome/renderer/audio_message_filter.h"
#include "chrome/renderer/debug_message_handler.h"
#include "chrome/renderer/devtools_agent.h"
#include "chrome/renderer/devtools_agent_filter.h"
@@ -219,6 +220,7 @@ RenderView::~RenderView() {
render_thread_->RemoveFilter(debug_message_handler_);
if (devtools_agent_filter_.get())
render_thread_->RemoveFilter(devtools_agent_filter_);
+ render_thread_->RemoveFilter(audio_message_filter_);
#ifdef CHROME_PERSONALIZATION
Personalization::CleanupRendererPersonalization(personalization_);
@@ -355,6 +357,9 @@ void RenderView::Init(gfx::NativeViewId parent_hwnd,
render_thread_->AddFilter(debug_message_handler_);
if (dev_tools_enabled)
render_thread_->AddFilter(devtools_agent_filter_);
+
+ audio_message_filter_ = new AudioMessageFilter(routing_id_);
+ render_thread_->AddFilter(audio_message_filter_);
}
void RenderView::OnMessageReceived(const IPC::Message& message) {
@@ -445,11 +450,6 @@ void RenderView::OnMessageReceived(const IPC::Message& message) {
OnReceivedAutofillSuggestions)
IPC_MESSAGE_HANDLER(ViewMsg_PopupNotificationVisiblityChanged,
OnPopupNotificationVisiblityChanged)
- IPC_MESSAGE_HANDLER(ViewMsg_RequestAudioPacket, OnRequestAudioPacket)
- IPC_MESSAGE_HANDLER(ViewMsg_NotifyAudioStreamCreated, OnAudioStreamCreated)
- IPC_MESSAGE_HANDLER(ViewMsg_NotifyAudioStreamStateChanged,
- OnAudioStreamStateChanged)
- IPC_MESSAGE_HANDLER(ViewMsg_NotifyAudioStreamVolume, OnAudioStreamVolume)
IPC_MESSAGE_HANDLER(ViewMsg_MoveOrResizeStarted, OnMoveOrResizeStarted)
IPC_MESSAGE_HANDLER(ViewMsg_ExtensionResponse, OnExtensionResponse)
IPC_MESSAGE_HANDLER(ViewMsg_ClearFocusedNode, OnClearFocusedNode)
@@ -2937,106 +2937,11 @@ MessageLoop* RenderView::GetMessageLoopForIO() {
return NULL;
}
-void RenderView::OnRequestAudioPacket(int stream_id) {
- AudioRendererImpl* audio_renderer = audio_renderers_.Lookup(stream_id);
- if (!audio_renderer) {
- // It is possible that AudioRendererImpl is un-registered but we still
- // receives packet requests here, because of closing a stream is not a
- // synchronous operation with the browser process.
- return;
- }
- audio_renderer->OnRequestPacket();
-}
-
-void RenderView::OnAudioStreamCreated(
- int stream_id, base::SharedMemoryHandle handle, int length) {
- AudioRendererImpl* audio_renderer = audio_renderers_.Lookup(stream_id);
- if (!audio_renderer) {
- return;
- }
- audio_renderer->OnCreated(handle, length);
-}
-
-void RenderView::OnAudioStreamStateChanged(
- int stream_id, AudioOutputStream::State state, int info) {
- AudioRendererImpl* audio_renderer = audio_renderers_.Lookup(stream_id);
- if (!audio_renderer) {
- return;
- }
- audio_renderer->OnStateChanged(state, info);
-}
-
-void RenderView::OnAudioStreamVolume(int stream_id, double left, double right) {
- AudioRendererImpl* audio_renderer = audio_renderers_.Lookup(stream_id);
- if (!audio_renderer) {
- return;
- }
- audio_renderer->OnVolume(left, right);
-}
-
void RenderView::OnMoveOrResizeStarted() {
if (webview())
webview()->HideAutofillPopup();
}
-int32 RenderView::CreateAudioStream(AudioRendererImpl* audio_renderer,
- AudioManager::Format format, int channels,
- int sample_rate, int bits_per_sample,
- size_t packet_size) {
- DCHECK(RenderThread::current()->message_loop() == MessageLoop::current());
- // Loop through the map and make sure there's no renderer already in the map.
- for (IDMap<AudioRendererImpl>::const_iterator iter = audio_renderers_.begin();
- iter != audio_renderers_.end(); ++iter) {
- DCHECK(iter->second != audio_renderer);
- }
-
- // Add to map and send the IPC to browser process.
- int32 stream_id = audio_renderers_.Add(audio_renderer);
- ViewHostMsg_Audio_CreateStream params;
- params.format = format;
- params.channels = channels;
- params.sample_rate = sample_rate;
- params.bits_per_sample = bits_per_sample;
- params.packet_size = packet_size;
- Send(new ViewHostMsg_CreateAudioStream(routing_id_, stream_id, params));
- return stream_id;
-}
-
-void RenderView::StartAudioStream(int stream_id) {
- DCHECK(RenderThread::current()->message_loop() == MessageLoop::current());
- DCHECK(audio_renderers_.Lookup(stream_id) != NULL);
- Send(new ViewHostMsg_StartAudioStream(routing_id_, stream_id));
-}
-
-void RenderView::CloseAudioStream(int stream_id) {
- DCHECK(RenderThread::current()->message_loop() == MessageLoop::current());
- if (audio_renderers_.Lookup(stream_id) != NULL) {
- // Remove the entry from the map and send a close message to browser
- // process, we won't be getting anything back from browser even if there's
- // an error.
- audio_renderers_.Remove(stream_id);
- Send(new ViewHostMsg_CloseAudioStream(routing_id_, stream_id));
- }
-}
-
-void RenderView::NotifyAudioPacketReady(int stream_id, size_t size) {
- DCHECK(RenderThread::current()->message_loop() == MessageLoop::current());
- DCHECK(audio_renderers_.Lookup(stream_id) != NULL);
- Send(new ViewHostMsg_NotifyAudioPacketReady(routing_id_, stream_id, size));
-}
-
-void RenderView::GetAudioVolume(int stream_id) {
- DCHECK(RenderThread::current()->message_loop() == MessageLoop::current());
- DCHECK(audio_renderers_.Lookup(stream_id) != NULL);
- Send(new ViewHostMsg_GetAudioVolume(routing_id_, stream_id));
-}
-
-void RenderView::SetAudioVolume(int stream_id, double left, double right) {
- DCHECK(RenderThread::current()->message_loop() == MessageLoop::current());
- DCHECK(audio_renderers_.Lookup(stream_id) != NULL);
- Send(new ViewHostMsg_SetAudioVolume(routing_id_, stream_id, left, right));
-}
-
void RenderView::OnResize(const gfx::Size& new_size,
const gfx::Rect& resizer_rect) {
if (webview())
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index d0264f3..f6bd01b 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -26,7 +26,6 @@
#include "chrome/renderer/external_host_bindings.h"
#include "chrome/renderer/external_js_object.h"
#include "chrome/renderer/render_widget.h"
-#include "media/audio/audio_output.h"
#include "testing/gtest/include/gtest/gtest_prod.h"
#include "third_party/WebKit/WebKit/chromium/public/WebConsoleMessage.h"
#include "webkit/glue/dom_serializer_delegate.h"
@@ -44,7 +43,7 @@
#pragma warning(disable: 4250)
#endif
-class AudioRendererImpl;
+class AudioMessageFilter;
class DictionaryValue;
class DebugMessageHandler;
class DevToolsAgent;
@@ -372,18 +371,7 @@ class RenderView : public RenderWidget,
// the renderer, which processes all IPC, to any I/O should be non-blocking.
MessageLoop* GetMessageLoopForIO();
- // Register the audio renderer and try to create an audio output stream in the
- // browser process. Always return a stream id. Audio renderer will then
- // receive state change notification messages.
- int32 CreateAudioStream(AudioRendererImpl* renderer,
- AudioManager::Format format, int channels,
- int sample_rate, int bits_per_sample,
- size_t packet_size);
- void StartAudioStream(int stream_id);
- void CloseAudioStream(int stream_id);
- void NotifyAudioPacketReady(int stream_id, size_t size);
- void GetAudioVolume(int stream_id);
- void SetAudioVolume(int stream_id, double left, double right);
+ AudioMessageFilter* audio_message_filter() { return audio_message_filter_; }
void OnClearFocusedNode();
@@ -591,21 +579,6 @@ class RenderView : public RenderWidget,
// grouping, and should form our own grouping.
void OnDisassociateFromPopupCount();
- // Received when browser process wants more audio packet.
- void OnRequestAudioPacket(int stream_id);
-
- // Received when browser process has created an audio output stream for us.
- void OnAudioStreamCreated(int stream_id, base::SharedMemoryHandle handle,
- int length);
-
- // Received when internal state of browser process' audio output device has
- // changed.
- void OnAudioStreamStateChanged(int stream_id, AudioOutputStream::State state,
- int info);
-
- // Notification of volume property of an audio output stream.
- void OnAudioStreamVolume(int stream_id, double left, double right);
-
// Sends the selection text to the browser.
void OnRequestSelectionText();
@@ -833,12 +806,15 @@ class RenderView : public RenderWidget,
// change but is overridden by tests.
int delay_seconds_for_form_state_sync_;
- // A set of audio renderers registered to use IPC for audio output.
- IDMap<AudioRendererImpl> audio_renderers_;
-
// Maps pending callback IDs to their frames.
IDMap<WebFrame> pending_extension_callbacks_;
+ scoped_refptr<AudioMessageFilter> audio_message_filter_;
+
+ // The currently selected text. This is currently only updated on Linux, where
+ // it's for the selection clipboard.
+ std::string selection_text_;
+
DISALLOW_COPY_AND_ASSIGN(RenderView);
};
diff --git a/chrome/renderer/renderer.vcproj b/chrome/renderer/renderer.vcproj
index 56f9e82..5a388fd 100644
--- a/chrome/renderer/renderer.vcproj
+++ b/chrome/renderer/renderer.vcproj
@@ -222,6 +222,14 @@
>
</File>
<File
+ RelativePath=".\audio_message_filter.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\audio_message_filter.h"
+ >
+ </File>
+ <File
RelativePath=".\debug_message_handler.cc"
>
</File>
diff --git a/chrome/renderer/webmediaplayer_delegate_impl.cc b/chrome/renderer/webmediaplayer_delegate_impl.cc
index 5a0f1c2..d605a99 100644
--- a/chrome/renderer/webmediaplayer_delegate_impl.cc
+++ b/chrome/renderer/webmediaplayer_delegate_impl.cc
@@ -57,7 +57,6 @@ WebMediaPlayerDelegateImpl::WebMediaPlayerDelegateImpl(RenderView* view)
ready_state_(webkit_glue::WebMediaPlayer::HAVE_NOTHING),
main_loop_(NULL),
filter_factory_(new media::FilterFactoryCollection()),
- audio_renderer_(NULL),
video_renderer_(NULL),
data_source_(NULL),
web_media_player_(NULL),
@@ -70,7 +69,8 @@ WebMediaPlayerDelegateImpl::WebMediaPlayerDelegateImpl(RenderView* view)
filter_factory_->AddFactory(media::FFmpegAudioDecoder::CreateFactory());
filter_factory_->AddFactory(media::FFmpegVideoDecoder::CreateFactory());
#endif
- filter_factory_->AddFactory(AudioRendererImpl::CreateFactory(this));
+ filter_factory_->AddFactory(AudioRendererImpl::CreateFactory(
+ view_->audio_message_filter()));
filter_factory_->AddFactory(VideoRendererImpl::CreateFactory(this));
filter_factory_->AddFactory(DataSourceImpl::CreateFactory(this));
}
@@ -315,15 +315,8 @@ void WebMediaPlayerDelegateImpl::DidInitializePipeline(bool successful) {
&webkit_glue::WebMediaPlayer::NotifyReadyStateChange);
}
-void WebMediaPlayerDelegateImpl::SetAudioRenderer(
- AudioRendererImpl* audio_renderer) {
- DCHECK(!audio_renderer_);
- audio_renderer_ = audio_renderer;
-}
-
void WebMediaPlayerDelegateImpl::SetVideoRenderer(
VideoRendererImpl* video_renderer) {
- DCHECK(!video_renderer_);
video_renderer_ = video_renderer;
}
@@ -373,11 +366,6 @@ void WebMediaPlayerDelegateImpl::StopPipeline(bool render_thread_is_dying) {
// Instruct the renderers and data source to release all Renderer related
// resources during destruction of render thread, because they won't have any
// chance to release these resources on render thread by posting tasks on it.
- if (audio_renderer_) {
- audio_renderer_->ReleaseResources(render_thread_is_dying);
- audio_renderer_ = NULL;
- }
-
if (data_source_) {
data_source_->ReleaseResources(render_thread_is_dying);
data_source_ = NULL;
diff --git a/chrome/renderer/webmediaplayer_delegate_impl.h b/chrome/renderer/webmediaplayer_delegate_impl.h
index fc976bf..b104ee6 100644
--- a/chrome/renderer/webmediaplayer_delegate_impl.h
+++ b/chrome/renderer/webmediaplayer_delegate_impl.h
@@ -188,10 +188,6 @@ class WebMediaPlayerDelegateImpl : public webkit_glue::WebMediaPlayerDelegate,
// the same lifetime as the pipeline.
media::PipelineImpl pipeline_;
- // Holds a pointer to the audio renderer so we can tell it to stop during
- // render thread destruction.
- scoped_refptr<AudioRendererImpl> audio_renderer_;
-
// We have the interface to VideoRenderer to delegate paint messages to it
// from WebKit.
scoped_refptr<VideoRendererImpl> video_renderer_;