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 11 namespace content { 12 13 VideoCaptureMessageFilter::VideoCaptureMessageFilter() 14 : last_device_id_(0), 15 sender_(NULL) { 16 } 17 18 void 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 32 void 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 49 bool VideoCaptureMessageFilter::Send(IPC::Message* message) { 50 if (!sender_) { 51 delete message; 52 return false; 53 } 54 55 return sender_->Send(message); 56 } 57 58 bool 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 76 void 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 88 void VideoCaptureMessageFilter::OnFilterRemoved() { 89 sender_ = NULL; 90 } 91 92 void VideoCaptureMessageFilter::OnChannelClosing() { 93 sender_ = NULL; 94 } 95 96 VideoCaptureMessageFilter::~VideoCaptureMessageFilter() {} 97 98 VideoCaptureMessageFilter::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 104 void 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 124 void 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 144 void 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 166 void 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 179 void 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 191 void 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 202 void 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