Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: ppapi/proxy/ppb_video_capture_proxy.cc

Issue 7601005: PPB/PPP_VideoCapture_Dev proxy (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address review comments Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ppapi/proxy/ppb_video_capture_proxy.h ('k') | ppapi/proxy/resource_creation_proxy.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 "ppapi/proxy/ppb_video_capture_proxy.h"
6
7 #include <vector>
8
9 #include "base/logging.h"
10 #include "build/build_config.h"
11 #include "ppapi/c/pp_errors.h"
12 #include "ppapi/c/pp_resource.h"
13 #include "ppapi/c/ppb_core.h"
14 #include "ppapi/c/dev/ppb_video_capture_dev.h"
15 #include "ppapi/c/dev/ppp_video_capture_dev.h"
16 #include "ppapi/proxy/enter_proxy.h"
17 #include "ppapi/proxy/host_dispatcher.h"
18 #include "ppapi/proxy/plugin_dispatcher.h"
19 #include "ppapi/proxy/plugin_resource.h"
20 #include "ppapi/proxy/ppapi_messages.h"
21 #include "ppapi/proxy/ppb_buffer_proxy.h"
22 #include "ppapi/thunk/ppb_buffer_api.h"
23 #include "ppapi/thunk/ppb_buffer_trusted_api.h"
24 #include "ppapi/thunk/ppb_video_capture_api.h"
25 #include "ppapi/thunk/thunk.h"
26
27 using ppapi::thunk::EnterResourceNoLock;
28 using ppapi::thunk::PPB_Buffer_API;
29 using ppapi::thunk::PPB_BufferTrusted_API;
30 using ppapi::thunk::PPB_VideoCapture_API;
31
32 namespace pp {
33 namespace proxy {
34
35 namespace {
36
37 InterfaceProxy* CreatePPBVideoCaptureProxy(Dispatcher* dispatcher,
38 const void* target_interface) {
39 return new PPB_VideoCapture_Proxy(dispatcher, target_interface);
40 }
41
42 InterfaceProxy* CreatePPPVideoCaptureProxy(Dispatcher* dispatcher,
43 const void* target_interface) {
44 return new PPP_VideoCapture_Proxy(dispatcher, target_interface);
45 }
46
47 void OnDeviceInfo(PP_Instance instance,
48 PP_Resource resource,
49 const PP_VideoCaptureDeviceInfo_Dev* info,
50 uint32_t buffer_count,
51 const PP_Resource* resources) {
52 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
53 if (!dispatcher) {
54 NOTREACHED();
55 return;
56 }
57 HostResource host_resource;
58 host_resource.SetHostResource(instance, resource);
59 std::vector<PPPVideoCapture_Buffer> buffers(buffer_count);
60 const PPB_Core* core = static_cast<const PPB_Core*>(
61 dispatcher->GetLocalInterface(PPB_CORE_INTERFACE));
62 DCHECK(core);
63 for (uint32_t i = 0; i < buffer_count; ++i) {
64 // We need to take a ref on the resource now. The browser may drop
65 // references once we return from here, but we're sending an asynchronous
66 // message. The plugin side takes ownership of that reference.
67 core->AddRefResource(resources[i]);
68 buffers[i].resource.SetHostResource(instance, resources[i]);
69 {
70 EnterResourceNoLock<PPB_Buffer_API> enter(resources[i], true);
71 DCHECK(enter.succeeded());
72 PP_Bool result = enter.object()->Describe(&buffers[i].size);
73 DCHECK(result);
74 }
75 {
76 EnterResourceNoLock<PPB_BufferTrusted_API> enter(resources[i], true);
77 DCHECK(enter.succeeded());
78 int handle;
79 int32_t result = enter.object()->GetSharedMemory(&handle);
80 DCHECK(result == PP_OK);
81 // TODO(piman/brettw): Change trusted interface to return a PP_FileHandle,
82 // those casts are ugly.
83 base::PlatformFile platform_file =
84 #if defined(OS_WIN)
85 reinterpret_cast<HANDLE>(static_cast<intptr_t>(handle));
86 #elif defined(OS_POSIX)
87 handle;
88 #else
89 #error Not implemented.
90 #endif
91 buffers[i].handle =
92 dispatcher->ShareHandleWithRemote(platform_file, false);
93 }
94 }
95 dispatcher->Send(new PpapiMsg_PPPVideoCapture_OnDeviceInfo(
96 INTERFACE_ID_PPP_VIDEO_CAPTURE_DEV, host_resource, *info, buffers));
97 }
98
99 void OnStatus(PP_Instance instance, PP_Resource resource, uint32_t status) {
100 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
101 if (!dispatcher) {
102 NOTREACHED();
103 return;
104 }
105 HostResource host_resource;
106 host_resource.SetHostResource(instance, resource);
107 dispatcher->Send(new PpapiMsg_PPPVideoCapture_OnStatus(
108 INTERFACE_ID_PPP_VIDEO_CAPTURE_DEV, host_resource, status));
109 }
110
111 void OnError(PP_Instance instance, PP_Resource resource, uint32_t error_code) {
112 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
113 if (!dispatcher) {
114 NOTREACHED();
115 return;
116 }
117 HostResource host_resource;
118 host_resource.SetHostResource(instance, resource);
119 dispatcher->Send(new PpapiMsg_PPPVideoCapture_OnError(
120 INTERFACE_ID_PPP_VIDEO_CAPTURE_DEV, host_resource, error_code));
121 }
122
123 void OnBufferReady(PP_Instance instance,
124 PP_Resource resource,
125 uint32_t buffer) {
126 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
127 if (!dispatcher) {
128 NOTREACHED();
129 return;
130 }
131 HostResource host_resource;
132 host_resource.SetHostResource(instance, resource);
133 dispatcher->Send(new PpapiMsg_PPPVideoCapture_OnBufferReady(
134 INTERFACE_ID_PPP_VIDEO_CAPTURE_DEV, host_resource, buffer));
135 }
136
137 PPP_VideoCapture_Dev ppp_video_capture = {
138 OnDeviceInfo,
139 OnStatus,
140 OnError,
141 OnBufferReady
142 };
143
144 } // namespace
145
146 class VideoCapture : public ppapi::thunk::PPB_VideoCapture_API,
147 public PluginResource {
148 public:
149 VideoCapture(const HostResource& resource);
150 virtual ~VideoCapture();
151
152 // Resource overrides.
153 virtual VideoCapture* AsVideoCapture() OVERRIDE;
154
155 // ResourceObjectBase overrides.
156 virtual ppapi::thunk::PPB_VideoCapture_API* AsPPB_VideoCapture_API() OVERRIDE;
157
158 // PPB_VideoCapture_API implementation.
159 virtual int32_t StartCapture(
160 const PP_VideoCaptureDeviceInfo_Dev& requested_info,
161 uint32_t buffer_count) {
162 switch (status_) {
163 case PP_VIDEO_CAPTURE_STATUS_STARTING:
164 case PP_VIDEO_CAPTURE_STATUS_STARTED:
165 case PP_VIDEO_CAPTURE_STATUS_PAUSED:
166 default:
167 return PP_ERROR_FAILED;
168 case PP_VIDEO_CAPTURE_STATUS_STOPPED:
169 case PP_VIDEO_CAPTURE_STATUS_STOPPING:
170 break;
171 }
172 status_ = PP_VIDEO_CAPTURE_STATUS_STARTING;
173 GetDispatcher()->Send(new PpapiHostMsg_PPBVideoCapture_StartCapture(
174 INTERFACE_ID_PPB_VIDEO_CAPTURE_DEV, host_resource(),
175 requested_info, buffer_count));
176 return PP_OK;
177 }
178
179 virtual int32_t ReuseBuffer(uint32_t buffer) {
180 if (buffer >= buffer_in_use_.size() || !buffer_in_use_[buffer])
181 return PP_ERROR_BADARGUMENT;
182 GetDispatcher()->Send(new PpapiHostMsg_PPBVideoCapture_ReuseBuffer(
183 INTERFACE_ID_PPB_VIDEO_CAPTURE_DEV, host_resource(), buffer));
184 return PP_OK;
185 }
186
187 virtual int32_t StopCapture() {
188 switch (status_) {
189 case PP_VIDEO_CAPTURE_STATUS_STOPPED:
190 case PP_VIDEO_CAPTURE_STATUS_STOPPING:
191 default:
192 return PP_ERROR_FAILED;
193 case PP_VIDEO_CAPTURE_STATUS_STARTING:
194 case PP_VIDEO_CAPTURE_STATUS_STARTED:
195 case PP_VIDEO_CAPTURE_STATUS_PAUSED:
196 break;
197 }
198 buffer_in_use_.clear();
199 status_ = PP_VIDEO_CAPTURE_STATUS_STOPPING;
200 GetDispatcher()->Send(new PpapiHostMsg_PPBVideoCapture_StopCapture(
201 INTERFACE_ID_PPB_VIDEO_CAPTURE_DEV, host_resource()));
202 return PP_OK;
203 }
204
205 bool OnStatus(uint32_t status) {
206 switch (status) {
207 case PP_VIDEO_CAPTURE_STATUS_STARTING:
208 case PP_VIDEO_CAPTURE_STATUS_STOPPING:
209 default:
210 // Those states are not sent by the browser.
211 NOTREACHED();
212 return false;
213 case PP_VIDEO_CAPTURE_STATUS_STARTED:
214 switch (status_) {
215 case PP_VIDEO_CAPTURE_STATUS_STARTING:
216 case PP_VIDEO_CAPTURE_STATUS_PAUSED:
217 break;
218 default:
219 return false;
220 }
221 break;
222 case PP_VIDEO_CAPTURE_STATUS_PAUSED:
223 switch (status_) {
224 case PP_VIDEO_CAPTURE_STATUS_STARTING:
225 case PP_VIDEO_CAPTURE_STATUS_STARTED:
226 break;
227 default:
228 return false;
229 }
230 break;
231 case PP_VIDEO_CAPTURE_STATUS_STOPPED:
232 if (status_ != PP_VIDEO_CAPTURE_STATUS_STOPPING)
233 return false;
234 break;
235 }
236 status_ = status;
237 return true;
238 }
239
240 void set_status(uint32_t status) { status_ = status; }
241
242 void SetBufferCount(size_t count) {
243 buffer_in_use_ = std::vector<bool>(count);
244 }
245 void SetBufferInUse(uint32_t buffer) {
246 DCHECK(buffer < buffer_in_use_.size());
247 buffer_in_use_[buffer] = true;
248 }
249
250 private:
251 uint32_t status_;
252 std::vector<bool> buffer_in_use_;
253 DISALLOW_COPY_AND_ASSIGN(VideoCapture);
254 };
255
256 VideoCapture::VideoCapture(const HostResource& resource)
257 : PluginResource(resource),
258 status_(PP_VIDEO_CAPTURE_STATUS_STOPPED) {
259 }
260
261 VideoCapture::~VideoCapture() {
262 }
263
264 VideoCapture* VideoCapture::AsVideoCapture() {
265 return this;
266 }
267
268 ppapi::thunk::PPB_VideoCapture_API* VideoCapture::AsPPB_VideoCapture_API() {
269 return this;
270 }
271
272 PPB_VideoCapture_Proxy::PPB_VideoCapture_Proxy(Dispatcher* dispatcher,
273 const void* target_interface)
274 : InterfaceProxy(dispatcher, target_interface) {
275 }
276
277 PPB_VideoCapture_Proxy::~PPB_VideoCapture_Proxy() {
278 }
279
280 // static
281 const InterfaceProxy::Info* PPB_VideoCapture_Proxy::GetInfo() {
282 static const Info info = {
283 ppapi::thunk::GetPPB_VideoCapture_Thunk(),
284 PPB_VIDEO_CAPTURE_DEV_INTERFACE,
285 INTERFACE_ID_PPB_VIDEO_CAPTURE_DEV,
286 false,
287 &CreatePPBVideoCaptureProxy,
288 };
289 return &info;
290 }
291
292 // static
293 PP_Resource PPB_VideoCapture_Proxy::CreateProxyResource(PP_Instance instance) {
294 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
295 if (!dispatcher)
296 return 0;
297
298 HostResource result;
299 dispatcher->Send(new PpapiHostMsg_PPBVideoCapture_Create(
300 INTERFACE_ID_PPB_VIDEO_CAPTURE_DEV, instance, &result));
301 if (result.is_null())
302 return 0;
303
304 linked_ptr<VideoCapture> object(new VideoCapture(result));
305 return PluginResourceTracker::GetInstance()->AddResource(object);
306 }
307
308 bool PPB_VideoCapture_Proxy::OnMessageReceived(const IPC::Message& msg) {
309 bool handled = true;
310 IPC_BEGIN_MESSAGE_MAP(PPB_VideoCapture_Proxy, msg)
311 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoCapture_Create, OnMsgCreate)
312 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoCapture_StartCapture,
313 OnMsgStartCapture)
314 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoCapture_ReuseBuffer,
315 OnMsgReuseBuffer)
316 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoCapture_StopCapture,
317 OnMsgStopCapture)
318 IPC_MESSAGE_UNHANDLED(handled = false)
319 IPC_END_MESSAGE_MAP()
320 // TODO(brettw) handle bad messages!
321 return handled;
322 }
323
324 void PPB_VideoCapture_Proxy::OnMsgCreate(PP_Instance instance,
325 HostResource* result_resource) {
326 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
327 if (!dispatcher)
328 return;
329 PP_Resource resource = ppb_video_capture_target()->Create(instance);
330 result_resource->SetHostResource(instance, resource);
331 }
332
333 void PPB_VideoCapture_Proxy::OnMsgStartCapture(
334 const HostResource& resource,
335 const PP_VideoCaptureDeviceInfo_Dev& info,
336 uint32_t buffers) {
337 EnterHostFromHostResource<PPB_VideoCapture_API> enter(resource);
338 if (enter.succeeded())
339 enter.object()->StartCapture(info, buffers);
340 }
341
342 void PPB_VideoCapture_Proxy::OnMsgReuseBuffer(const HostResource& resource,
343 uint32_t buffer) {
344 EnterHostFromHostResource<PPB_VideoCapture_API> enter(resource);
345 if (enter.succeeded())
346 enter.object()->ReuseBuffer(buffer);
347 }
348
349 void PPB_VideoCapture_Proxy::OnMsgStopCapture(const HostResource& resource) {
350 EnterHostFromHostResource<PPB_VideoCapture_API> enter(resource);
351 if (enter.succeeded())
352 enter.object()->StopCapture();
353 }
354
355 PPP_VideoCapture_Proxy::PPP_VideoCapture_Proxy(Dispatcher* dispatcher,
356 const void* target_interface)
357 : InterfaceProxy(dispatcher, target_interface) {
358 }
359
360 PPP_VideoCapture_Proxy::~PPP_VideoCapture_Proxy() {
361 }
362
363 // static
364 const InterfaceProxy::Info* PPP_VideoCapture_Proxy::GetInfo() {
365 static const Info info = {
366 &ppp_video_capture,
367 PPP_VIDEO_CAPTURE_DEV_INTERFACE,
368 INTERFACE_ID_PPP_VIDEO_CAPTURE_DEV,
369 false,
370 &CreatePPPVideoCaptureProxy,
371 };
372 return &info;
373 }
374
375 bool PPP_VideoCapture_Proxy::OnMessageReceived(const IPC::Message& msg) {
376 bool handled = true;
377 IPC_BEGIN_MESSAGE_MAP(PPP_VideoCapture_Proxy, msg)
378 IPC_MESSAGE_HANDLER(PpapiMsg_PPPVideoCapture_OnDeviceInfo,
379 OnMsgOnDeviceInfo)
380 IPC_MESSAGE_HANDLER(PpapiMsg_PPPVideoCapture_OnStatus, OnMsgOnStatus)
381 IPC_MESSAGE_HANDLER(PpapiMsg_PPPVideoCapture_OnError, OnMsgOnError)
382 IPC_MESSAGE_HANDLER(PpapiMsg_PPPVideoCapture_OnBufferReady,
383 OnMsgOnBufferReady)
384 IPC_MESSAGE_UNHANDLED(handled = false)
385 IPC_END_MESSAGE_MAP()
386 // TODO(brettw) handle bad messages!
387 return handled;
388 }
389
390 void PPP_VideoCapture_Proxy::OnMsgOnDeviceInfo(
391 const HostResource& host_resource,
392 const PP_VideoCaptureDeviceInfo_Dev& info,
393 const std::vector<PPPVideoCapture_Buffer>& buffers) {
394 EnterPluginFromHostResource<PPB_VideoCapture_API> enter(host_resource);
395 PluginResourceTracker* tracker = PluginResourceTracker::GetInstance();
396 PP_Resource resource = tracker->PluginResourceForHostResource(host_resource);
397 if (!resource || !ppp_video_capture_target() || enter.failed())
398 return;
399
400 scoped_array<PP_Resource> resources(new PP_Resource[buffers.size()]);
401 for (size_t i = 0; i < buffers.size(); ++i) {
402 // We assume that the browser created a new set of resources.
403 DCHECK(!tracker->PluginResourceForHostResource(buffers[i].resource));
404 resources[i] = PPB_Buffer_Proxy::AddProxyResource(buffers[i].resource,
405 buffers[i].handle,
406 buffers[i].size);
407 }
408 static_cast<VideoCapture*>(enter.object())->SetBufferCount(buffers.size());
409 ppp_video_capture_target()->OnDeviceInfo(
410 host_resource.instance(),
411 resource,
412 &info,
413 buffers.size(),
414 resources.get());
415 for (size_t i = 0; i < buffers.size(); ++i)
416 tracker->ReleaseResource(resources[i]);
417 }
418
419 void PPP_VideoCapture_Proxy::OnMsgOnStatus(const HostResource& host_resource,
420 uint32_t status) {
421 EnterPluginFromHostResource<PPB_VideoCapture_API> enter(host_resource);
422 PluginResourceTracker* tracker = PluginResourceTracker::GetInstance();
423 PP_Resource resource = tracker->PluginResourceForHostResource(host_resource);
424 if (!resource || !ppp_video_capture_target() || enter.failed())
425 return;
426
427 if (!static_cast<VideoCapture*>(enter.object())->OnStatus(status))
428 return;
429 ppp_video_capture_target()->OnStatus(
430 host_resource.instance(), resource, status);
431 }
432
433 void PPP_VideoCapture_Proxy::OnMsgOnError(const HostResource& host_resource,
434 uint32_t error_code) {
435 EnterPluginFromHostResource<PPB_VideoCapture_API> enter(host_resource);
436 PluginResourceTracker* tracker = PluginResourceTracker::GetInstance();
437 PP_Resource resource = tracker->PluginResourceForHostResource(host_resource);
438 if (!resource || !ppp_video_capture_target() || enter.failed())
439 return;
440 static_cast<VideoCapture*>(enter.object())->set_status(
441 PP_VIDEO_CAPTURE_STATUS_STOPPED);
442 ppp_video_capture_target()->OnError(
443 host_resource.instance(), resource, error_code);
444 }
445
446 void PPP_VideoCapture_Proxy::OnMsgOnBufferReady(
447 const HostResource& host_resource, uint32_t buffer) {
448 EnterPluginFromHostResource<PPB_VideoCapture_API> enter(host_resource);
449 PluginResourceTracker* tracker = PluginResourceTracker::GetInstance();
450 PP_Resource resource = tracker->PluginResourceForHostResource(host_resource);
451 if (!resource || !ppp_video_capture_target() || enter.failed())
452 return;
453 static_cast<VideoCapture*>(enter.object())->SetBufferInUse(buffer);
454 ppp_video_capture_target()->OnBufferReady(
455 host_resource.instance(), resource, buffer);
456 }
457
458 } // namespace proxy
459 } // namespace pp
OLDNEW
« no previous file with comments | « ppapi/proxy/ppb_video_capture_proxy.h ('k') | ppapi/proxy/resource_creation_proxy.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698