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( 118 device_id, buffer_id, std::vector<uint32>())); 119 return; 120 } 121 122 delegate->OnBufferCreated(handle, length, buffer_id); 123 } 124 125 void VideoCaptureMessageFilter::OnBufferReceived( 126 int device_id, 127 int buffer_id, 128 const media::VideoCaptureFormat& format, 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( 138 device_id, buffer_id, std::vector<uint32>())); 139 return; 140 } 141 142 delegate->OnBufferReceived(buffer_id, format, timestamp); 143 } 144 145 void VideoCaptureMessageFilter::OnMailboxBufferReceived( 146 int device_id, 147 int buffer_id, 148 const gpu::MailboxHolder& mailbox_holder, 149 const media::VideoCaptureFormat& format, 150 base::TimeTicks timestamp) { 151 Delegate* delegate = find_delegate(device_id); 152 153 if (!delegate) { 154 DLOG(WARNING) << "OnMailboxBufferReceived: Got video mailbox buffer for a " 155 "non-existent or removed video capture."; 156 157 // Send the buffer back to Host in case it's waiting for all buffers 158 // to be returned. 159 Send(new VideoCaptureHostMsg_BufferReady( 160 device_id, buffer_id, std::vector<uint32>())); 161 return; 162 } 163 164 delegate->OnMailboxBufferReceived( 165 buffer_id, mailbox_holder, format, timestamp); 166 } 167 168 void VideoCaptureMessageFilter::OnBufferDestroyed( 169 int device_id, 170 int buffer_id) { 171 Delegate* delegate = find_delegate(device_id); 172 if (!delegate) { 173 DLOG(WARNING) << "OnBufferDestroyed: Instructed to free buffer for a " 174 "non-existent or removed video capture."; 175 return; 176 } 177 178 delegate->OnBufferDestroyed(buffer_id); 179 } 180 181 void VideoCaptureMessageFilter::OnDeviceStateChanged( 182 int device_id, 183 VideoCaptureState state) { 184 Delegate* delegate = find_delegate(device_id); 185 if (!delegate) { 186 DLOG(WARNING) << "OnDeviceStateChanged: Got video capture event for a " 187 "non-existent or removed video capture."; 188 return; 189 } 190 delegate->OnStateChanged(state); 191 } 192 193 void VideoCaptureMessageFilter::OnDeviceSupportedFormatsEnumerated( 194 int device_id, 195 const media::VideoCaptureFormats& supported_formats) { 196 Delegate* delegate = find_delegate(device_id); 197 if (!delegate) { 198 DLOG(WARNING) << "OnDeviceFormatsEnumerated: unknown device"; 199 return; 200 } 201 delegate->OnDeviceSupportedFormatsEnumerated(supported_formats); 202 } 203 204 void VideoCaptureMessageFilter::OnDeviceFormatsInUseReceived( 205 int device_id, 206 const media::VideoCaptureFormats& formats_in_use) { 207 Delegate* delegate = find_delegate(device_id); 208 if (!delegate) { 209 DLOG(WARNING) << "OnDeviceFormatInUse: unknown device"; 210 return; 211 } 212 delegate->OnDeviceFormatsInUseReceived(formats_in_use); 213 } 214 215 } // namespace content 216