1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "content/renderer/media/video_capture_message_filter.h" 6 7#include "content/common/media/video_capture_messages.h" 8#include "content/common/view_messages.h" 9#include "ipc/ipc_sender.h" 10 11namespace content { 12 13VideoCaptureMessageFilter::VideoCaptureMessageFilter() 14 : last_device_id_(0), 15 sender_(NULL) { 16} 17 18void VideoCaptureMessageFilter::AddDelegate(Delegate* delegate) { 19 if (++last_device_id_ <= 0) 20 last_device_id_ = 1; 21 while (delegates_.find(last_device_id_) != delegates_.end()) 22 last_device_id_++; 23 24 if (sender_) { 25 delegates_[last_device_id_] = delegate; 26 delegate->OnDelegateAdded(last_device_id_); 27 } else { 28 pending_delegates_[last_device_id_] = delegate; 29 } 30} 31 32void VideoCaptureMessageFilter::RemoveDelegate(Delegate* delegate) { 33 for (Delegates::iterator it = delegates_.begin(); 34 it != delegates_.end(); it++) { 35 if (it->second == delegate) { 36 delegates_.erase(it); 37 break; 38 } 39 } 40 for (Delegates::iterator it = pending_delegates_.begin(); 41 it != pending_delegates_.end(); it++) { 42 if (it->second == delegate) { 43 pending_delegates_.erase(it); 44 break; 45 } 46 } 47} 48 49bool VideoCaptureMessageFilter::Send(IPC::Message* message) { 50 if (!sender_) { 51 delete message; 52 return false; 53 } 54 55 return sender_->Send(message); 56} 57 58bool VideoCaptureMessageFilter::OnMessageReceived(const IPC::Message& message) { 59 bool handled = true; 60 IPC_BEGIN_MESSAGE_MAP(VideoCaptureMessageFilter, message) 61 IPC_MESSAGE_HANDLER(VideoCaptureMsg_BufferReady, OnBufferReceived) 62 IPC_MESSAGE_HANDLER(VideoCaptureMsg_MailboxBufferReady, 63 OnMailboxBufferReceived) 64 IPC_MESSAGE_HANDLER(VideoCaptureMsg_StateChanged, OnDeviceStateChanged) 65 IPC_MESSAGE_HANDLER(VideoCaptureMsg_NewBuffer, OnBufferCreated) 66 IPC_MESSAGE_HANDLER(VideoCaptureMsg_FreeBuffer, OnBufferDestroyed) 67 IPC_MESSAGE_HANDLER(VideoCaptureMsg_DeviceSupportedFormatsEnumerated, 68 OnDeviceSupportedFormatsEnumerated) 69 IPC_MESSAGE_HANDLER(VideoCaptureMsg_DeviceFormatsInUseReceived, 70 OnDeviceFormatsInUseReceived) 71 IPC_MESSAGE_UNHANDLED(handled = false) 72 IPC_END_MESSAGE_MAP() 73 return handled; 74} 75 76void VideoCaptureMessageFilter::OnFilterAdded(IPC::Sender* sender) { 77 DVLOG(1) << "VideoCaptureMessageFilter::OnFilterAdded()"; 78 sender_ = sender; 79 80 for (Delegates::iterator it = pending_delegates_.begin(); 81 it != pending_delegates_.end(); it++) { 82 it->second->OnDelegateAdded(it->first); 83 delegates_[it->first] = it->second; 84 } 85 pending_delegates_.clear(); 86} 87 88void VideoCaptureMessageFilter::OnFilterRemoved() { 89 sender_ = NULL; 90} 91 92void VideoCaptureMessageFilter::OnChannelClosing() { 93 sender_ = NULL; 94} 95 96VideoCaptureMessageFilter::~VideoCaptureMessageFilter() {} 97 98VideoCaptureMessageFilter::Delegate* VideoCaptureMessageFilter::find_delegate( 99 int device_id) const { 100 Delegates::const_iterator i = delegates_.find(device_id); 101 return i != delegates_.end() ? i->second : NULL; 102} 103 104void VideoCaptureMessageFilter::OnBufferCreated( 105 int device_id, 106 base::SharedMemoryHandle handle, 107 int length, 108 int buffer_id) { 109 Delegate* delegate = find_delegate(device_id); 110 if (!delegate) { 111 DLOG(WARNING) << "OnBufferCreated: Got video SHM buffer for a " 112 "non-existent or removed video capture."; 113 114 // Send the buffer back to Host in case it's waiting for all buffers 115 // to be returned. 116 base::SharedMemory::CloseHandle(handle); 117 Send(new VideoCaptureHostMsg_BufferReady(device_id, buffer_id, 0)); 118 return; 119 } 120 121 delegate->OnBufferCreated(handle, length, buffer_id); 122} 123 124void VideoCaptureMessageFilter::OnBufferReceived( 125 int device_id, 126 int buffer_id, 127 const media::VideoCaptureFormat& format, 128 const gfx::Rect& visible_rect, 129 base::TimeTicks timestamp) { 130 Delegate* delegate = find_delegate(device_id); 131 if (!delegate) { 132 DLOG(WARNING) << "OnBufferReceived: Got video SHM buffer for a " 133 "non-existent or removed video capture."; 134 135 // Send the buffer back to Host in case it's waiting for all buffers 136 // to be returned. 137 Send(new VideoCaptureHostMsg_BufferReady(device_id, buffer_id, 0)); 138 return; 139 } 140 141 delegate->OnBufferReceived(buffer_id, format, visible_rect, timestamp); 142} 143 144void VideoCaptureMessageFilter::OnMailboxBufferReceived( 145 int device_id, 146 int buffer_id, 147 const gpu::MailboxHolder& mailbox_holder, 148 const media::VideoCaptureFormat& format, 149 base::TimeTicks timestamp) { 150 Delegate* delegate = find_delegate(device_id); 151 152 if (!delegate) { 153 DLOG(WARNING) << "OnMailboxBufferReceived: Got video mailbox buffer for a " 154 "non-existent or removed video capture."; 155 156 // Send the buffer back to Host in case it's waiting for all buffers 157 // to be returned. 158 Send(new VideoCaptureHostMsg_BufferReady(device_id, buffer_id, 0)); 159 return; 160 } 161 162 delegate->OnMailboxBufferReceived( 163 buffer_id, mailbox_holder, format, timestamp); 164} 165 166void VideoCaptureMessageFilter::OnBufferDestroyed( 167 int device_id, 168 int buffer_id) { 169 Delegate* delegate = find_delegate(device_id); 170 if (!delegate) { 171 DLOG(WARNING) << "OnBufferDestroyed: Instructed to free buffer for a " 172 "non-existent or removed video capture."; 173 return; 174 } 175 176 delegate->OnBufferDestroyed(buffer_id); 177} 178 179void VideoCaptureMessageFilter::OnDeviceStateChanged( 180 int device_id, 181 VideoCaptureState state) { 182 Delegate* delegate = find_delegate(device_id); 183 if (!delegate) { 184 DLOG(WARNING) << "OnDeviceStateChanged: Got video capture event for a " 185 "non-existent or removed video capture."; 186 return; 187 } 188 delegate->OnStateChanged(state); 189} 190 191void VideoCaptureMessageFilter::OnDeviceSupportedFormatsEnumerated( 192 int device_id, 193 const media::VideoCaptureFormats& supported_formats) { 194 Delegate* delegate = find_delegate(device_id); 195 if (!delegate) { 196 DLOG(WARNING) << "OnDeviceFormatsEnumerated: unknown device"; 197 return; 198 } 199 delegate->OnDeviceSupportedFormatsEnumerated(supported_formats); 200} 201 202void VideoCaptureMessageFilter::OnDeviceFormatsInUseReceived( 203 int device_id, 204 const media::VideoCaptureFormats& formats_in_use) { 205 Delegate* delegate = find_delegate(device_id); 206 if (!delegate) { 207 DLOG(WARNING) << "OnDeviceFormatInUse: unknown device"; 208 return; 209 } 210 delegate->OnDeviceFormatsInUseReceived(formats_in_use); 211} 212 213} // namespace content 214