Revert 268405 "Make sure that ScratchBuffer::Allocate() always r..."
[chromium-blink-merge.git] / content / browser / renderer_host / media / video_capture_host.cc
blob14ab5d403fd330dd965194f1eff524047eae3079
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.
5 #include "content/browser/renderer_host/media/video_capture_host.h"
7 #include "base/bind.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "content/browser/browser_main_loop.h"
10 #include "content/browser/renderer_host/media/media_stream_manager.h"
11 #include "content/browser/renderer_host/media/video_capture_manager.h"
12 #include "content/common/media/video_capture_messages.h"
14 namespace content {
16 VideoCaptureHost::VideoCaptureHost(MediaStreamManager* media_stream_manager)
17 : BrowserMessageFilter(VideoCaptureMsgStart),
18 media_stream_manager_(media_stream_manager) {
21 VideoCaptureHost::~VideoCaptureHost() {}
23 void VideoCaptureHost::OnChannelClosing() {
24 // Since the IPC channel is gone, close all requested VideoCaptureDevices.
25 for (EntryMap::iterator it = entries_.begin(); it != entries_.end(); ) {
26 const base::WeakPtr<VideoCaptureController>& controller = it->second;
27 if (controller) {
28 VideoCaptureControllerID controller_id(it->first);
29 media_stream_manager_->video_capture_manager()->StopCaptureForClient(
30 controller.get(), controller_id, this, false);
31 ++it;
32 } else {
33 // Remove the entry for this controller_id so that when the controller
34 // is added, the controller will be notified to stop for this client
35 // in DoControllerAddedOnIOThread.
36 entries_.erase(it++);
41 void VideoCaptureHost::OnDestruct() const {
42 BrowserThread::DeleteOnIOThread::Destruct(this);
45 ///////////////////////////////////////////////////////////////////////////////
47 // Implements VideoCaptureControllerEventHandler.
48 void VideoCaptureHost::OnError(const VideoCaptureControllerID& controller_id) {
49 DVLOG(1) << "VideoCaptureHost::OnError";
50 BrowserThread::PostTask(
51 BrowserThread::IO, FROM_HERE,
52 base::Bind(&VideoCaptureHost::DoHandleErrorOnIOThread,
53 this, controller_id));
56 void VideoCaptureHost::OnBufferCreated(
57 const VideoCaptureControllerID& controller_id,
58 base::SharedMemoryHandle handle,
59 int length,
60 int buffer_id) {
61 BrowserThread::PostTask(
62 BrowserThread::IO, FROM_HERE,
63 base::Bind(&VideoCaptureHost::DoSendNewBufferOnIOThread,
64 this, controller_id, handle, length, buffer_id));
67 void VideoCaptureHost::OnBufferDestroyed(
68 const VideoCaptureControllerID& controller_id,
69 int buffer_id) {
70 BrowserThread::PostTask(
71 BrowserThread::IO, FROM_HERE,
72 base::Bind(&VideoCaptureHost::DoSendFreeBufferOnIOThread,
73 this, controller_id, buffer_id));
76 void VideoCaptureHost::OnBufferReady(
77 const VideoCaptureControllerID& controller_id,
78 int buffer_id,
79 const media::VideoCaptureFormat& frame_format,
80 base::TimeTicks timestamp) {
81 BrowserThread::PostTask(
82 BrowserThread::IO,
83 FROM_HERE,
84 base::Bind(&VideoCaptureHost::DoSendFilledBufferOnIOThread,
85 this,
86 controller_id,
87 buffer_id,
88 frame_format,
89 timestamp));
92 void VideoCaptureHost::OnMailboxBufferReady(
93 const VideoCaptureControllerID& controller_id,
94 int buffer_id,
95 const gpu::MailboxHolder& mailbox_holder,
96 const media::VideoCaptureFormat& frame_format,
97 base::TimeTicks timestamp) {
98 BrowserThread::PostTask(
99 BrowserThread::IO,
100 FROM_HERE,
101 base::Bind(&VideoCaptureHost::DoSendFilledMailboxBufferOnIOThread,
102 this,
103 controller_id,
104 buffer_id,
105 mailbox_holder,
106 frame_format,
107 timestamp));
110 void VideoCaptureHost::OnEnded(const VideoCaptureControllerID& controller_id) {
111 DVLOG(1) << "VideoCaptureHost::OnEnded";
112 BrowserThread::PostTask(
113 BrowserThread::IO, FROM_HERE,
114 base::Bind(&VideoCaptureHost::DoEndedOnIOThread, this, controller_id));
117 void VideoCaptureHost::DoSendNewBufferOnIOThread(
118 const VideoCaptureControllerID& controller_id,
119 base::SharedMemoryHandle handle,
120 int length,
121 int buffer_id) {
122 DCHECK_CURRENTLY_ON(BrowserThread::IO);
124 if (entries_.find(controller_id) == entries_.end())
125 return;
127 Send(new VideoCaptureMsg_NewBuffer(controller_id.device_id, handle,
128 length, buffer_id));
131 void VideoCaptureHost::DoSendFreeBufferOnIOThread(
132 const VideoCaptureControllerID& controller_id,
133 int buffer_id) {
134 DCHECK_CURRENTLY_ON(BrowserThread::IO);
136 if (entries_.find(controller_id) == entries_.end())
137 return;
139 Send(new VideoCaptureMsg_FreeBuffer(controller_id.device_id, buffer_id));
142 void VideoCaptureHost::DoSendFilledBufferOnIOThread(
143 const VideoCaptureControllerID& controller_id,
144 int buffer_id,
145 const media::VideoCaptureFormat& format,
146 base::TimeTicks timestamp) {
147 DCHECK_CURRENTLY_ON(BrowserThread::IO);
149 if (entries_.find(controller_id) == entries_.end())
150 return;
152 Send(new VideoCaptureMsg_BufferReady(
153 controller_id.device_id, buffer_id, format, timestamp));
156 void VideoCaptureHost::DoSendFilledMailboxBufferOnIOThread(
157 const VideoCaptureControllerID& controller_id,
158 int buffer_id,
159 const gpu::MailboxHolder& mailbox_holder,
160 const media::VideoCaptureFormat& format,
161 base::TimeTicks timestamp) {
162 DCHECK_CURRENTLY_ON(BrowserThread::IO);
164 if (entries_.find(controller_id) == entries_.end())
165 return;
167 Send(new VideoCaptureMsg_MailboxBufferReady(
168 controller_id.device_id, buffer_id, mailbox_holder, format, timestamp));
171 void VideoCaptureHost::DoHandleErrorOnIOThread(
172 const VideoCaptureControllerID& controller_id) {
173 DCHECK_CURRENTLY_ON(BrowserThread::IO);
175 if (entries_.find(controller_id) == entries_.end())
176 return;
178 Send(new VideoCaptureMsg_StateChanged(controller_id.device_id,
179 VIDEO_CAPTURE_STATE_ERROR));
180 DeleteVideoCaptureControllerOnIOThread(controller_id, true);
183 void VideoCaptureHost::DoEndedOnIOThread(
184 const VideoCaptureControllerID& controller_id) {
185 DCHECK_CURRENTLY_ON(BrowserThread::IO);
186 DVLOG(1) << "VideoCaptureHost::DoEndedOnIOThread";
187 if (entries_.find(controller_id) == entries_.end())
188 return;
190 Send(new VideoCaptureMsg_StateChanged(controller_id.device_id,
191 VIDEO_CAPTURE_STATE_ENDED));
192 DeleteVideoCaptureControllerOnIOThread(controller_id, false);
195 ///////////////////////////////////////////////////////////////////////////////
196 // IPC Messages handler.
197 bool VideoCaptureHost::OnMessageReceived(const IPC::Message& message,
198 bool* message_was_ok) {
199 bool handled = true;
200 IPC_BEGIN_MESSAGE_MAP_EX(VideoCaptureHost, message, *message_was_ok)
201 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Start, OnStartCapture)
202 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Pause, OnPauseCapture)
203 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Stop, OnStopCapture)
204 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_BufferReady, OnReceiveEmptyBuffer)
205 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_GetDeviceSupportedFormats,
206 OnGetDeviceSupportedFormats)
207 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_GetDeviceFormatsInUse,
208 OnGetDeviceFormatsInUse)
209 IPC_MESSAGE_UNHANDLED(handled = false)
210 IPC_END_MESSAGE_MAP_EX()
212 return handled;
215 void VideoCaptureHost::OnStartCapture(int device_id,
216 media::VideoCaptureSessionId session_id,
217 const media::VideoCaptureParams& params) {
218 DCHECK_CURRENTLY_ON(BrowserThread::IO);
219 DVLOG(1) << "VideoCaptureHost::OnStartCapture:"
220 << " session_id=" << session_id
221 << ", device_id=" << device_id
222 << ", format=" << params.requested_format.frame_size.ToString()
223 << "@" << params.requested_format.frame_rate
224 << " (" << (params.allow_resolution_change ? "variable" : "constant")
225 << ")";
226 VideoCaptureControllerID controller_id(device_id);
227 if (entries_.find(controller_id) != entries_.end()) {
228 Send(new VideoCaptureMsg_StateChanged(device_id,
229 VIDEO_CAPTURE_STATE_ERROR));
230 return;
233 entries_[controller_id] = base::WeakPtr<VideoCaptureController>();
234 media_stream_manager_->video_capture_manager()->StartCaptureForClient(
235 session_id,
236 params,
237 PeerHandle(),
238 controller_id,
239 this,
240 base::Bind(&VideoCaptureHost::OnControllerAdded, this, device_id));
243 void VideoCaptureHost::OnControllerAdded(
244 int device_id,
245 const base::WeakPtr<VideoCaptureController>& controller) {
246 BrowserThread::PostTask(
247 BrowserThread::IO,
248 FROM_HERE,
249 base::Bind(&VideoCaptureHost::DoControllerAddedOnIOThread,
250 this,
251 device_id,
252 controller));
255 void VideoCaptureHost::DoControllerAddedOnIOThread(
256 int device_id,
257 const base::WeakPtr<VideoCaptureController>& controller) {
258 DCHECK_CURRENTLY_ON(BrowserThread::IO);
259 VideoCaptureControllerID controller_id(device_id);
260 EntryMap::iterator it = entries_.find(controller_id);
261 if (it == entries_.end()) {
262 if (controller) {
263 media_stream_manager_->video_capture_manager()->StopCaptureForClient(
264 controller.get(), controller_id, this, false);
266 return;
269 if (!controller) {
270 Send(new VideoCaptureMsg_StateChanged(device_id,
271 VIDEO_CAPTURE_STATE_ERROR));
272 entries_.erase(controller_id);
273 return;
276 DCHECK(!it->second);
277 it->second = controller;
280 void VideoCaptureHost::OnStopCapture(int device_id) {
281 DCHECK_CURRENTLY_ON(BrowserThread::IO);
282 DVLOG(1) << "VideoCaptureHost::OnStopCapture, device_id " << device_id;
284 VideoCaptureControllerID controller_id(device_id);
286 Send(new VideoCaptureMsg_StateChanged(device_id,
287 VIDEO_CAPTURE_STATE_STOPPED));
288 DeleteVideoCaptureControllerOnIOThread(controller_id, false);
291 void VideoCaptureHost::OnPauseCapture(int device_id) {
292 DCHECK_CURRENTLY_ON(BrowserThread::IO);
293 DVLOG(1) << "VideoCaptureHost::OnPauseCapture, device_id " << device_id;
294 // Not used.
295 Send(new VideoCaptureMsg_StateChanged(device_id, VIDEO_CAPTURE_STATE_ERROR));
298 void VideoCaptureHost::OnReceiveEmptyBuffer(
299 int device_id,
300 int buffer_id,
301 const std::vector<uint32>& sync_points) {
302 DCHECK_CURRENTLY_ON(BrowserThread::IO);
304 VideoCaptureControllerID controller_id(device_id);
305 EntryMap::iterator it = entries_.find(controller_id);
306 if (it != entries_.end()) {
307 const base::WeakPtr<VideoCaptureController>& controller = it->second;
308 if (controller)
309 controller->ReturnBuffer(controller_id, this, buffer_id, sync_points);
313 void VideoCaptureHost::OnGetDeviceSupportedFormats(
314 int device_id,
315 media::VideoCaptureSessionId capture_session_id) {
316 DCHECK_CURRENTLY_ON(BrowserThread::IO);
317 DVLOG(1) << "VideoCaptureHost::OnGetDeviceFormats, capture_session_id "
318 << capture_session_id;
319 media::VideoCaptureFormats device_supported_formats;
320 if (!media_stream_manager_->video_capture_manager()
321 ->GetDeviceSupportedFormats(capture_session_id,
322 &device_supported_formats)) {
323 DLOG(WARNING)
324 << "Could not retrieve device supported formats for device_id="
325 << device_id << " capture_session_id=" << capture_session_id;
327 Send(new VideoCaptureMsg_DeviceSupportedFormatsEnumerated(
328 device_id, device_supported_formats));
331 void VideoCaptureHost::OnGetDeviceFormatsInUse(
332 int device_id,
333 media::VideoCaptureSessionId capture_session_id) {
334 DCHECK_CURRENTLY_ON(BrowserThread::IO);
335 DVLOG(1) << "VideoCaptureHost::OnGetDeviceFormatsInUse, capture_session_id "
336 << capture_session_id;
337 media::VideoCaptureFormats formats_in_use;
338 if (!media_stream_manager_->video_capture_manager()->GetDeviceFormatsInUse(
339 capture_session_id, &formats_in_use)) {
340 DVLOG(1) << "Could not retrieve device format(s) in use for device_id="
341 << device_id << " capture_session_id=" << capture_session_id;
343 Send(new VideoCaptureMsg_DeviceFormatsInUseReceived(device_id,
344 formats_in_use));
347 void VideoCaptureHost::DeleteVideoCaptureControllerOnIOThread(
348 const VideoCaptureControllerID& controller_id, bool on_error) {
349 DCHECK_CURRENTLY_ON(BrowserThread::IO);
351 EntryMap::iterator it = entries_.find(controller_id);
352 if (it == entries_.end())
353 return;
355 if (it->second) {
356 media_stream_manager_->video_capture_manager()->StopCaptureForClient(
357 it->second.get(), controller_id, this, on_error);
359 entries_.erase(it);
362 } // namespace content