Index: content/renderer/media/audio_message_filter.cc |
diff --git a/content/renderer/media/audio_message_filter.cc b/content/renderer/media/audio_message_filter.cc |
index fd349a250021e5b2b21c8652715f64c58e5cc9b7..991d8d4405968d7e9ed74ede440535f4cbc21522 100644 |
--- a/content/renderer/media/audio_message_filter.cc |
+++ b/content/renderer/media/audio_message_filter.cc |
@@ -12,6 +12,30 @@ |
namespace content { |
+namespace { |
+const int kStreamIDNotSet = -1; |
+} |
+ |
+class AudioMessageFilter::AudioOutputIPCImpl |
+ : public NON_EXPORTED_BASE(media::AudioOutputIPC) { |
+ public: |
+ explicit AudioOutputIPCImpl(int render_view_id); |
+ virtual ~AudioOutputIPCImpl(); |
+ |
+ // media::AudioOutputIPC implementation. |
+ virtual void CreateStream(media::AudioOutputIPCDelegate* delegate, |
+ const media::AudioParameters& params) OVERRIDE; |
+ virtual void PlayStream() OVERRIDE; |
+ virtual void PauseStream() OVERRIDE; |
+ virtual void FlushStream() OVERRIDE; |
+ virtual void CloseStream() OVERRIDE; |
+ virtual void SetVolume(double volume) OVERRIDE; |
+ |
+ private: |
+ const int render_view_id_; |
+ int stream_id_; |
+}; |
+ |
AudioMessageFilter* AudioMessageFilter::filter_ = NULL; |
// static |
@@ -22,53 +46,60 @@ AudioMessageFilter* AudioMessageFilter::Get() { |
AudioMessageFilter::AudioMessageFilter( |
const scoped_refptr<base::MessageLoopProxy>& io_message_loop) |
: channel_(NULL), |
- next_stream_id_(1), |
audio_hardware_config_(NULL), |
io_message_loop_(io_message_loop) { |
DCHECK(!filter_); |
filter_ = this; |
} |
-int AudioMessageFilter::AddDelegate(media::AudioOutputIPCDelegate* delegate) { |
- base::AutoLock auto_lock(lock_); |
- const int id = next_stream_id_++; |
- delegates_.insert(std::make_pair(id, delegate)); |
- return id; |
-} |
+AudioMessageFilter::AudioOutputIPCImpl::AudioOutputIPCImpl(int render_view_id) |
+ : render_view_id_(render_view_id), stream_id_(kStreamIDNotSet) {} |
-void AudioMessageFilter::RemoveDelegate(int id) { |
- base::AutoLock auto_lock(lock_); |
- delegates_.erase(id); |
-} |
+AudioMessageFilter::AudioOutputIPCImpl::~AudioOutputIPCImpl() {} |
-void AudioMessageFilter::CreateStream(int stream_id, |
- const media::AudioParameters& params) { |
- Send(new AudioHostMsg_CreateStream(stream_id, params)); |
+media::AudioOutputIPC* AudioMessageFilter::CreateAudioOutputIPC( |
+ int render_view_id) { |
+ DCHECK_LT(0, render_view_id); |
+ return new AudioOutputIPCImpl(render_view_id); |
} |
-void AudioMessageFilter::AssociateStreamWithProducer(int stream_id, |
- int render_view_id) { |
- Send(new AudioHostMsg_AssociateStreamWithProducer(stream_id, render_view_id)); |
+void AudioMessageFilter::AudioOutputIPCImpl::CreateStream( |
+ media::AudioOutputIPCDelegate* delegate, |
+ const media::AudioParameters& params) { |
+ DCHECK(filter_->io_message_loop_->BelongsToCurrentThread()); |
+ DCHECK(delegate); |
+ DCHECK_EQ(kStreamIDNotSet, stream_id_); |
+ stream_id_ = filter_->delegates_.Add(delegate); |
+ filter_->Send(new AudioHostMsg_CreateStream( |
+ stream_id_, render_view_id_, params)); |
} |
-void AudioMessageFilter::PlayStream(int stream_id) { |
- Send(new AudioHostMsg_PlayStream(stream_id)); |
+void AudioMessageFilter::AudioOutputIPCImpl::PlayStream() { |
+ DCHECK_NE(kStreamIDNotSet, stream_id_); |
+ filter_->Send(new AudioHostMsg_PlayStream(stream_id_)); |
} |
-void AudioMessageFilter::PauseStream(int stream_id) { |
- Send(new AudioHostMsg_PauseStream(stream_id)); |
+void AudioMessageFilter::AudioOutputIPCImpl::PauseStream() { |
+ DCHECK_NE(kStreamIDNotSet, stream_id_); |
+ filter_->Send(new AudioHostMsg_PauseStream(stream_id_)); |
} |
-void AudioMessageFilter::FlushStream(int stream_id) { |
- Send(new AudioHostMsg_FlushStream(stream_id)); |
+void AudioMessageFilter::AudioOutputIPCImpl::FlushStream() { |
+ DCHECK_NE(kStreamIDNotSet, stream_id_); |
+ filter_->Send(new AudioHostMsg_FlushStream(stream_id_)); |
} |
-void AudioMessageFilter::CloseStream(int stream_id) { |
- Send(new AudioHostMsg_CloseStream(stream_id)); |
+void AudioMessageFilter::AudioOutputIPCImpl::CloseStream() { |
+ DCHECK(filter_->io_message_loop_->BelongsToCurrentThread()); |
+ DCHECK_NE(kStreamIDNotSet, stream_id_); |
+ filter_->Send(new AudioHostMsg_CloseStream(stream_id_)); |
+ filter_->delegates_.Remove(stream_id_); |
+ stream_id_ = kStreamIDNotSet; |
} |
-void AudioMessageFilter::SetVolume(int stream_id, double volume) { |
- Send(new AudioHostMsg_SetVolume(stream_id, volume)); |
+void AudioMessageFilter::AudioOutputIPCImpl::SetVolume(double volume) { |
+ DCHECK_NE(kStreamIDNotSet, stream_id_); |
+ filter_->Send(new AudioHostMsg_SetVolume(stream_id_, volume)); |
} |
void AudioMessageFilter::Send(IPC::Message* message) { |
@@ -106,18 +137,19 @@ void AudioMessageFilter::OnChannelClosing() { |
DCHECK(io_message_loop_->BelongsToCurrentThread()); |
channel_ = NULL; |
- base::AutoLock auto_lock(lock_); |
- DLOG_IF(WARNING, !delegates_.empty()) |
+ DLOG_IF(WARNING, !delegates_.IsEmpty()) |
<< "Not all audio devices have been closed."; |
- for (DelegateMap::const_iterator it = delegates_.begin(); |
- it != delegates_.end(); ++it) { |
- it->second->OnIPCClosed(); |
+ IDMap<media::AudioOutputIPCDelegate>::iterator it(&delegates_); |
+ while (!it.IsAtEnd()) { |
+ it.GetCurrentValue()->OnIPCClosed(); |
+ delegates_.Remove(it.GetCurrentKey()); |
+ it.Advance(); |
} |
} |
AudioMessageFilter::~AudioMessageFilter() { |
- CHECK(delegates_.empty()); |
+ CHECK(delegates_.IsEmpty()); |
DCHECK_EQ(filter_, this); |
filter_ = NULL; |
} |
@@ -137,31 +169,27 @@ void AudioMessageFilter::OnStreamCreated( |
base::SyncSocket::Handle socket_handle = socket_descriptor.fd; |
#endif |
- { |
- base::AutoLock auto_lock(lock_); |
- DelegateMap::const_iterator it = delegates_.find(stream_id); |
- if (it != delegates_.end()) { |
- it->second->OnStreamCreated(handle, socket_handle, length); |
- return; |
- } |
+ media::AudioOutputIPCDelegate* delegate = delegates_.Lookup(stream_id); |
+ if (!delegate) { |
+ DLOG(WARNING) << "Got OnStreamCreated() event for a non-existent or removed" |
+ << " audio renderer. (stream_id=" << stream_id << ")."; |
+ base::SharedMemory::CloseHandle(handle); |
+ base::SyncSocket socket(socket_handle); |
+ return; |
} |
- |
- DLOG(WARNING) << "Got audio stream event for a non-existent or removed" |
- " audio renderer. (stream_id=" << stream_id << ")."; |
- base::SharedMemory::CloseHandle(handle); |
- base::SyncSocket socket(socket_handle); |
+ delegate->OnStreamCreated(handle, socket_handle, length); |
} |
void AudioMessageFilter::OnStreamStateChanged( |
int stream_id, media::AudioOutputIPCDelegate::State state) { |
DCHECK(io_message_loop_->BelongsToCurrentThread()); |
- |
- base::AutoLock auto_lock(lock_); |
- DelegateMap::const_iterator it = delegates_.find(stream_id); |
- DLOG_IF(WARNING, it == delegates_.end()) |
- << "No delegate found for state change. " << state; |
- if (it != delegates_.end()) |
- it->second->OnStateChanged(state); |
+ media::AudioOutputIPCDelegate* delegate = delegates_.Lookup(stream_id); |
+ if (!delegate) { |
+ DLOG(WARNING) << "Got OnStreamStateChanged() event for a non-existent or" |
+ << " removed audio renderer. State: " << state; |
+ return; |
+ } |
+ delegate->OnStateChanged(state); |
} |
void AudioMessageFilter::OnOutputDeviceChanged(int stream_id, |