Simplify ChildProcessLauncher
[chromium-blink-merge.git] / content / browser / renderer_host / media / video_capture_host.cc
blob72e440cd2e928688413a2aeea61e37a36784962c
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/bind_helpers.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "content/browser/browser_main_loop.h"
11 #include "content/browser/renderer_host/media/media_stream_manager.h"
12 #include "content/browser/renderer_host/media/video_capture_manager.h"
13 #include "content/common/media/video_capture_messages.h"
15 namespace content {
17 VideoCaptureHost::VideoCaptureHost(MediaStreamManager* media_stream_manager)
18 : BrowserMessageFilter(VideoCaptureMsgStart),
19 media_stream_manager_(media_stream_manager) {
20 DCHECK_CURRENTLY_ON(BrowserThread::UI);
23 VideoCaptureHost::~VideoCaptureHost() {}
25 void VideoCaptureHost::OnChannelClosing() {
26 // Since the IPC sender is gone, close all requested VideoCaptureDevices.
27 for (EntryMap::iterator it = entries_.begin(); it != entries_.end(); ) {
28 const base::WeakPtr<VideoCaptureController>& controller = it->second;
29 if (controller) {
30 const VideoCaptureControllerID controller_id(it->first);
31 media_stream_manager_->video_capture_manager()->StopCaptureForClient(
32 controller.get(), controller_id, this, false);
33 ++it;
34 } else {
35 // Remove the entry for this controller_id so that when the controller
36 // is added, the controller will be notified to stop for this client
37 // in DoControllerAdded.
38 entries_.erase(it++);
43 void VideoCaptureHost::OnDestruct() const {
44 BrowserThread::DeleteOnIOThread::Destruct(this);
47 ///////////////////////////////////////////////////////////////////////////////
49 // Implements VideoCaptureControllerEventHandler.
50 void VideoCaptureHost::OnError(VideoCaptureControllerID controller_id) {
51 DVLOG(1) << "VideoCaptureHost::OnError";
52 DCHECK_CURRENTLY_ON(BrowserThread::IO);
53 BrowserThread::PostTask(
54 BrowserThread::IO, FROM_HERE,
55 base::Bind(&VideoCaptureHost::DoError, this, controller_id));
58 void VideoCaptureHost::OnBufferCreated(VideoCaptureControllerID controller_id,
59 base::SharedMemoryHandle handle,
60 int length,
61 int buffer_id) {
62 DCHECK_CURRENTLY_ON(BrowserThread::IO);
63 if (entries_.find(controller_id) == entries_.end())
64 return;
66 Send(new VideoCaptureMsg_NewBuffer(controller_id, handle, length, buffer_id));
69 void VideoCaptureHost::OnBufferDestroyed(VideoCaptureControllerID controller_id,
70 int buffer_id) {
71 DCHECK_CURRENTLY_ON(BrowserThread::IO);
72 if (entries_.find(controller_id) == entries_.end())
73 return;
75 Send(new VideoCaptureMsg_FreeBuffer(controller_id, buffer_id));
78 void VideoCaptureHost::OnBufferReady(
79 VideoCaptureControllerID controller_id,
80 int buffer_id,
81 const gfx::Size& coded_size,
82 const gfx::Rect& visible_rect,
83 const base::TimeTicks& timestamp,
84 scoped_ptr<base::DictionaryValue> metadata) {
85 DCHECK_CURRENTLY_ON(BrowserThread::IO);
86 if (entries_.find(controller_id) == entries_.end())
87 return;
89 VideoCaptureMsg_BufferReady_Params params;
90 params.device_id = controller_id;
91 params.buffer_id = buffer_id;
92 params.coded_size = coded_size;
93 params.visible_rect = visible_rect;
94 params.timestamp = timestamp;
95 if (metadata)
96 params.metadata.Swap(metadata.get());
97 Send(new VideoCaptureMsg_BufferReady(params));
100 void VideoCaptureHost::OnMailboxBufferReady(
101 VideoCaptureControllerID controller_id,
102 int buffer_id,
103 const gpu::MailboxHolder& mailbox_holder,
104 const gfx::Size& packed_frame_size,
105 const base::TimeTicks& timestamp,
106 scoped_ptr<base::DictionaryValue> metadata) {
107 DCHECK_CURRENTLY_ON(BrowserThread::IO);
109 if (entries_.find(controller_id) == entries_.end())
110 return;
112 VideoCaptureMsg_MailboxBufferReady_Params params;
113 params.device_id = controller_id;
114 params.buffer_id = buffer_id;
115 params.mailbox_holder = mailbox_holder;
116 params.packed_frame_size = packed_frame_size;
117 params.timestamp = timestamp;
118 if (metadata)
119 params.metadata.Swap(metadata.get());
120 Send(new VideoCaptureMsg_MailboxBufferReady(params));
123 void VideoCaptureHost::OnEnded(VideoCaptureControllerID controller_id) {
124 DVLOG(1) << "VideoCaptureHost::OnEnded";
125 DCHECK_CURRENTLY_ON(BrowserThread::IO);
126 BrowserThread::PostTask(
127 BrowserThread::IO, FROM_HERE,
128 base::Bind(&VideoCaptureHost::DoEnded, this, controller_id));
131 void VideoCaptureHost::DoError(VideoCaptureControllerID controller_id) {
132 DVLOG(1) << "VideoCaptureHost::DoError";
133 DCHECK_CURRENTLY_ON(BrowserThread::IO);
134 if (entries_.find(controller_id) == entries_.end())
135 return;
137 Send(new VideoCaptureMsg_StateChanged(controller_id,
138 VIDEO_CAPTURE_STATE_ERROR));
139 DeleteVideoCaptureController(controller_id, true);
142 void VideoCaptureHost::DoEnded(VideoCaptureControllerID controller_id) {
143 DVLOG(1) << "VideoCaptureHost::DoEnded";
144 DCHECK_CURRENTLY_ON(BrowserThread::IO);
145 if (entries_.find(controller_id) == entries_.end())
146 return;
148 Send(new VideoCaptureMsg_StateChanged(controller_id,
149 VIDEO_CAPTURE_STATE_ENDED));
150 DeleteVideoCaptureController(controller_id, false);
153 ///////////////////////////////////////////////////////////////////////////////
154 // IPC Messages handler.
155 bool VideoCaptureHost::OnMessageReceived(const IPC::Message& message) {
156 bool handled = true;
157 IPC_BEGIN_MESSAGE_MAP(VideoCaptureHost, message)
158 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Start, OnStartCapture)
159 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Pause, OnPauseCapture)
160 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Resume, OnResumeCapture)
161 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Stop, OnStopCapture)
162 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_BufferReady, OnReceiveEmptyBuffer)
163 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_GetDeviceSupportedFormats,
164 OnGetDeviceSupportedFormats)
165 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_GetDeviceFormatsInUse,
166 OnGetDeviceFormatsInUse)
167 IPC_MESSAGE_UNHANDLED(handled = false)
168 IPC_END_MESSAGE_MAP()
170 return handled;
173 void VideoCaptureHost::OnStartCapture(int device_id,
174 media::VideoCaptureSessionId session_id,
175 const media::VideoCaptureParams& params) {
176 DCHECK_CURRENTLY_ON(BrowserThread::IO);
177 DVLOG(1) << "VideoCaptureHost::OnStartCapture:"
178 << " session_id=" << session_id
179 << ", device_id=" << device_id
180 << ", format=" << params.requested_format.ToString()
181 << "@" << params.requested_format.frame_rate
182 << " (" << (params.resolution_change_policy ==
183 media::RESOLUTION_POLICY_DYNAMIC_WITHIN_LIMIT ?
184 "variable" : "constant")
185 << ")";
186 VideoCaptureControllerID controller_id(device_id);
187 if (entries_.find(controller_id) != entries_.end()) {
188 Send(new VideoCaptureMsg_StateChanged(device_id,
189 VIDEO_CAPTURE_STATE_ERROR));
190 return;
193 entries_[controller_id] = base::WeakPtr<VideoCaptureController>();
194 media_stream_manager_->video_capture_manager()->StartCaptureForClient(
195 session_id,
196 params,
197 PeerHandle(),
198 controller_id,
199 this,
200 base::Bind(&VideoCaptureHost::OnControllerAdded, this, device_id));
203 void VideoCaptureHost::OnControllerAdded(
204 int device_id,
205 const base::WeakPtr<VideoCaptureController>& controller) {
206 DCHECK_CURRENTLY_ON(BrowserThread::IO);
207 VideoCaptureControllerID controller_id(device_id);
208 EntryMap::iterator it = entries_.find(controller_id);
209 if (it == entries_.end()) {
210 if (controller) {
211 media_stream_manager_->video_capture_manager()->StopCaptureForClient(
212 controller.get(), controller_id, this, false);
214 return;
217 if (!controller) {
218 Send(new VideoCaptureMsg_StateChanged(device_id,
219 VIDEO_CAPTURE_STATE_ERROR));
220 entries_.erase(controller_id);
221 return;
224 DCHECK(!it->second);
225 it->second = controller;
228 void VideoCaptureHost::OnStopCapture(int device_id) {
229 DCHECK_CURRENTLY_ON(BrowserThread::IO);
230 DVLOG(1) << "VideoCaptureHost::OnStopCapture, device_id " << device_id;
232 VideoCaptureControllerID controller_id(device_id);
234 Send(new VideoCaptureMsg_StateChanged(device_id,
235 VIDEO_CAPTURE_STATE_STOPPED));
236 DeleteVideoCaptureController(controller_id, false);
239 void VideoCaptureHost::OnPauseCapture(int device_id) {
240 DCHECK_CURRENTLY_ON(BrowserThread::IO);
241 DVLOG(1) << "VideoCaptureHost::OnPauseCapture, device_id " << device_id;
243 VideoCaptureControllerID controller_id(device_id);
244 EntryMap::iterator it = entries_.find(controller_id);
245 if (it == entries_.end())
246 return;
248 if (it->second) {
249 media_stream_manager_->video_capture_manager()->PauseCaptureForClient(
250 it->second.get(), controller_id, this);
254 void VideoCaptureHost::OnResumeCapture(
255 int device_id,
256 media::VideoCaptureSessionId session_id,
257 const media::VideoCaptureParams& params) {
258 DCHECK_CURRENTLY_ON(BrowserThread::IO);
259 DVLOG(1) << "VideoCaptureHost::OnResumeCapture, device_id " << device_id;
261 VideoCaptureControllerID controller_id(device_id);
262 EntryMap::iterator it = entries_.find(controller_id);
263 if (it == entries_.end())
264 return;
266 if (it->second) {
267 media_stream_manager_->video_capture_manager()->ResumeCaptureForClient(
268 session_id, params, it->second.get(), controller_id, this);
272 void VideoCaptureHost::OnReceiveEmptyBuffer(int device_id,
273 int buffer_id,
274 uint32 sync_point) {
275 DCHECK_CURRENTLY_ON(BrowserThread::IO);
277 VideoCaptureControllerID controller_id(device_id);
278 EntryMap::iterator it = entries_.find(controller_id);
279 if (it != entries_.end()) {
280 const base::WeakPtr<VideoCaptureController>& controller = it->second;
281 if (controller)
282 controller->ReturnBuffer(controller_id, this, buffer_id, sync_point);
286 void VideoCaptureHost::OnGetDeviceSupportedFormats(
287 int device_id,
288 media::VideoCaptureSessionId capture_session_id) {
289 DCHECK_CURRENTLY_ON(BrowserThread::IO);
290 DVLOG(1) << "VideoCaptureHost::OnGetDeviceFormats, capture_session_id "
291 << capture_session_id;
292 media::VideoCaptureFormats device_supported_formats;
293 if (!media_stream_manager_->video_capture_manager()
294 ->GetDeviceSupportedFormats(capture_session_id,
295 &device_supported_formats)) {
296 DLOG(WARNING)
297 << "Could not retrieve device supported formats for device_id="
298 << device_id << " capture_session_id=" << capture_session_id;
300 Send(new VideoCaptureMsg_DeviceSupportedFormatsEnumerated(
301 device_id, device_supported_formats));
304 void VideoCaptureHost::OnGetDeviceFormatsInUse(
305 int device_id,
306 media::VideoCaptureSessionId capture_session_id) {
307 DCHECK_CURRENTLY_ON(BrowserThread::IO);
308 DVLOG(1) << "VideoCaptureHost::OnGetDeviceFormatsInUse, capture_session_id "
309 << capture_session_id;
310 media::VideoCaptureFormats formats_in_use;
311 if (!media_stream_manager_->video_capture_manager()->GetDeviceFormatsInUse(
312 capture_session_id, &formats_in_use)) {
313 DVLOG(1) << "Could not retrieve device format(s) in use for device_id="
314 << device_id << " capture_session_id=" << capture_session_id;
316 Send(new VideoCaptureMsg_DeviceFormatsInUseReceived(device_id,
317 formats_in_use));
320 void VideoCaptureHost::DeleteVideoCaptureController(
321 VideoCaptureControllerID controller_id, bool on_error) {
322 DCHECK_CURRENTLY_ON(BrowserThread::IO);
324 EntryMap::iterator it = entries_.find(controller_id);
325 if (it == entries_.end())
326 return;
328 if (it->second) {
329 media_stream_manager_->video_capture_manager()->StopCaptureForClient(
330 it->second.get(), controller_id, this, on_error);
332 entries_.erase(it);
335 } // namespace content