Add ICU message format support
[chromium-blink-merge.git] / content / browser / renderer_host / media / video_capture_host.cc
blob9d84d92840950f9b934834fd273b027e7afbe998
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 scoped_refptr<media::VideoFrame>& video_frame,
82 const base::TimeTicks& timestamp) {
83 DCHECK_CURRENTLY_ON(BrowserThread::IO);
84 if (entries_.find(controller_id) == entries_.end())
85 return;
87 VideoCaptureMsg_BufferReady_Params params;
88 params.device_id = controller_id;
89 params.buffer_id = buffer_id;
90 params.timestamp = timestamp;
91 video_frame->metadata()->MergeInternalValuesInto(&params.metadata);
92 params.pixel_format = video_frame->format();
93 params.storage_type = video_frame->storage_type();
94 params.coded_size = video_frame->coded_size();
95 params.visible_rect = video_frame->visible_rect();
96 if (video_frame->HasTextures()) {
97 DCHECK_EQ(media::VideoFrame::NumPlanes(video_frame->format()), 1u)
98 << "Multiplanar textures not supported";
99 params.mailbox_holder = video_frame->mailbox_holder(0);
102 Send(new VideoCaptureMsg_BufferReady(params));
105 void VideoCaptureHost::OnEnded(VideoCaptureControllerID controller_id) {
106 DVLOG(1) << "VideoCaptureHost::OnEnded";
107 DCHECK_CURRENTLY_ON(BrowserThread::IO);
108 BrowserThread::PostTask(
109 BrowserThread::IO, FROM_HERE,
110 base::Bind(&VideoCaptureHost::DoEnded, this, controller_id));
113 void VideoCaptureHost::DoError(VideoCaptureControllerID controller_id) {
114 DVLOG(1) << "VideoCaptureHost::DoError";
115 DCHECK_CURRENTLY_ON(BrowserThread::IO);
116 if (entries_.find(controller_id) == entries_.end())
117 return;
119 Send(new VideoCaptureMsg_StateChanged(controller_id,
120 VIDEO_CAPTURE_STATE_ERROR));
121 DeleteVideoCaptureController(controller_id, true);
124 void VideoCaptureHost::DoEnded(VideoCaptureControllerID controller_id) {
125 DVLOG(1) << "VideoCaptureHost::DoEnded";
126 DCHECK_CURRENTLY_ON(BrowserThread::IO);
127 if (entries_.find(controller_id) == entries_.end())
128 return;
130 Send(new VideoCaptureMsg_StateChanged(controller_id,
131 VIDEO_CAPTURE_STATE_ENDED));
132 DeleteVideoCaptureController(controller_id, false);
135 ///////////////////////////////////////////////////////////////////////////////
136 // IPC Messages handler.
137 bool VideoCaptureHost::OnMessageReceived(const IPC::Message& message) {
138 bool handled = true;
139 IPC_BEGIN_MESSAGE_MAP(VideoCaptureHost, message)
140 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Start, OnStartCapture)
141 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Pause, OnPauseCapture)
142 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Resume, OnResumeCapture)
143 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Stop, OnStopCapture)
144 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_BufferReady,
145 OnRendererFinishedWithBuffer)
146 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_GetDeviceSupportedFormats,
147 OnGetDeviceSupportedFormats)
148 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_GetDeviceFormatsInUse,
149 OnGetDeviceFormatsInUse)
150 IPC_MESSAGE_UNHANDLED(handled = false)
151 IPC_END_MESSAGE_MAP()
153 return handled;
156 void VideoCaptureHost::OnStartCapture(int device_id,
157 media::VideoCaptureSessionId session_id,
158 const media::VideoCaptureParams& params) {
159 DCHECK_CURRENTLY_ON(BrowserThread::IO);
160 DVLOG(1) << "VideoCaptureHost::OnStartCapture:"
161 << " session_id=" << session_id << ", device_id=" << device_id
162 << ", format="
163 << media::VideoCaptureFormat::ToString(params.requested_format)
164 << "@" << params.requested_format.frame_rate << " ("
165 << (params.resolution_change_policy ==
166 media::RESOLUTION_POLICY_FIXED_RESOLUTION
167 ? "fixed resolution"
168 : (params.resolution_change_policy ==
169 media::RESOLUTION_POLICY_FIXED_ASPECT_RATIO
170 ? "fixed aspect ratio"
171 : "variable resolution")) << ")";
172 VideoCaptureControllerID controller_id(device_id);
173 if (entries_.find(controller_id) != entries_.end()) {
174 Send(new VideoCaptureMsg_StateChanged(device_id,
175 VIDEO_CAPTURE_STATE_ERROR));
176 return;
179 entries_[controller_id] = base::WeakPtr<VideoCaptureController>();
180 media_stream_manager_->video_capture_manager()->StartCaptureForClient(
181 session_id,
182 params,
183 PeerHandle(),
184 controller_id,
185 this,
186 base::Bind(&VideoCaptureHost::OnControllerAdded, this, device_id));
189 void VideoCaptureHost::OnControllerAdded(
190 int device_id,
191 const base::WeakPtr<VideoCaptureController>& controller) {
192 DCHECK_CURRENTLY_ON(BrowserThread::IO);
193 VideoCaptureControllerID controller_id(device_id);
194 EntryMap::iterator it = entries_.find(controller_id);
195 if (it == entries_.end()) {
196 if (controller) {
197 media_stream_manager_->video_capture_manager()->StopCaptureForClient(
198 controller.get(), controller_id, this, false);
200 return;
203 if (!controller) {
204 Send(new VideoCaptureMsg_StateChanged(device_id,
205 VIDEO_CAPTURE_STATE_ERROR));
206 entries_.erase(controller_id);
207 return;
210 DCHECK(!it->second);
211 it->second = controller;
214 void VideoCaptureHost::OnStopCapture(int device_id) {
215 DCHECK_CURRENTLY_ON(BrowserThread::IO);
216 DVLOG(1) << "VideoCaptureHost::OnStopCapture, device_id " << device_id;
218 VideoCaptureControllerID controller_id(device_id);
220 Send(new VideoCaptureMsg_StateChanged(device_id,
221 VIDEO_CAPTURE_STATE_STOPPED));
222 DeleteVideoCaptureController(controller_id, false);
225 void VideoCaptureHost::OnPauseCapture(int device_id) {
226 DCHECK_CURRENTLY_ON(BrowserThread::IO);
227 DVLOG(1) << "VideoCaptureHost::OnPauseCapture, device_id " << device_id;
229 VideoCaptureControllerID controller_id(device_id);
230 EntryMap::iterator it = entries_.find(controller_id);
231 if (it == entries_.end())
232 return;
234 if (it->second) {
235 media_stream_manager_->video_capture_manager()->PauseCaptureForClient(
236 it->second.get(), controller_id, this);
240 void VideoCaptureHost::OnResumeCapture(
241 int device_id,
242 media::VideoCaptureSessionId session_id,
243 const media::VideoCaptureParams& params) {
244 DCHECK_CURRENTLY_ON(BrowserThread::IO);
245 DVLOG(1) << "VideoCaptureHost::OnResumeCapture, device_id " << device_id;
247 VideoCaptureControllerID controller_id(device_id);
248 EntryMap::iterator it = entries_.find(controller_id);
249 if (it == entries_.end())
250 return;
252 if (it->second) {
253 media_stream_manager_->video_capture_manager()->ResumeCaptureForClient(
254 session_id, params, it->second.get(), controller_id, this);
258 void VideoCaptureHost::OnRendererFinishedWithBuffer(
259 int device_id,
260 int buffer_id,
261 uint32 sync_point,
262 double consumer_resource_utilization) {
263 DCHECK_CURRENTLY_ON(BrowserThread::IO);
265 VideoCaptureControllerID controller_id(device_id);
266 EntryMap::iterator it = entries_.find(controller_id);
267 if (it != entries_.end()) {
268 const base::WeakPtr<VideoCaptureController>& controller = it->second;
269 if (controller) {
270 controller->ReturnBuffer(controller_id,
271 this,
272 buffer_id,
273 sync_point,
274 consumer_resource_utilization);
279 void VideoCaptureHost::OnGetDeviceSupportedFormats(
280 int device_id,
281 media::VideoCaptureSessionId capture_session_id) {
282 DCHECK_CURRENTLY_ON(BrowserThread::IO);
283 DVLOG(1) << "VideoCaptureHost::OnGetDeviceFormats, capture_session_id "
284 << capture_session_id;
285 media::VideoCaptureFormats device_supported_formats;
286 if (!media_stream_manager_->video_capture_manager()
287 ->GetDeviceSupportedFormats(capture_session_id,
288 &device_supported_formats)) {
289 DLOG(WARNING)
290 << "Could not retrieve device supported formats for device_id="
291 << device_id << " capture_session_id=" << capture_session_id;
293 Send(new VideoCaptureMsg_DeviceSupportedFormatsEnumerated(
294 device_id, device_supported_formats));
297 void VideoCaptureHost::OnGetDeviceFormatsInUse(
298 int device_id,
299 media::VideoCaptureSessionId capture_session_id) {
300 DCHECK_CURRENTLY_ON(BrowserThread::IO);
301 DVLOG(1) << "VideoCaptureHost::OnGetDeviceFormatsInUse, capture_session_id "
302 << capture_session_id;
303 media::VideoCaptureFormats formats_in_use;
304 if (!media_stream_manager_->video_capture_manager()->GetDeviceFormatsInUse(
305 capture_session_id, &formats_in_use)) {
306 DVLOG(1) << "Could not retrieve device format(s) in use for device_id="
307 << device_id << " capture_session_id=" << capture_session_id;
309 Send(new VideoCaptureMsg_DeviceFormatsInUseReceived(device_id,
310 formats_in_use));
313 void VideoCaptureHost::DeleteVideoCaptureController(
314 VideoCaptureControllerID controller_id, bool on_error) {
315 DCHECK_CURRENTLY_ON(BrowserThread::IO);
317 EntryMap::iterator it = entries_.find(controller_id);
318 if (it == entries_.end())
319 return;
321 if (it->second) {
322 media_stream_manager_->video_capture_manager()->StopCaptureForClient(
323 it->second.get(), controller_id, this, on_error);
325 entries_.erase(it);
328 } // namespace content