| // Copyright (c) 2012 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 "content/renderer/media/video_capture_message_filter.h" |
| |
| #include "content/common/media/video_capture_messages.h" |
| #include "content/common/view_messages.h" |
| #include "ipc/ipc_sender.h" |
| |
| namespace content { |
| |
| VideoCaptureMessageFilter::VideoCaptureMessageFilter() |
| : last_device_id_(0), |
| sender_(NULL) { |
| } |
| |
| void VideoCaptureMessageFilter::AddDelegate(Delegate* delegate) { |
| if (++last_device_id_ <= 0) |
| last_device_id_ = 1; |
| while (delegates_.find(last_device_id_) != delegates_.end()) |
| last_device_id_++; |
| |
| if (sender_) { |
| delegates_[last_device_id_] = delegate; |
| delegate->OnDelegateAdded(last_device_id_); |
| } else { |
| pending_delegates_[last_device_id_] = delegate; |
| } |
| } |
| |
| void VideoCaptureMessageFilter::RemoveDelegate(Delegate* delegate) { |
| for (Delegates::iterator it = delegates_.begin(); |
| it != delegates_.end(); it++) { |
| if (it->second == delegate) { |
| delegates_.erase(it); |
| break; |
| } |
| } |
| for (Delegates::iterator it = pending_delegates_.begin(); |
| it != pending_delegates_.end(); it++) { |
| if (it->second == delegate) { |
| pending_delegates_.erase(it); |
| break; |
| } |
| } |
| } |
| |
| bool VideoCaptureMessageFilter::Send(IPC::Message* message) { |
| if (!sender_) { |
| delete message; |
| return false; |
| } |
| |
| return sender_->Send(message); |
| } |
| |
| bool VideoCaptureMessageFilter::OnMessageReceived(const IPC::Message& message) { |
| bool handled = true; |
| IPC_BEGIN_MESSAGE_MAP(VideoCaptureMessageFilter, message) |
| IPC_MESSAGE_HANDLER(VideoCaptureMsg_BufferReady, OnBufferReceived) |
| IPC_MESSAGE_HANDLER(VideoCaptureMsg_MailboxBufferReady, |
| OnMailboxBufferReceived) |
| IPC_MESSAGE_HANDLER(VideoCaptureMsg_StateChanged, OnDeviceStateChanged) |
| IPC_MESSAGE_HANDLER(VideoCaptureMsg_NewBuffer, OnBufferCreated) |
| IPC_MESSAGE_HANDLER(VideoCaptureMsg_FreeBuffer, OnBufferDestroyed) |
| IPC_MESSAGE_HANDLER(VideoCaptureMsg_DeviceSupportedFormatsEnumerated, |
| OnDeviceSupportedFormatsEnumerated) |
| IPC_MESSAGE_HANDLER(VideoCaptureMsg_DeviceFormatsInUseReceived, |
| OnDeviceFormatsInUseReceived) |
| IPC_MESSAGE_UNHANDLED(handled = false) |
| IPC_END_MESSAGE_MAP() |
| return handled; |
| } |
| |
| void VideoCaptureMessageFilter::OnFilterAdded(IPC::Sender* sender) { |
| DVLOG(1) << "VideoCaptureMessageFilter::OnFilterAdded()"; |
| sender_ = sender; |
| |
| for (Delegates::iterator it = pending_delegates_.begin(); |
| it != pending_delegates_.end(); it++) { |
| it->second->OnDelegateAdded(it->first); |
| delegates_[it->first] = it->second; |
| } |
| pending_delegates_.clear(); |
| } |
| |
| void VideoCaptureMessageFilter::OnFilterRemoved() { |
| sender_ = NULL; |
| } |
| |
| void VideoCaptureMessageFilter::OnChannelClosing() { |
| sender_ = NULL; |
| } |
| |
| VideoCaptureMessageFilter::~VideoCaptureMessageFilter() {} |
| |
| VideoCaptureMessageFilter::Delegate* VideoCaptureMessageFilter::find_delegate( |
| int device_id) const { |
| Delegates::const_iterator i = delegates_.find(device_id); |
| return i != delegates_.end() ? i->second : NULL; |
| } |
| |
| void VideoCaptureMessageFilter::OnBufferCreated( |
| int device_id, |
| base::SharedMemoryHandle handle, |
| int length, |
| int buffer_id) { |
| Delegate* delegate = find_delegate(device_id); |
| if (!delegate) { |
| DLOG(WARNING) << "OnBufferCreated: Got video SHM buffer for a " |
| "non-existent or removed video capture."; |
| |
| // Send the buffer back to Host in case it's waiting for all buffers |
| // to be returned. |
| base::SharedMemory::CloseHandle(handle); |
| Send(new VideoCaptureHostMsg_BufferReady( |
| device_id, buffer_id, std::vector<uint32>())); |
| return; |
| } |
| |
| delegate->OnBufferCreated(handle, length, buffer_id); |
| } |
| |
| void VideoCaptureMessageFilter::OnBufferReceived( |
| int device_id, |
| int buffer_id, |
| const media::VideoCaptureFormat& format, |
| base::TimeTicks timestamp) { |
| Delegate* delegate = find_delegate(device_id); |
| if (!delegate) { |
| DLOG(WARNING) << "OnBufferReceived: Got video SHM buffer for a " |
| "non-existent or removed video capture."; |
| |
| // Send the buffer back to Host in case it's waiting for all buffers |
| // to be returned. |
| Send(new VideoCaptureHostMsg_BufferReady( |
| device_id, buffer_id, std::vector<uint32>())); |
| return; |
| } |
| |
| delegate->OnBufferReceived(buffer_id, format, timestamp); |
| } |
| |
| void VideoCaptureMessageFilter::OnMailboxBufferReceived( |
| int device_id, |
| int buffer_id, |
| const gpu::MailboxHolder& mailbox_holder, |
| const media::VideoCaptureFormat& format, |
| base::TimeTicks timestamp) { |
| Delegate* delegate = find_delegate(device_id); |
| |
| if (!delegate) { |
| DLOG(WARNING) << "OnMailboxBufferReceived: Got video mailbox buffer for a " |
| "non-existent or removed video capture."; |
| |
| // Send the buffer back to Host in case it's waiting for all buffers |
| // to be returned. |
| Send(new VideoCaptureHostMsg_BufferReady( |
| device_id, buffer_id, std::vector<uint32>())); |
| return; |
| } |
| |
| delegate->OnMailboxBufferReceived( |
| buffer_id, mailbox_holder, format, timestamp); |
| } |
| |
| void VideoCaptureMessageFilter::OnBufferDestroyed( |
| int device_id, |
| int buffer_id) { |
| Delegate* delegate = find_delegate(device_id); |
| if (!delegate) { |
| DLOG(WARNING) << "OnBufferDestroyed: Instructed to free buffer for a " |
| "non-existent or removed video capture."; |
| return; |
| } |
| |
| delegate->OnBufferDestroyed(buffer_id); |
| } |
| |
| void VideoCaptureMessageFilter::OnDeviceStateChanged( |
| int device_id, |
| VideoCaptureState state) { |
| Delegate* delegate = find_delegate(device_id); |
| if (!delegate) { |
| DLOG(WARNING) << "OnDeviceStateChanged: Got video capture event for a " |
| "non-existent or removed video capture."; |
| return; |
| } |
| delegate->OnStateChanged(state); |
| } |
| |
| void VideoCaptureMessageFilter::OnDeviceSupportedFormatsEnumerated( |
| int device_id, |
| const media::VideoCaptureFormats& supported_formats) { |
| Delegate* delegate = find_delegate(device_id); |
| if (!delegate) { |
| DLOG(WARNING) << "OnDeviceFormatsEnumerated: unknown device"; |
| return; |
| } |
| delegate->OnDeviceSupportedFormatsEnumerated(supported_formats); |
| } |
| |
| void VideoCaptureMessageFilter::OnDeviceFormatsInUseReceived( |
| int device_id, |
| const media::VideoCaptureFormats& formats_in_use) { |
| Delegate* delegate = find_delegate(device_id); |
| if (!delegate) { |
| DLOG(WARNING) << "OnDeviceFormatInUse: unknown device"; |
| return; |
| } |
| delegate->OnDeviceFormatsInUseReceived(formats_in_use); |
| } |
| |
| } // namespace content |