| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include "ppapi/proxy/ppb_video_capture_proxy.h" | |
| 6 | |
| 7 #include "base/compiler_specific.h" | |
| 8 #include "base/logging.h" | |
| 9 #include "build/build_config.h" | |
| 10 #include "ppapi/c/pp_errors.h" | |
| 11 #include "ppapi/c/pp_resource.h" | |
| 12 #include "ppapi/c/ppb_core.h" | |
| 13 #include "ppapi/c/dev/ppb_video_capture_dev.h" | |
| 14 #include "ppapi/proxy/enter_proxy.h" | |
| 15 #include "ppapi/proxy/host_dispatcher.h" | |
| 16 #include "ppapi/proxy/plugin_dispatcher.h" | |
| 17 #include "ppapi/proxy/ppapi_messages.h" | |
| 18 #include "ppapi/proxy/ppb_buffer_proxy.h" | |
| 19 #include "ppapi/shared_impl/ppapi_globals.h" | |
| 20 #include "ppapi/shared_impl/ppb_video_capture_shared.h" | |
| 21 #include "ppapi/shared_impl/resource_tracker.h" | |
| 22 #include "ppapi/shared_impl/tracked_callback.h" | |
| 23 #include "ppapi/thunk/ppb_buffer_api.h" | |
| 24 #include "ppapi/thunk/ppb_buffer_trusted_api.h" | |
| 25 #include "ppapi/thunk/ppb_video_capture_api.h" | |
| 26 #include "ppapi/thunk/resource_creation_api.h" | |
| 27 #include "ppapi/thunk/thunk.h" | |
| 28 | |
| 29 using ppapi::thunk::EnterResourceNoLock; | |
| 30 using ppapi::thunk::PPB_Buffer_API; | |
| 31 using ppapi::thunk::PPB_BufferTrusted_API; | |
| 32 using ppapi::thunk::PPB_VideoCapture_API; | |
| 33 | |
| 34 namespace ppapi { | |
| 35 namespace proxy { | |
| 36 | |
| 37 namespace { | |
| 38 | |
| 39 InterfaceProxy* CreatePPPVideoCaptureProxy(Dispatcher* dispatcher) { | |
| 40 return new PPP_VideoCapture_Proxy(dispatcher); | |
| 41 } | |
| 42 | |
| 43 void OnDeviceInfo(PP_Instance instance, | |
| 44 PP_Resource resource, | |
| 45 const PP_VideoCaptureDeviceInfo_Dev* info, | |
| 46 uint32_t buffer_count, | |
| 47 const PP_Resource resources[]) { | |
| 48 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); | |
| 49 if (!dispatcher) { | |
| 50 NOTREACHED(); | |
| 51 return; | |
| 52 } | |
| 53 HostResource host_resource; | |
| 54 host_resource.SetHostResource(instance, resource); | |
| 55 std::vector<PPPVideoCapture_Buffer> buffers(buffer_count); | |
| 56 const PPB_Core* core = static_cast<const PPB_Core*>( | |
| 57 dispatcher->local_get_interface()(PPB_CORE_INTERFACE)); | |
| 58 DCHECK(core); | |
| 59 for (uint32_t i = 0; i < buffer_count; ++i) { | |
| 60 // We need to take a ref on the resource now. The browser may drop | |
| 61 // references once we return from here, but we're sending an asynchronous | |
| 62 // message. The plugin side takes ownership of that reference. | |
| 63 core->AddRefResource(resources[i]); | |
| 64 buffers[i].resource.SetHostResource(instance, resources[i]); | |
| 65 { | |
| 66 EnterResourceNoLock<PPB_Buffer_API> enter(resources[i], true); | |
| 67 DCHECK(enter.succeeded()); | |
| 68 PP_Bool result = enter.object()->Describe(&buffers[i].size); | |
| 69 DCHECK(result); | |
| 70 } | |
| 71 { | |
| 72 EnterResourceNoLock<PPB_BufferTrusted_API> enter(resources[i], true); | |
| 73 DCHECK(enter.succeeded()); | |
| 74 int handle; | |
| 75 int32_t result = enter.object()->GetSharedMemory(&handle); | |
| 76 DCHECK(result == PP_OK); | |
| 77 // TODO(piman/brettw): Change trusted interface to return a PP_FileHandle, | |
| 78 // those casts are ugly. | |
| 79 base::PlatformFile platform_file = | |
| 80 #if defined(OS_WIN) | |
| 81 reinterpret_cast<HANDLE>(static_cast<intptr_t>(handle)); | |
| 82 #elif defined(OS_POSIX) | |
| 83 handle; | |
| 84 #else | |
| 85 #error Not implemented. | |
| 86 #endif | |
| 87 buffers[i].handle = | |
| 88 dispatcher->ShareHandleWithRemote(platform_file, false); | |
| 89 } | |
| 90 } | |
| 91 dispatcher->Send(new PpapiMsg_PPPVideoCapture_OnDeviceInfo( | |
| 92 API_ID_PPP_VIDEO_CAPTURE_DEV, host_resource, *info, buffers)); | |
| 93 } | |
| 94 | |
| 95 void OnStatus(PP_Instance instance, PP_Resource resource, uint32_t status) { | |
| 96 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); | |
| 97 if (!dispatcher) { | |
| 98 NOTREACHED(); | |
| 99 return; | |
| 100 } | |
| 101 HostResource host_resource; | |
| 102 host_resource.SetHostResource(instance, resource); | |
| 103 dispatcher->Send(new PpapiMsg_PPPVideoCapture_OnStatus( | |
| 104 API_ID_PPP_VIDEO_CAPTURE_DEV, host_resource, status)); | |
| 105 } | |
| 106 | |
| 107 void OnError(PP_Instance instance, PP_Resource resource, uint32_t error_code) { | |
| 108 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); | |
| 109 if (!dispatcher) { | |
| 110 NOTREACHED(); | |
| 111 return; | |
| 112 } | |
| 113 HostResource host_resource; | |
| 114 host_resource.SetHostResource(instance, resource); | |
| 115 dispatcher->Send(new PpapiMsg_PPPVideoCapture_OnError( | |
| 116 API_ID_PPP_VIDEO_CAPTURE_DEV, host_resource, error_code)); | |
| 117 } | |
| 118 | |
| 119 void OnBufferReady(PP_Instance instance, | |
| 120 PP_Resource resource, | |
| 121 uint32_t buffer) { | |
| 122 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); | |
| 123 if (!dispatcher) { | |
| 124 NOTREACHED(); | |
| 125 return; | |
| 126 } | |
| 127 HostResource host_resource; | |
| 128 host_resource.SetHostResource(instance, resource); | |
| 129 dispatcher->Send(new PpapiMsg_PPPVideoCapture_OnBufferReady( | |
| 130 API_ID_PPP_VIDEO_CAPTURE_DEV, host_resource, buffer)); | |
| 131 } | |
| 132 | |
| 133 PPP_VideoCapture_Dev ppp_video_capture = { | |
| 134 OnDeviceInfo, | |
| 135 OnStatus, | |
| 136 OnError, | |
| 137 OnBufferReady | |
| 138 }; | |
| 139 | |
| 140 } // namespace | |
| 141 | |
| 142 class VideoCapture : public PPB_VideoCapture_Shared { | |
| 143 public: | |
| 144 explicit VideoCapture(const HostResource& resource); | |
| 145 virtual ~VideoCapture(); | |
| 146 | |
| 147 bool OnStatus(PP_VideoCaptureStatus_Dev status); | |
| 148 | |
| 149 void set_status(PP_VideoCaptureStatus_Dev status) { | |
| 150 SetStatus(status, true); | |
| 151 } | |
| 152 | |
| 153 void SetBufferCount(size_t count) { | |
| 154 buffer_in_use_ = std::vector<bool>(count); | |
| 155 } | |
| 156 | |
| 157 void SetBufferInUse(uint32_t buffer) { | |
| 158 DCHECK(buffer < buffer_in_use_.size()); | |
| 159 buffer_in_use_[buffer] = true; | |
| 160 } | |
| 161 | |
| 162 private: | |
| 163 // PPB_VideoCapture_Shared implementation. | |
| 164 virtual int32_t InternalEnumerateDevices( | |
| 165 PP_Resource* devices, | |
| 166 scoped_refptr<TrackedCallback> callback) OVERRIDE; | |
| 167 virtual int32_t InternalOpen( | |
| 168 const std::string& device_id, | |
| 169 const PP_VideoCaptureDeviceInfo_Dev& requested_info, | |
| 170 uint32_t buffer_count, | |
| 171 scoped_refptr<TrackedCallback> callback) OVERRIDE; | |
| 172 virtual int32_t InternalStartCapture() OVERRIDE; | |
| 173 virtual int32_t InternalReuseBuffer(uint32_t buffer) OVERRIDE; | |
| 174 virtual int32_t InternalStopCapture() OVERRIDE; | |
| 175 virtual void InternalClose() OVERRIDE; | |
| 176 virtual int32_t InternalStartCapture0_1( | |
| 177 const PP_VideoCaptureDeviceInfo_Dev& requested_info, | |
| 178 uint32_t buffer_count) OVERRIDE; | |
| 179 virtual const std::vector<DeviceRefData>& | |
| 180 InternalGetDeviceRefData() const OVERRIDE; | |
| 181 | |
| 182 PluginDispatcher* GetDispatcher() const { | |
| 183 return PluginDispatcher::GetForResource(this); | |
| 184 } | |
| 185 | |
| 186 std::vector<bool> buffer_in_use_; | |
| 187 | |
| 188 DISALLOW_COPY_AND_ASSIGN(VideoCapture); | |
| 189 }; | |
| 190 | |
| 191 VideoCapture::VideoCapture(const HostResource& resource) | |
| 192 : PPB_VideoCapture_Shared(resource) { | |
| 193 } | |
| 194 | |
| 195 VideoCapture::~VideoCapture() { | |
| 196 Close(); | |
| 197 } | |
| 198 | |
| 199 bool VideoCapture::OnStatus(PP_VideoCaptureStatus_Dev status) { | |
| 200 switch (status) { | |
| 201 case PP_VIDEO_CAPTURE_STATUS_STARTED: | |
| 202 case PP_VIDEO_CAPTURE_STATUS_PAUSED: | |
| 203 case PP_VIDEO_CAPTURE_STATUS_STOPPED: | |
| 204 return SetStatus(status, false); | |
| 205 case PP_VIDEO_CAPTURE_STATUS_STARTING: | |
| 206 case PP_VIDEO_CAPTURE_STATUS_STOPPING: | |
| 207 // Those states are not sent by the browser. | |
| 208 break; | |
| 209 } | |
| 210 | |
| 211 NOTREACHED(); | |
| 212 return false; | |
| 213 } | |
| 214 | |
| 215 int32_t VideoCapture::InternalEnumerateDevices( | |
| 216 PP_Resource* devices, | |
| 217 scoped_refptr<TrackedCallback> callback) { | |
| 218 devices_ = devices; | |
| 219 enumerate_devices_callback_ = callback; | |
| 220 GetDispatcher()->Send(new PpapiHostMsg_PPBVideoCapture_EnumerateDevices( | |
| 221 API_ID_PPB_VIDEO_CAPTURE_DEV, host_resource())); | |
| 222 return PP_OK_COMPLETIONPENDING; | |
| 223 } | |
| 224 | |
| 225 int32_t VideoCapture::InternalOpen( | |
| 226 const std::string& device_id, | |
| 227 const PP_VideoCaptureDeviceInfo_Dev& requested_info, | |
| 228 uint32_t buffer_count, | |
| 229 scoped_refptr<TrackedCallback> callback) { | |
| 230 open_callback_ = callback; | |
| 231 GetDispatcher()->Send(new PpapiHostMsg_PPBVideoCapture_Open( | |
| 232 API_ID_PPB_VIDEO_CAPTURE_DEV, host_resource(), device_id, requested_info, | |
| 233 buffer_count)); | |
| 234 return PP_OK_COMPLETIONPENDING; | |
| 235 } | |
| 236 | |
| 237 int32_t VideoCapture::InternalStartCapture() { | |
| 238 buffer_in_use_.clear(); | |
| 239 GetDispatcher()->Send(new PpapiHostMsg_PPBVideoCapture_StartCapture( | |
| 240 API_ID_PPB_VIDEO_CAPTURE_DEV, host_resource())); | |
| 241 return PP_OK; | |
| 242 } | |
| 243 | |
| 244 int32_t VideoCapture::InternalReuseBuffer(uint32_t buffer) { | |
| 245 if (buffer >= buffer_in_use_.size() || !buffer_in_use_[buffer]) | |
| 246 return PP_ERROR_BADARGUMENT; | |
| 247 GetDispatcher()->Send(new PpapiHostMsg_PPBVideoCapture_ReuseBuffer( | |
| 248 API_ID_PPB_VIDEO_CAPTURE_DEV, host_resource(), buffer)); | |
| 249 return PP_OK; | |
| 250 } | |
| 251 | |
| 252 int32_t VideoCapture::InternalStopCapture() { | |
| 253 GetDispatcher()->Send(new PpapiHostMsg_PPBVideoCapture_StopCapture( | |
| 254 API_ID_PPB_VIDEO_CAPTURE_DEV, host_resource())); | |
| 255 return PP_OK; | |
| 256 } | |
| 257 | |
| 258 void VideoCapture::InternalClose() { | |
| 259 GetDispatcher()->Send(new PpapiHostMsg_PPBVideoCapture_Close( | |
| 260 API_ID_PPB_VIDEO_CAPTURE_DEV, host_resource())); | |
| 261 } | |
| 262 | |
| 263 int32_t VideoCapture::InternalStartCapture0_1( | |
| 264 const PP_VideoCaptureDeviceInfo_Dev& requested_info, | |
| 265 uint32_t buffer_count) { | |
| 266 buffer_in_use_.clear(); | |
| 267 GetDispatcher()->Send(new PpapiHostMsg_PPBVideoCapture_StartCapture0_1( | |
| 268 API_ID_PPB_VIDEO_CAPTURE_DEV, host_resource(), requested_info, | |
| 269 buffer_count)); | |
| 270 return PP_OK; | |
| 271 } | |
| 272 | |
| 273 const std::vector<DeviceRefData>& | |
| 274 VideoCapture::InternalGetDeviceRefData() const { | |
| 275 // This should never be called at the plugin side. | |
| 276 NOTREACHED(); | |
| 277 static std::vector<DeviceRefData> result; | |
| 278 return result; | |
| 279 } | |
| 280 | |
| 281 PPB_VideoCapture_Proxy::PPB_VideoCapture_Proxy(Dispatcher* dispatcher) | |
| 282 : InterfaceProxy(dispatcher), | |
| 283 ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)) { | |
| 284 } | |
| 285 | |
| 286 PPB_VideoCapture_Proxy::~PPB_VideoCapture_Proxy() { | |
| 287 } | |
| 288 | |
| 289 // static | |
| 290 PP_Resource PPB_VideoCapture_Proxy::CreateProxyResource(PP_Instance instance) { | |
| 291 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); | |
| 292 if (!dispatcher) | |
| 293 return 0; | |
| 294 | |
| 295 HostResource result; | |
| 296 dispatcher->Send(new PpapiHostMsg_PPBVideoCapture_Create( | |
| 297 API_ID_PPB_VIDEO_CAPTURE_DEV, instance, &result)); | |
| 298 if (result.is_null()) | |
| 299 return 0; | |
| 300 return (new VideoCapture(result))->GetReference(); | |
| 301 } | |
| 302 | |
| 303 bool PPB_VideoCapture_Proxy::OnMessageReceived(const IPC::Message& msg) { | |
| 304 bool handled = true; | |
| 305 IPC_BEGIN_MESSAGE_MAP(PPB_VideoCapture_Proxy, msg) | |
| 306 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoCapture_Create, OnMsgCreate) | |
| 307 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoCapture_EnumerateDevices, | |
| 308 OnMsgEnumerateDevices) | |
| 309 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoCapture_Open, OnMsgOpen) | |
| 310 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoCapture_StartCapture, | |
| 311 OnMsgStartCapture) | |
| 312 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoCapture_ReuseBuffer, | |
| 313 OnMsgReuseBuffer) | |
| 314 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoCapture_StopCapture, | |
| 315 OnMsgStopCapture) | |
| 316 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoCapture_Close, OnMsgClose) | |
| 317 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoCapture_StartCapture0_1, | |
| 318 OnMsgStartCapture0_1) | |
| 319 | |
| 320 IPC_MESSAGE_HANDLER(PpapiMsg_PPBVideoCapture_EnumerateDevicesACK, | |
| 321 OnMsgEnumerateDevicesACK) | |
| 322 IPC_MESSAGE_HANDLER(PpapiMsg_PPBVideoCapture_OpenACK, | |
| 323 OnMsgOpenACK) | |
| 324 IPC_MESSAGE_UNHANDLED(handled = false) | |
| 325 IPC_END_MESSAGE_MAP() | |
| 326 // TODO(brettw) handle bad messages! | |
| 327 return handled; | |
| 328 } | |
| 329 | |
| 330 void PPB_VideoCapture_Proxy::OnMsgCreate(PP_Instance instance, | |
| 331 HostResource* result_resource) { | |
| 332 thunk::EnterResourceCreation enter(instance); | |
| 333 if (enter.succeeded()) { | |
| 334 result_resource->SetHostResource( | |
| 335 instance, | |
| 336 enter.functions()->CreateVideoCapture(instance)); | |
| 337 } | |
| 338 } | |
| 339 | |
| 340 void PPB_VideoCapture_Proxy::OnMsgEnumerateDevices( | |
| 341 const HostResource& resource) { | |
| 342 EnterHostFromHostResourceForceCallback<PPB_VideoCapture_API> enter( | |
| 343 resource, callback_factory_, | |
| 344 &PPB_VideoCapture_Proxy::EnumerateDevicesACKInHost, resource); | |
| 345 | |
| 346 if (enter.succeeded()) | |
| 347 enter.SetResult(enter.object()->EnumerateDevices(NULL, enter.callback())); | |
| 348 } | |
| 349 | |
| 350 void PPB_VideoCapture_Proxy::OnMsgOpen( | |
| 351 const ppapi::HostResource& resource, | |
| 352 const std::string& device_id, | |
| 353 const PP_VideoCaptureDeviceInfo_Dev& info, | |
| 354 uint32_t buffers) { | |
| 355 EnterHostFromHostResourceForceCallback<PPB_VideoCapture_API> enter( | |
| 356 resource, callback_factory_, &PPB_VideoCapture_Proxy::OpenACKInHost, | |
| 357 resource); | |
| 358 | |
| 359 if (enter.succeeded()) { | |
| 360 enter.SetResult(enter.object()->Open(device_id, info, buffers, | |
| 361 enter.callback())); | |
| 362 } | |
| 363 } | |
| 364 | |
| 365 void PPB_VideoCapture_Proxy::OnMsgStartCapture(const HostResource& resource) { | |
| 366 EnterHostFromHostResource<PPB_VideoCapture_API> enter(resource); | |
| 367 if (enter.succeeded()) | |
| 368 enter.object()->StartCapture(); | |
| 369 } | |
| 370 | |
| 371 void PPB_VideoCapture_Proxy::OnMsgReuseBuffer(const HostResource& resource, | |
| 372 uint32_t buffer) { | |
| 373 EnterHostFromHostResource<PPB_VideoCapture_API> enter(resource); | |
| 374 if (enter.succeeded()) | |
| 375 enter.object()->ReuseBuffer(buffer); | |
| 376 } | |
| 377 | |
| 378 void PPB_VideoCapture_Proxy::OnMsgStopCapture(const HostResource& resource) { | |
| 379 EnterHostFromHostResource<PPB_VideoCapture_API> enter(resource); | |
| 380 if (enter.succeeded()) | |
| 381 enter.object()->StopCapture(); | |
| 382 } | |
| 383 | |
| 384 void PPB_VideoCapture_Proxy::OnMsgClose(const HostResource& resource) { | |
| 385 EnterHostFromHostResource<PPB_VideoCapture_API> enter(resource); | |
| 386 if (enter.succeeded()) | |
| 387 enter.object()->Close(); | |
| 388 } | |
| 389 | |
| 390 void PPB_VideoCapture_Proxy::OnMsgStartCapture0_1( | |
| 391 const HostResource& resource, | |
| 392 const PP_VideoCaptureDeviceInfo_Dev& info, | |
| 393 uint32_t buffers) { | |
| 394 EnterHostFromHostResource<PPB_VideoCapture_API> enter(resource); | |
| 395 if (enter.succeeded()) | |
| 396 enter.object()->StartCapture0_1(info, buffers); | |
| 397 } | |
| 398 | |
| 399 void PPB_VideoCapture_Proxy::OnMsgEnumerateDevicesACK( | |
| 400 const HostResource& resource, | |
| 401 int32_t result, | |
| 402 const std::vector<ppapi::DeviceRefData>& devices) { | |
| 403 EnterPluginFromHostResource<PPB_VideoCapture_API> enter(resource); | |
| 404 if (enter.succeeded()) { | |
| 405 static_cast<VideoCapture*>(enter.object())->OnEnumerateDevicesComplete( | |
| 406 result, devices); | |
| 407 } | |
| 408 } | |
| 409 | |
| 410 void PPB_VideoCapture_Proxy::OnMsgOpenACK( | |
| 411 const HostResource& resource, | |
| 412 int32_t result) { | |
| 413 EnterPluginFromHostResource<PPB_VideoCapture_API> enter(resource); | |
| 414 if (enter.succeeded()) | |
| 415 static_cast<VideoCapture*>(enter.object())->OnOpenComplete(result); | |
| 416 } | |
| 417 | |
| 418 void PPB_VideoCapture_Proxy::EnumerateDevicesACKInHost( | |
| 419 int32_t result, | |
| 420 const HostResource& resource) { | |
| 421 EnterHostFromHostResource<PPB_VideoCapture_API> enter(resource); | |
| 422 dispatcher()->Send(new PpapiMsg_PPBVideoCapture_EnumerateDevicesACK( | |
| 423 API_ID_PPB_VIDEO_CAPTURE_DEV, resource, result, | |
| 424 enter.succeeded() && result == PP_OK ? | |
| 425 enter.object()->GetDeviceRefData() : std::vector<DeviceRefData>())); | |
| 426 } | |
| 427 | |
| 428 void PPB_VideoCapture_Proxy::OpenACKInHost(int32_t result, | |
| 429 const HostResource& resource) { | |
| 430 dispatcher()->Send(new PpapiMsg_PPBVideoCapture_OpenACK( | |
| 431 API_ID_PPB_VIDEO_CAPTURE_DEV, resource, result)); | |
| 432 } | |
| 433 | |
| 434 PPP_VideoCapture_Proxy::PPP_VideoCapture_Proxy(Dispatcher* dispatcher) | |
| 435 : InterfaceProxy(dispatcher), | |
| 436 ppp_video_capture_impl_(NULL) { | |
| 437 if (dispatcher->IsPlugin()) { | |
| 438 ppp_video_capture_impl_ = static_cast<const PPP_VideoCapture_Dev*>( | |
| 439 dispatcher->local_get_interface()(PPP_VIDEO_CAPTURE_DEV_INTERFACE)); | |
| 440 } | |
| 441 } | |
| 442 | |
| 443 PPP_VideoCapture_Proxy::~PPP_VideoCapture_Proxy() { | |
| 444 } | |
| 445 | |
| 446 // static | |
| 447 const InterfaceProxy::Info* PPP_VideoCapture_Proxy::GetInfo() { | |
| 448 static const Info info = { | |
| 449 &ppp_video_capture, | |
| 450 PPP_VIDEO_CAPTURE_DEV_INTERFACE, | |
| 451 API_ID_PPP_VIDEO_CAPTURE_DEV, | |
| 452 false, | |
| 453 &CreatePPPVideoCaptureProxy, | |
| 454 }; | |
| 455 return &info; | |
| 456 } | |
| 457 | |
| 458 bool PPP_VideoCapture_Proxy::OnMessageReceived(const IPC::Message& msg) { | |
| 459 bool handled = true; | |
| 460 IPC_BEGIN_MESSAGE_MAP(PPP_VideoCapture_Proxy, msg) | |
| 461 IPC_MESSAGE_HANDLER(PpapiMsg_PPPVideoCapture_OnDeviceInfo, | |
| 462 OnMsgOnDeviceInfo) | |
| 463 IPC_MESSAGE_HANDLER(PpapiMsg_PPPVideoCapture_OnStatus, OnMsgOnStatus) | |
| 464 IPC_MESSAGE_HANDLER(PpapiMsg_PPPVideoCapture_OnError, OnMsgOnError) | |
| 465 IPC_MESSAGE_HANDLER(PpapiMsg_PPPVideoCapture_OnBufferReady, | |
| 466 OnMsgOnBufferReady) | |
| 467 IPC_MESSAGE_UNHANDLED(handled = false) | |
| 468 IPC_END_MESSAGE_MAP() | |
| 469 // TODO(brettw) handle bad messages! | |
| 470 return handled; | |
| 471 } | |
| 472 | |
| 473 void PPP_VideoCapture_Proxy::OnMsgOnDeviceInfo( | |
| 474 const HostResource& host_resource, | |
| 475 const PP_VideoCaptureDeviceInfo_Dev& info, | |
| 476 const std::vector<PPPVideoCapture_Buffer>& buffers) { | |
| 477 EnterPluginFromHostResource<PPB_VideoCapture_API> enter(host_resource); | |
| 478 if (enter.failed() || !ppp_video_capture_impl_) | |
| 479 return; | |
| 480 | |
| 481 PluginResourceTracker* tracker = | |
| 482 PluginGlobals::Get()->plugin_resource_tracker(); | |
| 483 scoped_array<PP_Resource> resources(new PP_Resource[buffers.size()]); | |
| 484 for (size_t i = 0; i < buffers.size(); ++i) { | |
| 485 // We assume that the browser created a new set of resources. | |
| 486 DCHECK(!tracker->PluginResourceForHostResource(buffers[i].resource)); | |
| 487 resources[i] = PPB_Buffer_Proxy::AddProxyResource(buffers[i].resource, | |
| 488 buffers[i].handle, | |
| 489 buffers[i].size); | |
| 490 } | |
| 491 | |
| 492 VideoCapture* capture = static_cast<VideoCapture*>(enter.object()); | |
| 493 capture->SetBufferCount(buffers.size()); | |
| 494 ppp_video_capture_impl_->OnDeviceInfo( | |
| 495 host_resource.instance(), | |
| 496 capture->pp_resource(), | |
| 497 &info, | |
| 498 buffers.size(), | |
| 499 resources.get()); | |
| 500 for (size_t i = 0; i < buffers.size(); ++i) | |
| 501 tracker->ReleaseResource(resources[i]); | |
| 502 } | |
| 503 | |
| 504 void PPP_VideoCapture_Proxy::OnMsgOnStatus(const HostResource& host_resource, | |
| 505 uint32_t status) { | |
| 506 EnterPluginFromHostResource<PPB_VideoCapture_API> enter(host_resource); | |
| 507 if (enter.failed() || !ppp_video_capture_impl_) | |
| 508 return; | |
| 509 | |
| 510 VideoCapture* capture = static_cast<VideoCapture*>(enter.object()); | |
| 511 if (!capture->OnStatus(static_cast<PP_VideoCaptureStatus_Dev>(status))) | |
| 512 return; | |
| 513 ppp_video_capture_impl_->OnStatus( | |
| 514 host_resource.instance(), capture->pp_resource(), status); | |
| 515 } | |
| 516 | |
| 517 void PPP_VideoCapture_Proxy::OnMsgOnError(const HostResource& host_resource, | |
| 518 uint32_t error_code) { | |
| 519 EnterPluginFromHostResource<PPB_VideoCapture_API> enter(host_resource); | |
| 520 if (enter.failed() || !ppp_video_capture_impl_) | |
| 521 return; | |
| 522 | |
| 523 VideoCapture* capture = static_cast<VideoCapture*>(enter.object()); | |
| 524 capture->set_status(PP_VIDEO_CAPTURE_STATUS_STOPPED); | |
| 525 ppp_video_capture_impl_->OnError( | |
| 526 host_resource.instance(), capture->pp_resource(), error_code); | |
| 527 } | |
| 528 | |
| 529 void PPP_VideoCapture_Proxy::OnMsgOnBufferReady( | |
| 530 const HostResource& host_resource, uint32_t buffer) { | |
| 531 EnterPluginFromHostResource<PPB_VideoCapture_API> enter(host_resource); | |
| 532 if (enter.failed() || !ppp_video_capture_impl_) | |
| 533 return; | |
| 534 | |
| 535 VideoCapture* capture = static_cast<VideoCapture*>(enter.object()); | |
| 536 capture->SetBufferInUse(buffer); | |
| 537 ppp_video_capture_impl_->OnBufferReady( | |
| 538 host_resource.instance(), capture->pp_resource(), buffer); | |
| 539 } | |
| 540 | |
| 541 } // namespace proxy | |
| 542 } // namespace ppapi | |
| OLD | NEW |