OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/renderer_host/media/video_capture_host.h" | 5 #include "content/browser/renderer_host/media/video_capture_host.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
10 #include "content/browser/browser_main_loop.h" | 10 #include "content/browser/browser_main_loop.h" |
11 #include "content/browser/renderer_host/media/media_stream_manager.h" | 11 #include "content/browser/renderer_host/media/media_stream_manager.h" |
12 #include "content/browser/renderer_host/media/video_capture_manager.h" | 12 #include "content/browser/renderer_host/media/video_capture_manager.h" |
13 #include "content/common/media/video_capture_messages.h" | 13 #include "content/common/media/video_capture_messages.h" |
14 | 14 |
15 namespace content { | 15 namespace content { |
16 | 16 |
17 VideoCaptureHost::VideoCaptureHost(MediaStreamManager* media_stream_manager) | 17 VideoCaptureHost::VideoCaptureHost(MediaStreamManager* media_stream_manager) |
18 : BrowserMessageFilter(VideoCaptureMsgStart), | 18 : BrowserMessageFilter(VideoCaptureMsgStart), |
19 media_stream_manager_(media_stream_manager) { | 19 media_stream_manager_(media_stream_manager) { |
| 20 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
20 } | 21 } |
21 | 22 |
22 VideoCaptureHost::~VideoCaptureHost() {} | 23 VideoCaptureHost::~VideoCaptureHost() {} |
23 | 24 |
24 void VideoCaptureHost::OnChannelClosing() { | 25 void VideoCaptureHost::OnChannelClosing() { |
25 // Since the IPC sender is gone, close all requested VideoCaptureDevices. | 26 // Since the IPC sender is gone, close all requested VideoCaptureDevices. |
26 for (EntryMap::iterator it = entries_.begin(); it != entries_.end(); ) { | 27 for (EntryMap::iterator it = entries_.begin(); it != entries_.end(); ) { |
27 const base::WeakPtr<VideoCaptureController>& controller = it->second; | 28 const base::WeakPtr<VideoCaptureController>& controller = it->second; |
28 if (controller) { | 29 if (controller) { |
29 VideoCaptureControllerID controller_id(it->first); | 30 const VideoCaptureControllerID controller_id(it->first); |
30 media_stream_manager_->video_capture_manager()->StopCaptureForClient( | 31 media_stream_manager_->video_capture_manager()->StopCaptureForClient( |
31 controller.get(), controller_id, this, false); | 32 controller.get(), controller_id, this, false); |
32 ++it; | 33 ++it; |
33 } else { | 34 } else { |
34 // Remove the entry for this controller_id so that when the controller | 35 // Remove the entry for this controller_id so that when the controller |
35 // is added, the controller will be notified to stop for this client | 36 // is added, the controller will be notified to stop for this client |
36 // in DoControllerAddedOnIOThread. | 37 // in DoControllerAdded. |
37 entries_.erase(it++); | 38 entries_.erase(it++); |
38 } | 39 } |
39 } | 40 } |
40 } | 41 } |
41 | 42 |
42 void VideoCaptureHost::OnDestruct() const { | 43 void VideoCaptureHost::OnDestruct() const { |
43 BrowserThread::DeleteOnIOThread::Destruct(this); | 44 BrowserThread::DeleteOnIOThread::Destruct(this); |
44 } | 45 } |
45 | 46 |
46 /////////////////////////////////////////////////////////////////////////////// | 47 /////////////////////////////////////////////////////////////////////////////// |
47 | 48 |
48 // Implements VideoCaptureControllerEventHandler. | 49 // Implements VideoCaptureControllerEventHandler. |
49 void VideoCaptureHost::OnError(const VideoCaptureControllerID& controller_id) { | 50 void VideoCaptureHost::OnError(VideoCaptureControllerID controller_id) { |
50 DVLOG(1) << "VideoCaptureHost::OnError"; | 51 DVLOG(1) << "VideoCaptureHost::OnError"; |
| 52 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
51 BrowserThread::PostTask( | 53 BrowserThread::PostTask( |
52 BrowserThread::IO, FROM_HERE, | 54 BrowserThread::IO, FROM_HERE, |
53 base::Bind(&VideoCaptureHost::DoHandleErrorOnIOThread, | 55 base::Bind(&VideoCaptureHost::DoError, this, controller_id)); |
54 this, controller_id)); | |
55 } | 56 } |
56 | 57 |
57 void VideoCaptureHost::OnBufferCreated( | 58 void VideoCaptureHost::OnBufferCreated(VideoCaptureControllerID controller_id, |
58 const VideoCaptureControllerID& controller_id, | 59 base::SharedMemoryHandle handle, |
59 base::SharedMemoryHandle handle, | 60 int length, |
60 int length, | 61 int buffer_id) { |
61 int buffer_id) { | 62 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
62 BrowserThread::PostTask( | 63 if (entries_.find(controller_id) == entries_.end()) |
63 BrowserThread::IO, FROM_HERE, | 64 return; |
64 base::Bind(&VideoCaptureHost::DoSendNewBufferOnIOThread, | 65 |
65 this, controller_id, handle, length, buffer_id)); | 66 Send(new VideoCaptureMsg_NewBuffer(controller_id, handle, length, buffer_id)); |
66 } | 67 } |
67 | 68 |
68 void VideoCaptureHost::OnBufferDestroyed( | 69 void VideoCaptureHost::OnBufferDestroyed(VideoCaptureControllerID controller_id, |
69 const VideoCaptureControllerID& controller_id, | 70 int buffer_id) { |
70 int buffer_id) { | 71 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
71 BrowserThread::PostTask( | 72 if (entries_.find(controller_id) == entries_.end()) |
72 BrowserThread::IO, FROM_HERE, | 73 return; |
73 base::Bind(&VideoCaptureHost::DoSendFreeBufferOnIOThread, | 74 |
74 this, controller_id, buffer_id)); | 75 Send(new VideoCaptureMsg_FreeBuffer(controller_id, buffer_id)); |
75 } | 76 } |
76 | 77 |
77 void VideoCaptureHost::OnBufferReady( | 78 void VideoCaptureHost::OnBufferReady( |
78 const VideoCaptureControllerID& controller_id, | 79 VideoCaptureControllerID controller_id, |
79 int buffer_id, | 80 int buffer_id, |
80 const gfx::Size& coded_size, | 81 const gfx::Size& coded_size, |
81 const gfx::Rect& visible_rect, | 82 const gfx::Rect& visible_rect, |
82 base::TimeTicks timestamp, | 83 const base::TimeTicks& timestamp, |
83 scoped_ptr<base::DictionaryValue> metadata) { | |
84 BrowserThread::PostTask( | |
85 BrowserThread::IO, | |
86 FROM_HERE, | |
87 base::Bind(&VideoCaptureHost::DoSendFilledBufferOnIOThread, | |
88 this, | |
89 controller_id, | |
90 buffer_id, | |
91 coded_size, | |
92 visible_rect, | |
93 timestamp, | |
94 base::Passed(&metadata))); | |
95 } | |
96 | |
97 void VideoCaptureHost::OnMailboxBufferReady( | |
98 const VideoCaptureControllerID& controller_id, | |
99 int buffer_id, | |
100 const gpu::MailboxHolder& mailbox_holder, | |
101 const gfx::Size& packed_frame_size, | |
102 base::TimeTicks timestamp, | |
103 scoped_ptr<base::DictionaryValue> metadata) { | |
104 BrowserThread::PostTask( | |
105 BrowserThread::IO, | |
106 FROM_HERE, | |
107 base::Bind(&VideoCaptureHost::DoSendFilledMailboxBufferOnIOThread, | |
108 this, | |
109 controller_id, | |
110 buffer_id, | |
111 mailbox_holder, | |
112 packed_frame_size, | |
113 timestamp, | |
114 base::Passed(&metadata))); | |
115 } | |
116 | |
117 void VideoCaptureHost::OnEnded(const VideoCaptureControllerID& controller_id) { | |
118 DVLOG(1) << "VideoCaptureHost::OnEnded"; | |
119 BrowserThread::PostTask( | |
120 BrowserThread::IO, FROM_HERE, | |
121 base::Bind(&VideoCaptureHost::DoEndedOnIOThread, this, controller_id)); | |
122 } | |
123 | |
124 void VideoCaptureHost::DoSendNewBufferOnIOThread( | |
125 const VideoCaptureControllerID& controller_id, | |
126 base::SharedMemoryHandle handle, | |
127 int length, | |
128 int buffer_id) { | |
129 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
130 | |
131 if (entries_.find(controller_id) == entries_.end()) | |
132 return; | |
133 | |
134 Send(new VideoCaptureMsg_NewBuffer(controller_id.device_id, handle, | |
135 length, buffer_id)); | |
136 } | |
137 | |
138 void VideoCaptureHost::DoSendFreeBufferOnIOThread( | |
139 const VideoCaptureControllerID& controller_id, | |
140 int buffer_id) { | |
141 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
142 | |
143 if (entries_.find(controller_id) == entries_.end()) | |
144 return; | |
145 | |
146 Send(new VideoCaptureMsg_FreeBuffer(controller_id.device_id, buffer_id)); | |
147 } | |
148 | |
149 void VideoCaptureHost::DoSendFilledBufferOnIOThread( | |
150 const VideoCaptureControllerID& controller_id, | |
151 int buffer_id, | |
152 const gfx::Size& coded_size, | |
153 const gfx::Rect& visible_rect, | |
154 base::TimeTicks timestamp, | |
155 scoped_ptr<base::DictionaryValue> metadata) { | 84 scoped_ptr<base::DictionaryValue> metadata) { |
156 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 85 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
157 | |
158 if (entries_.find(controller_id) == entries_.end()) | 86 if (entries_.find(controller_id) == entries_.end()) |
159 return; | 87 return; |
160 | 88 |
161 VideoCaptureMsg_BufferReady_Params params; | 89 VideoCaptureMsg_BufferReady_Params params; |
162 params.device_id = controller_id.device_id; | 90 params.device_id = controller_id; |
163 params.buffer_id = buffer_id; | 91 params.buffer_id = buffer_id; |
164 params.coded_size = coded_size; | 92 params.coded_size = coded_size; |
165 params.visible_rect = visible_rect; | 93 params.visible_rect = visible_rect; |
166 params.timestamp = timestamp; | 94 params.timestamp = timestamp; |
167 if (metadata) | 95 if (metadata) |
168 params.metadata.Swap(metadata.get()); | 96 params.metadata.Swap(metadata.get()); |
169 Send(new VideoCaptureMsg_BufferReady(params)); | 97 Send(new VideoCaptureMsg_BufferReady(params)); |
170 } | 98 } |
171 | 99 |
172 void VideoCaptureHost::DoSendFilledMailboxBufferOnIOThread( | 100 void VideoCaptureHost::OnMailboxBufferReady( |
173 const VideoCaptureControllerID& controller_id, | 101 VideoCaptureControllerID controller_id, |
174 int buffer_id, | 102 int buffer_id, |
175 const gpu::MailboxHolder& mailbox_holder, | 103 const gpu::MailboxHolder& mailbox_holder, |
176 const gfx::Size& packed_frame_size, | 104 const gfx::Size& packed_frame_size, |
177 base::TimeTicks timestamp, | 105 const base::TimeTicks& timestamp, |
178 scoped_ptr<base::DictionaryValue> metadata) { | 106 scoped_ptr<base::DictionaryValue> metadata) { |
179 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 107 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
180 | 108 |
181 if (entries_.find(controller_id) == entries_.end()) | 109 if (entries_.find(controller_id) == entries_.end()) |
182 return; | 110 return; |
183 | 111 |
184 VideoCaptureMsg_MailboxBufferReady_Params params; | 112 VideoCaptureMsg_MailboxBufferReady_Params params; |
185 params.device_id = controller_id.device_id; | 113 params.device_id = controller_id; |
186 params.buffer_id = buffer_id; | 114 params.buffer_id = buffer_id; |
187 params.mailbox_holder = mailbox_holder; | 115 params.mailbox_holder = mailbox_holder; |
188 params.packed_frame_size = packed_frame_size; | 116 params.packed_frame_size = packed_frame_size; |
189 params.timestamp = timestamp; | 117 params.timestamp = timestamp; |
190 if (metadata) | 118 if (metadata) |
191 params.metadata.Swap(metadata.get()); | 119 params.metadata.Swap(metadata.get()); |
192 Send(new VideoCaptureMsg_MailboxBufferReady(params)); | 120 Send(new VideoCaptureMsg_MailboxBufferReady(params)); |
193 } | 121 } |
194 | 122 |
195 void VideoCaptureHost::DoHandleErrorOnIOThread( | 123 void VideoCaptureHost::OnEnded(VideoCaptureControllerID controller_id) { |
196 const VideoCaptureControllerID& controller_id) { | 124 DVLOG(1) << "VideoCaptureHost::OnEnded"; |
197 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 125 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 126 BrowserThread::PostTask( |
| 127 BrowserThread::IO, FROM_HERE, |
| 128 base::Bind(&VideoCaptureHost::DoEnded, this, controller_id)); |
| 129 } |
198 | 130 |
| 131 void VideoCaptureHost::DoError(VideoCaptureControllerID controller_id) { |
| 132 DVLOG(1) << "VideoCaptureHost::DoError"; |
| 133 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
199 if (entries_.find(controller_id) == entries_.end()) | 134 if (entries_.find(controller_id) == entries_.end()) |
200 return; | 135 return; |
201 | 136 |
202 Send(new VideoCaptureMsg_StateChanged(controller_id.device_id, | 137 Send(new VideoCaptureMsg_StateChanged(controller_id, |
203 VIDEO_CAPTURE_STATE_ERROR)); | 138 VIDEO_CAPTURE_STATE_ERROR)); |
204 DeleteVideoCaptureControllerOnIOThread(controller_id, true); | 139 DeleteVideoCaptureController(controller_id, true); |
205 } | 140 } |
206 | 141 |
207 void VideoCaptureHost::DoEndedOnIOThread( | 142 void VideoCaptureHost::DoEnded(VideoCaptureControllerID controller_id) { |
208 const VideoCaptureControllerID& controller_id) { | 143 DVLOG(1) << "VideoCaptureHost::DoEnded"; |
209 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 144 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
210 DVLOG(1) << "VideoCaptureHost::DoEndedOnIOThread"; | |
211 if (entries_.find(controller_id) == entries_.end()) | 145 if (entries_.find(controller_id) == entries_.end()) |
212 return; | 146 return; |
213 | 147 |
214 Send(new VideoCaptureMsg_StateChanged(controller_id.device_id, | 148 Send(new VideoCaptureMsg_StateChanged(controller_id, |
215 VIDEO_CAPTURE_STATE_ENDED)); | 149 VIDEO_CAPTURE_STATE_ENDED)); |
216 DeleteVideoCaptureControllerOnIOThread(controller_id, false); | 150 DeleteVideoCaptureController(controller_id, false); |
217 } | 151 } |
218 | 152 |
219 /////////////////////////////////////////////////////////////////////////////// | 153 /////////////////////////////////////////////////////////////////////////////// |
220 // IPC Messages handler. | 154 // IPC Messages handler. |
221 bool VideoCaptureHost::OnMessageReceived(const IPC::Message& message) { | 155 bool VideoCaptureHost::OnMessageReceived(const IPC::Message& message) { |
222 bool handled = true; | 156 bool handled = true; |
223 IPC_BEGIN_MESSAGE_MAP(VideoCaptureHost, message) | 157 IPC_BEGIN_MESSAGE_MAP(VideoCaptureHost, message) |
224 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Start, OnStartCapture) | 158 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Start, OnStartCapture) |
225 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Pause, OnPauseCapture) | 159 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Pause, OnPauseCapture) |
226 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Resume, OnResumeCapture) | 160 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Resume, OnResumeCapture) |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 PeerHandle(), | 197 PeerHandle(), |
264 controller_id, | 198 controller_id, |
265 this, | 199 this, |
266 base::Bind(&VideoCaptureHost::OnControllerAdded, this, device_id)); | 200 base::Bind(&VideoCaptureHost::OnControllerAdded, this, device_id)); |
267 } | 201 } |
268 | 202 |
269 void VideoCaptureHost::OnControllerAdded( | 203 void VideoCaptureHost::OnControllerAdded( |
270 int device_id, | 204 int device_id, |
271 const base::WeakPtr<VideoCaptureController>& controller) { | 205 const base::WeakPtr<VideoCaptureController>& controller) { |
272 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 206 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
273 BrowserThread::PostTask( | |
274 BrowserThread::IO, | |
275 FROM_HERE, | |
276 base::Bind(&VideoCaptureHost::DoControllerAddedOnIOThread, | |
277 this, | |
278 device_id, | |
279 controller)); | |
280 } | |
281 | |
282 void VideoCaptureHost::DoControllerAddedOnIOThread( | |
283 int device_id, | |
284 const base::WeakPtr<VideoCaptureController>& controller) { | |
285 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
286 VideoCaptureControllerID controller_id(device_id); | 207 VideoCaptureControllerID controller_id(device_id); |
287 EntryMap::iterator it = entries_.find(controller_id); | 208 EntryMap::iterator it = entries_.find(controller_id); |
288 if (it == entries_.end()) { | 209 if (it == entries_.end()) { |
289 if (controller) { | 210 if (controller) { |
290 media_stream_manager_->video_capture_manager()->StopCaptureForClient( | 211 media_stream_manager_->video_capture_manager()->StopCaptureForClient( |
291 controller.get(), controller_id, this, false); | 212 controller.get(), controller_id, this, false); |
292 } | 213 } |
293 return; | 214 return; |
294 } | 215 } |
295 | 216 |
296 if (!controller) { | 217 if (!controller) { |
297 Send(new VideoCaptureMsg_StateChanged(device_id, | 218 Send(new VideoCaptureMsg_StateChanged(device_id, |
298 VIDEO_CAPTURE_STATE_ERROR)); | 219 VIDEO_CAPTURE_STATE_ERROR)); |
299 entries_.erase(controller_id); | 220 entries_.erase(controller_id); |
300 return; | 221 return; |
301 } | 222 } |
302 | 223 |
303 DCHECK(!it->second); | 224 DCHECK(!it->second); |
304 it->second = controller; | 225 it->second = controller; |
305 } | 226 } |
306 | 227 |
307 void VideoCaptureHost::OnStopCapture(int device_id) { | 228 void VideoCaptureHost::OnStopCapture(int device_id) { |
308 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 229 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
309 DVLOG(1) << "VideoCaptureHost::OnStopCapture, device_id " << device_id; | 230 DVLOG(1) << "VideoCaptureHost::OnStopCapture, device_id " << device_id; |
310 | 231 |
311 VideoCaptureControllerID controller_id(device_id); | 232 VideoCaptureControllerID controller_id(device_id); |
312 | 233 |
313 Send(new VideoCaptureMsg_StateChanged(device_id, | 234 Send(new VideoCaptureMsg_StateChanged(device_id, |
314 VIDEO_CAPTURE_STATE_STOPPED)); | 235 VIDEO_CAPTURE_STATE_STOPPED)); |
315 DeleteVideoCaptureControllerOnIOThread(controller_id, false); | 236 DeleteVideoCaptureController(controller_id, false); |
316 } | 237 } |
317 | 238 |
318 void VideoCaptureHost::OnPauseCapture(int device_id) { | 239 void VideoCaptureHost::OnPauseCapture(int device_id) { |
319 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 240 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
320 DVLOG(1) << "VideoCaptureHost::OnPauseCapture, device_id " << device_id; | 241 DVLOG(1) << "VideoCaptureHost::OnPauseCapture, device_id " << device_id; |
321 | 242 |
322 VideoCaptureControllerID controller_id(device_id); | 243 VideoCaptureControllerID controller_id(device_id); |
323 EntryMap::iterator it = entries_.find(controller_id); | 244 EntryMap::iterator it = entries_.find(controller_id); |
324 if (it == entries_.end()) | 245 if (it == entries_.end()) |
325 return; | 246 return; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 media::VideoCaptureFormats formats_in_use; | 310 media::VideoCaptureFormats formats_in_use; |
390 if (!media_stream_manager_->video_capture_manager()->GetDeviceFormatsInUse( | 311 if (!media_stream_manager_->video_capture_manager()->GetDeviceFormatsInUse( |
391 capture_session_id, &formats_in_use)) { | 312 capture_session_id, &formats_in_use)) { |
392 DVLOG(1) << "Could not retrieve device format(s) in use for device_id=" | 313 DVLOG(1) << "Could not retrieve device format(s) in use for device_id=" |
393 << device_id << " capture_session_id=" << capture_session_id; | 314 << device_id << " capture_session_id=" << capture_session_id; |
394 } | 315 } |
395 Send(new VideoCaptureMsg_DeviceFormatsInUseReceived(device_id, | 316 Send(new VideoCaptureMsg_DeviceFormatsInUseReceived(device_id, |
396 formats_in_use)); | 317 formats_in_use)); |
397 } | 318 } |
398 | 319 |
399 void VideoCaptureHost::DeleteVideoCaptureControllerOnIOThread( | 320 void VideoCaptureHost::DeleteVideoCaptureController( |
400 const VideoCaptureControllerID& controller_id, bool on_error) { | 321 VideoCaptureControllerID controller_id, bool on_error) { |
401 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 322 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
402 | 323 |
403 EntryMap::iterator it = entries_.find(controller_id); | 324 EntryMap::iterator it = entries_.find(controller_id); |
404 if (it == entries_.end()) | 325 if (it == entries_.end()) |
405 return; | 326 return; |
406 | 327 |
407 if (it->second) { | 328 if (it->second) { |
408 media_stream_manager_->video_capture_manager()->StopCaptureForClient( | 329 media_stream_manager_->video_capture_manager()->StopCaptureForClient( |
409 it->second.get(), controller_id, this, on_error); | 330 it->second.get(), controller_id, this, on_error); |
410 } | 331 } |
411 entries_.erase(it); | 332 entries_.erase(it); |
412 } | 333 } |
413 | 334 |
414 } // namespace content | 335 } // namespace content |
OLD | NEW |