Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2011 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/browser/renderer_host/video_capture_host.h" | |
| 6 | |
| 7 #include "base/memory/scoped_ptr.h" | |
| 8 #include "base/stl_util-inl.h" | |
| 9 #include "content/browser/media_stream/video_capture_manager.h" | |
| 10 #include "content/common/video_capture_messages.h" | |
| 11 | |
| 12 VideoCaptureHost::VideoCaptureHost() {} | |
| 13 | |
| 14 VideoCaptureHost::~VideoCaptureHost() { | |
| 15 DCHECK(vc_entries_.empty()); | |
| 16 // Delete all Memory handlers that have been stopped but not returned all | |
| 17 // TransportDIBs. | |
| 18 STLDeleteContainerPairSecondPointers(vc_stoped_entries_.begin(), | |
| 19 vc_stoped_entries_.end()); | |
| 20 vc_stoped_entries_.clear(); | |
| 21 } | |
| 22 | |
| 23 void VideoCaptureHost::OnChannelClosing() { | |
| 24 BrowserMessageFilter::OnChannelClosing(); | |
| 25 | |
| 26 // Since the IPC channel is gone, close all requested VideCaptureDevices. | |
| 27 for (VCEntryMap::iterator it = vc_entries_.begin(); | |
| 28 it != vc_entries_.end(); it++) { | |
| 29 StopVideoCapture(it->second->entry_id()); | |
| 30 } | |
| 31 } | |
| 32 | |
| 33 void VideoCaptureHost::OnDestruct() const { | |
| 34 BrowserThread::DeleteOnIOThread::Destruct(this); | |
| 35 } | |
| 36 | |
| 37 /////////////////////////////////////////////////////////////////////////////// | |
| 38 | |
| 39 // Implements VideoCaptureMemory::EventHandler. | |
| 40 void VideoCaptureHost::OnError(VideoCaptureMemory::VCEntryId entry) { | |
| 41 BrowserThread::PostTask( | |
| 42 BrowserThread::IO, FROM_HERE, | |
| 43 NewRunnableMethod(this, &VideoCaptureHost::DoHandleError, entry)); | |
| 44 } | |
| 45 | |
| 46 void VideoCaptureHost::OnBufferReady(VideoCaptureMemory::VCEntryId entry, | |
| 47 TransportDIB::Handle handle, | |
| 48 base::Time timestamp) { | |
| 49 BrowserThread::PostTask( | |
| 50 BrowserThread::IO, FROM_HERE, | |
| 51 NewRunnableMethod(this, &VideoCaptureHost::DoSendFilledBuffer, entry, | |
| 52 handle, timestamp)); | |
| 53 } | |
| 54 | |
| 55 void VideoCaptureHost::OnFrameInfo(VideoCaptureMemory::VCEntryId entry, | |
| 56 int width, | |
| 57 int height, | |
| 58 int frame_per_second) { | |
| 59 BrowserThread::PostTask( | |
| 60 BrowserThread::IO, FROM_HERE, | |
| 61 NewRunnableMethod(this, &VideoCaptureHost::DoSendFrameInfo, entry, width, | |
| 62 height, frame_per_second)); | |
| 63 } | |
| 64 | |
| 65 void VideoCaptureHost::DoSendFilledBuffer(VideoCaptureMemory::VCEntryId entry, | |
| 66 TransportDIB::Handle handle, | |
| 67 base::Time timestamp) { | |
| 68 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 69 | |
| 70 Send(new VideoCaptureMsg_BufferReady(entry.render_id, entry.device_id, handle, | |
| 71 timestamp)); | |
| 72 } | |
| 73 | |
| 74 void VideoCaptureHost::DoHandleError(VideoCaptureMemory::VCEntryId entry) { | |
| 75 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 76 | |
| 77 SendErrorMessage(entry.render_id, entry.device_id); | |
| 78 StopVideoCapture(entry); | |
| 79 } | |
| 80 | |
| 81 void VideoCaptureHost::DoSendFrameInfo(VideoCaptureMemory::VCEntryId entry, | |
| 82 int width, | |
| 83 int height, | |
| 84 int frame_per_second) { | |
| 85 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 86 media::VideoCaptureParams params; | |
| 87 params.width = width; | |
| 88 params.height = height; | |
| 89 params.frame_per_second = frame_per_second; | |
| 90 Send(new VideoCaptureMsg_DeviceInfo(entry.render_id, | |
| 91 entry.device_id, | |
| 92 params)); | |
| 93 Send(new VideoCaptureMsg_StateChanged(entry.render_id, entry.device_id, | |
| 94 media::VideoCapture::kStarted)); | |
| 95 } | |
| 96 | |
| 97 /////////////////////////////////////////////////////////////////////////////// | |
| 98 // IPC Messages handler. | |
| 99 bool VideoCaptureHost::OnMessageReceived(const IPC::Message& message, | |
| 100 bool* message_was_ok) { | |
| 101 bool handled = true; | |
| 102 IPC_BEGIN_MESSAGE_MAP_EX(VideoCaptureHost, message, *message_was_ok) | |
| 103 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Start, OnStartCapture) | |
| 104 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Pause, OnPauseCapture) | |
| 105 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Stop, OnStopCapture) | |
| 106 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_BufferReady, OnReceiveEmptyBuffer) | |
| 107 IPC_MESSAGE_UNHANDLED(handled = false) | |
| 108 IPC_END_MESSAGE_MAP_EX() | |
| 109 | |
| 110 return handled; | |
| 111 } | |
| 112 | |
| 113 void VideoCaptureHost::OnStartCapture( | |
| 114 const IPC::Message& msg, int device_id, | |
|
wjia(left Chromium)
2011/05/11 23:23:31
indent
Per K
2011/05/16 11:49:39
Done.
| |
| 115 const media::VideoCaptureParams& params) { | |
| 116 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 117 | |
| 118 VideoCaptureMemory::VCEntryId entry(msg.routing_id(), | |
| 119 device_id, | |
| 120 params.session_id); | |
| 121 // Check that it is not already started. | |
| 122 DCHECK(LookupStartedDevicesById(device_id) == NULL); | |
| 123 VideoCaptureMemory* memory_handler = new VideoCaptureMemory(this, entry); | |
| 124 if (!memory_handler) { | |
| 125 SendErrorMessage(msg.routing_id(), device_id); | |
| 126 return; | |
| 127 } | |
| 128 | |
| 129 media_stream::VideoCaptureManager* manager = | |
| 130 media_stream::VideoCaptureManager::Get(); | |
| 131 // Order the manager to start the actual capture. | |
| 132 manager->Start(params, memory_handler); | |
| 133 | |
| 134 vc_entries_.insert(std::make_pair(device_id, memory_handler)); | |
|
wjia(left Chromium)
2011/05/11 23:23:31
Some thoughts about the modules:
1. Host only nee
Per K
2011/05/16 11:49:39
VCEntryId moved to VideoCaptureHost and called Vid
| |
| 135 } | |
| 136 | |
| 137 void VideoCaptureHost::OnStopCapture(const IPC::Message& msg, int device_id) { | |
| 138 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 139 | |
| 140 VideoCaptureMemory* memory_handler = LookupStartedDevicesById(device_id); | |
|
wjia(left Chromium)
2011/05/11 23:23:31
would it be good to pass Stop command to memory_ha
Per K
2011/05/16 11:49:39
Done.
| |
| 141 if (!memory_handler) { | |
| 142 // Check if the device is being stopped | |
| 143 if (!LookupStopedDevicesById(device_id)) { | |
| 144 // It does not exist so it must have been stopped already. | |
| 145 Send(new VideoCaptureMsg_StateChanged(msg.routing_id(), device_id, | |
| 146 media::VideoCapture::kStopped)); | |
| 147 } | |
| 148 return; | |
| 149 } | |
| 150 StopVideoCapture(memory_handler->entry_id()); | |
| 151 } | |
| 152 | |
| 153 void VideoCaptureHost::OnPauseCapture(const IPC::Message& msg, int device_id) { | |
| 154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 155 // Not used. | |
| 156 SendErrorMessage(msg.routing_id(), device_id); | |
| 157 } | |
| 158 | |
| 159 void VideoCaptureHost::OnReceiveEmptyBuffer(const IPC::Message& msg, | |
| 160 int device_id, | |
| 161 TransportDIB::Handle handle) { | |
| 162 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 163 | |
| 164 VideoCaptureMemory* memory_handler = LookupStartedDevicesById(device_id); | |
| 165 if (!memory_handler || memory_handler->AddTransportDIB(handle) != 0) { | |
| 166 // This buffer do not belong to an active VideoCaptureMemory instance | |
| 167 // Check the Stopped Devices. | |
| 168 memory_handler = LookupStopedDevicesById(device_id); | |
| 169 if (memory_handler) { | |
| 170 memory_handler->AddTransportDIB(handle); | |
| 171 if (memory_handler->ReadyToDelete()) { | |
| 172 SendDeviceStopped(msg.routing_id(), device_id); | |
| 173 scoped_ptr<VideoCaptureMemory> item_to_delete(memory_handler); | |
| 174 vc_stoped_entries_.erase(device_id); | |
| 175 } | |
| 176 } | |
| 177 } | |
| 178 } | |
| 179 | |
| 180 void VideoCaptureHost::StopVideoCapture(VideoCaptureMemory::VCEntryId entry) { | |
| 181 media_stream::VideoCaptureManager* manager = | |
| 182 media_stream::VideoCaptureManager::Get(); | |
| 183 manager->Stop(entry.session_id, | |
| 184 NewRunnableMethod(this, &VideoCaptureHost::OnDeviceStoped, | |
| 185 entry.device_id)); | |
| 186 } | |
| 187 | |
| 188 void VideoCaptureHost::OnDeviceStoped(int device_id) { | |
| 189 BrowserThread::PostTask( | |
| 190 BrowserThread::IO, FROM_HERE, | |
| 191 NewRunnableMethod(this, &VideoCaptureHost::DoDeviceStoped, device_id)); | |
| 192 } | |
| 193 | |
| 194 void VideoCaptureHost::DoDeviceStoped(int device_id) { | |
| 195 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 196 | |
| 197 scoped_ptr<VideoCaptureMemory> memory_handler( | |
| 198 LookupStartedDevicesById(device_id)); | |
| 199 if (!memory_handler.get()) { | |
| 200 return; | |
| 201 } | |
| 202 | |
| 203 vc_entries_.erase(device_id); | |
| 204 | |
| 205 // If we can not delete the memory_handler now because all | |
| 206 // DIBS have not been returned we add the vc_entry to the list of stopped | |
| 207 // devices and do it later and hopefully get the missing DIB back soon. | |
| 208 if (!memory_handler->ReadyToDelete()) { | |
| 209 vc_stoped_entries_.insert( | |
| 210 std::make_pair(device_id, memory_handler.release())); | |
| 211 } else { | |
| 212 // We have received all buffers and is ready to delete the memory pool. | |
| 213 const VideoCaptureMemory::VCEntryId entry_id = memory_handler->entry_id(); | |
| 214 SendDeviceStopped(entry_id.render_id, entry_id.device_id); | |
| 215 } | |
| 216 } | |
| 217 | |
| 218 void VideoCaptureHost::SendDeviceStopped(int32 render_view_id, int device_id) { | |
| 219 // Report that the device have successfully been stopped. | |
| 220 Send(new VideoCaptureMsg_StateChanged(render_view_id, device_id, | |
| 221 media::VideoCapture::kStopped)); | |
| 222 } | |
| 223 | |
| 224 void VideoCaptureHost::SendErrorMessage(int32 render_view_id, int32 device_id) { | |
| 225 Send(new VideoCaptureMsg_StateChanged(render_view_id, device_id, | |
| 226 media::VideoCapture::kError)); | |
|
wjia(left Chromium)
2011/05/11 23:23:31
Is it needed for renderer process to distinguish d
Per K
2011/05/16 11:49:39
I am not really sure we will be able to distinguis
| |
| 227 } | |
| 228 | |
| 229 VideoCaptureMemory* VideoCaptureHost::LookupStartedDevicesById(int device_id) { | |
| 230 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 231 | |
| 232 VCEntryMap::iterator it = vc_entries_.find(device_id); | |
| 233 if (it != vc_entries_.end()) { | |
| 234 return it->second; | |
| 235 } | |
| 236 | |
| 237 return NULL; | |
| 238 } | |
| 239 | |
| 240 VideoCaptureMemory* VideoCaptureHost::LookupStopedDevicesById(int device_id) { | |
| 241 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 242 | |
| 243 VCEntryMap::iterator it = vc_stoped_entries_.find(device_id); | |
| 244 if (it != vc_stoped_entries_.end()) { | |
| 245 return it->second; | |
| 246 } | |
| 247 | |
| 248 return NULL; | |
| 249 } | |
| OLD | NEW |