diff options
author | piman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-09 07:31:49 +0000 |
---|---|---|
committer | piman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-09 07:31:49 +0000 |
commit | 0fa46e83462229fe740d886f757e99310278d33d (patch) | |
tree | 904cbfe858722351134f596ea4dea6628047b311 /ppapi | |
parent | 1a2966b9dce8d9fb7bebea2c1cad0acd8cb8a786 (diff) | |
download | chromium_src-0fa46e83462229fe740d886f757e99310278d33d.zip chromium_src-0fa46e83462229fe740d886f757e99310278d33d.tar.gz chromium_src-0fa46e83462229fe740d886f757e99310278d33d.tar.bz2 |
PPB/PPP_VideoCapture_Dev proxy
BUG=None
TEST=VideoCapture sample (in a later CL)
Review URL: http://codereview.chromium.org/7601005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@95961 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
-rw-r--r-- | ppapi/ppapi_proxy.gypi | 2 | ||||
-rw-r--r-- | ppapi/proxy/dispatcher.cc | 3 | ||||
-rw-r--r-- | ppapi/proxy/plugin_resource.h | 1 | ||||
-rw-r--r-- | ppapi/proxy/ppapi_messages.h | 44 | ||||
-rw-r--r-- | ppapi/proxy/ppb_buffer_proxy.cc | 10 | ||||
-rw-r--r-- | ppapi/proxy/ppb_buffer_proxy.h | 3 | ||||
-rw-r--r-- | ppapi/proxy/ppb_video_capture_proxy.cc | 459 | ||||
-rw-r--r-- | ppapi/proxy/ppb_video_capture_proxy.h | 78 | ||||
-rw-r--r-- | ppapi/proxy/resource_creation_proxy.cc | 4 | ||||
-rw-r--r-- | ppapi/proxy/serialized_structs.h | 6 |
10 files changed, 607 insertions, 3 deletions
diff --git a/ppapi/ppapi_proxy.gypi b/ppapi/ppapi_proxy.gypi index 49e392d..c354980 100644 --- a/ppapi/ppapi_proxy.gypi +++ b/ppapi/ppapi_proxy.gypi @@ -126,6 +126,8 @@ 'proxy/ppb_var_deprecated_proxy.h', 'proxy/ppb_var_proxy.cc', 'proxy/ppb_var_proxy.h', + 'proxy/ppb_video_capture_proxy.cc', + 'proxy/ppb_video_capture_proxy.h', 'proxy/ppb_video_decoder_proxy.cc', 'proxy/ppb_video_decoder_proxy.h', 'proxy/ppp_class_proxy.cc', diff --git a/ppapi/proxy/dispatcher.cc b/ppapi/proxy/dispatcher.cc index a1c9974..f8cc5b9 100644 --- a/ppapi/proxy/dispatcher.cc +++ b/ppapi/proxy/dispatcher.cc @@ -80,6 +80,7 @@ #include "ppapi/proxy/ppb_url_util_proxy.h" #include "ppapi/proxy/ppb_var_deprecated_proxy.h" #include "ppapi/proxy/ppb_var_proxy.h" +#include "ppapi/proxy/ppb_video_capture_proxy.h" #include "ppapi/proxy/ppb_video_decoder_proxy.h" #include "ppapi/proxy/ppp_class_proxy.h" #include "ppapi/proxy/ppp_graphics_3d_proxy.h" @@ -164,6 +165,7 @@ InterfaceList::InterfaceList() { AddPPB(PPB_URLUtil_Proxy::GetInfo()); AddPPB(PPB_Var_Deprecated_Proxy::GetInfo()); AddPPB(PPB_Var_Proxy::GetInfo()); + AddPPB(PPB_VideoCapture_Proxy::GetInfo()); AddPPB(PPB_VideoDecoder_Proxy::GetInfo()); #ifdef ENABLE_FLAPPER_HACKS @@ -176,6 +178,7 @@ InterfaceList::InterfaceList() { AddPPP(PPP_Instance_Private_Proxy::GetInfo()); AddPPP(PPP_Instance_Proxy::GetInfo1_0()); AddPPP(PPP_Messaging_Proxy::GetInfo()); + AddPPP(PPP_VideoCapture_Proxy::GetInfo()); AddPPP(PPP_VideoDecoder_Proxy::GetInfo()); } diff --git a/ppapi/proxy/plugin_resource.h b/ppapi/proxy/plugin_resource.h index a0675d3..3abe9cb 100644 --- a/ppapi/proxy/plugin_resource.h +++ b/ppapi/proxy/plugin_resource.h @@ -34,6 +34,7 @@ F(URLLoader) \ F(URLRequestInfo) \ F(URLResponseInfo) \ + F(VideoCapture) \ F(VideoDecoder) namespace pp { diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index b039878..0556304 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -18,6 +18,7 @@ #include "ipc/ipc_message_macros.h" #include "ipc/ipc_message_utils.h" #include "ipc/ipc_platform_file.h" +#include "ppapi/c/dev/pp_video_capture_dev.h" #include "ppapi/c/pp_bool.h" #include "ppapi/c/pp_file_info.h" #include "ppapi/c/pp_instance.h" @@ -71,6 +72,18 @@ IPC_STRUCT_TRAITS_BEGIN(PP_Picture_Dev) IPC_STRUCT_TRAITS_MEMBER(bitstream_buffer_id) IPC_STRUCT_TRAITS_END() +IPC_STRUCT_TRAITS_BEGIN(PP_VideoCaptureDeviceInfo_Dev) + IPC_STRUCT_TRAITS_MEMBER(width) + IPC_STRUCT_TRAITS_MEMBER(height) + IPC_STRUCT_TRAITS_MEMBER(frames_per_second) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(pp::proxy::PPPVideoCapture_Buffer) + IPC_STRUCT_TRAITS_MEMBER(resource) + IPC_STRUCT_TRAITS_MEMBER(handle) + IPC_STRUCT_TRAITS_MEMBER(size) +IPC_STRUCT_TRAITS_END() + IPC_STRUCT_TRAITS_BEGIN(::ppapi::Preferences) IPC_STRUCT_TRAITS_MEMBER(standard_font_family) IPC_STRUCT_TRAITS_MEMBER(fixed_font_family) @@ -330,6 +343,22 @@ IPC_MESSAGE_ROUTED3(PpapiMsg_PPBURLLoader_ReadResponseBody_Ack, int32 /* result */, std::string /* data */) +// PPP_VideoCapture_Dev +IPC_MESSAGE_ROUTED3( + PpapiMsg_PPPVideoCapture_OnDeviceInfo, + pp::proxy::HostResource /* video_capture */, + PP_VideoCaptureDeviceInfo_Dev /* info */, + std::vector<pp::proxy::PPPVideoCapture_Buffer> /* buffers */) +IPC_MESSAGE_ROUTED2(PpapiMsg_PPPVideoCapture_OnStatus, + pp::proxy::HostResource /* video_capture */, + uint32_t /* status */) +IPC_MESSAGE_ROUTED2(PpapiMsg_PPPVideoCapture_OnError, + pp::proxy::HostResource /* video_capture */, + uint32_t /* error_code */) +IPC_MESSAGE_ROUTED2(PpapiMsg_PPPVideoCapture_OnBufferReady, + pp::proxy::HostResource /* video_capture */, + uint32_t /* buffer */) + // PPB_VideoDecoder_Dev. // (Messages from renderer to plugin to notify it to run callbacks.) IPC_MESSAGE_ROUTED3(PpapiMsg_PPBVideoDecoder_EndOfBitstreamACK, @@ -945,6 +974,21 @@ IPC_SYNC_MESSAGE_ROUTED4_3(PpapiHostMsg_ResourceCreation_ImageData, pp::proxy::HostResource /* result_resource */, std::string /* image_data_desc */, pp::proxy::ImageHandle /* result */) + +// PPB_VideoCapture_Dev. +IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBVideoCapture_Create, + PP_Instance /* instance */, + pp::proxy::HostResource /* result */) +IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBVideoCapture_StartCapture, + pp::proxy::HostResource /* video_capture */, + PP_VideoCaptureDeviceInfo_Dev /* requested_info */, + uint32_t /* buffer_count */) +IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBVideoCapture_ReuseBuffer, + pp::proxy::HostResource /* video_capture */, + uint32_t /* buffer */) +IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBVideoCapture_StopCapture, + pp::proxy::HostResource /* video_capture */) + // PPB_VideoDecoder. IPC_SYNC_MESSAGE_ROUTED3_1(PpapiHostMsg_PPBVideoDecoder_Create, PP_Instance /* instance */, diff --git a/ppapi/proxy/ppb_buffer_proxy.cc b/ppapi/proxy/ppb_buffer_proxy.cc index 2e782ac..19442ea9 100644 --- a/ppapi/proxy/ppb_buffer_proxy.cc +++ b/ppapi/proxy/ppb_buffer_proxy.cc @@ -108,7 +108,15 @@ PP_Resource PPB_Buffer_Proxy::CreateProxyResource(PP_Instance instance, if (result.is_null() || !base::SharedMemory::IsHandleValid(shm_handle)) return 0; - linked_ptr<Buffer> object(new Buffer(result, shm_handle, size)); + return AddProxyResource(result, shm_handle, size); +} + +// static +PP_Resource PPB_Buffer_Proxy::AddProxyResource( + const HostResource& resource, + base::SharedMemoryHandle shm_handle, + uint32_t size) { + linked_ptr<Buffer> object(new Buffer(resource, shm_handle, size)); return PluginResourceTracker::GetInstance()->AddResource(object); } diff --git a/ppapi/proxy/ppb_buffer_proxy.h b/ppapi/proxy/ppb_buffer_proxy.h index e11b94f..552d422 100644 --- a/ppapi/proxy/ppb_buffer_proxy.h +++ b/ppapi/proxy/ppb_buffer_proxy.h @@ -56,6 +56,9 @@ class PPB_Buffer_Proxy : public InterfaceProxy { static PP_Resource CreateProxyResource(PP_Instance instance, uint32_t size); + static PP_Resource AddProxyResource(const HostResource& resource, + base::SharedMemoryHandle shm_handle, + uint32_t size); const PPB_Buffer_Dev* ppb_buffer_target() const { return static_cast<const PPB_Buffer_Dev*>(target_interface()); diff --git a/ppapi/proxy/ppb_video_capture_proxy.cc b/ppapi/proxy/ppb_video_capture_proxy.cc new file mode 100644 index 0000000..dc253d1 --- /dev/null +++ b/ppapi/proxy/ppb_video_capture_proxy.cc @@ -0,0 +1,459 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/proxy/ppb_video_capture_proxy.h" + +#include <vector> + +#include "base/logging.h" +#include "build/build_config.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/ppb_core.h" +#include "ppapi/c/dev/ppb_video_capture_dev.h" +#include "ppapi/c/dev/ppp_video_capture_dev.h" +#include "ppapi/proxy/enter_proxy.h" +#include "ppapi/proxy/host_dispatcher.h" +#include "ppapi/proxy/plugin_dispatcher.h" +#include "ppapi/proxy/plugin_resource.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/ppb_buffer_proxy.h" +#include "ppapi/thunk/ppb_buffer_api.h" +#include "ppapi/thunk/ppb_buffer_trusted_api.h" +#include "ppapi/thunk/ppb_video_capture_api.h" +#include "ppapi/thunk/thunk.h" + +using ppapi::thunk::EnterResourceNoLock; +using ppapi::thunk::PPB_Buffer_API; +using ppapi::thunk::PPB_BufferTrusted_API; +using ppapi::thunk::PPB_VideoCapture_API; + +namespace pp { +namespace proxy { + +namespace { + +InterfaceProxy* CreatePPBVideoCaptureProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_VideoCapture_Proxy(dispatcher, target_interface); +} + +InterfaceProxy* CreatePPPVideoCaptureProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPP_VideoCapture_Proxy(dispatcher, target_interface); +} + +void OnDeviceInfo(PP_Instance instance, + PP_Resource resource, + const PP_VideoCaptureDeviceInfo_Dev* info, + uint32_t buffer_count, + const PP_Resource* resources) { + HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); + if (!dispatcher) { + NOTREACHED(); + return; + } + HostResource host_resource; + host_resource.SetHostResource(instance, resource); + std::vector<PPPVideoCapture_Buffer> buffers(buffer_count); + const PPB_Core* core = static_cast<const PPB_Core*>( + dispatcher->GetLocalInterface(PPB_CORE_INTERFACE)); + DCHECK(core); + for (uint32_t i = 0; i < buffer_count; ++i) { + // We need to take a ref on the resource now. The browser may drop + // references once we return from here, but we're sending an asynchronous + // message. The plugin side takes ownership of that reference. + core->AddRefResource(resources[i]); + buffers[i].resource.SetHostResource(instance, resources[i]); + { + EnterResourceNoLock<PPB_Buffer_API> enter(resources[i], true); + DCHECK(enter.succeeded()); + PP_Bool result = enter.object()->Describe(&buffers[i].size); + DCHECK(result); + } + { + EnterResourceNoLock<PPB_BufferTrusted_API> enter(resources[i], true); + DCHECK(enter.succeeded()); + int handle; + int32_t result = enter.object()->GetSharedMemory(&handle); + DCHECK(result == PP_OK); + // TODO(piman/brettw): Change trusted interface to return a PP_FileHandle, + // those casts are ugly. + base::PlatformFile platform_file = +#if defined(OS_WIN) + reinterpret_cast<HANDLE>(static_cast<intptr_t>(handle)); +#elif defined(OS_POSIX) + handle; +#else +#error Not implemented. +#endif + buffers[i].handle = + dispatcher->ShareHandleWithRemote(platform_file, false); + } + } + dispatcher->Send(new PpapiMsg_PPPVideoCapture_OnDeviceInfo( + INTERFACE_ID_PPP_VIDEO_CAPTURE_DEV, host_resource, *info, buffers)); +} + +void OnStatus(PP_Instance instance, PP_Resource resource, uint32_t status) { + HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); + if (!dispatcher) { + NOTREACHED(); + return; + } + HostResource host_resource; + host_resource.SetHostResource(instance, resource); + dispatcher->Send(new PpapiMsg_PPPVideoCapture_OnStatus( + INTERFACE_ID_PPP_VIDEO_CAPTURE_DEV, host_resource, status)); +} + +void OnError(PP_Instance instance, PP_Resource resource, uint32_t error_code) { + HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); + if (!dispatcher) { + NOTREACHED(); + return; + } + HostResource host_resource; + host_resource.SetHostResource(instance, resource); + dispatcher->Send(new PpapiMsg_PPPVideoCapture_OnError( + INTERFACE_ID_PPP_VIDEO_CAPTURE_DEV, host_resource, error_code)); +} + +void OnBufferReady(PP_Instance instance, + PP_Resource resource, + uint32_t buffer) { + HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); + if (!dispatcher) { + NOTREACHED(); + return; + } + HostResource host_resource; + host_resource.SetHostResource(instance, resource); + dispatcher->Send(new PpapiMsg_PPPVideoCapture_OnBufferReady( + INTERFACE_ID_PPP_VIDEO_CAPTURE_DEV, host_resource, buffer)); +} + +PPP_VideoCapture_Dev ppp_video_capture = { + OnDeviceInfo, + OnStatus, + OnError, + OnBufferReady +}; + +} // namespace + +class VideoCapture : public ppapi::thunk::PPB_VideoCapture_API, + public PluginResource { + public: + VideoCapture(const HostResource& resource); + virtual ~VideoCapture(); + + // Resource overrides. + virtual VideoCapture* AsVideoCapture() OVERRIDE; + + // ResourceObjectBase overrides. + virtual ppapi::thunk::PPB_VideoCapture_API* AsPPB_VideoCapture_API() OVERRIDE; + + // PPB_VideoCapture_API implementation. + virtual int32_t StartCapture( + const PP_VideoCaptureDeviceInfo_Dev& requested_info, + uint32_t buffer_count) { + switch (status_) { + case PP_VIDEO_CAPTURE_STATUS_STARTING: + case PP_VIDEO_CAPTURE_STATUS_STARTED: + case PP_VIDEO_CAPTURE_STATUS_PAUSED: + default: + return PP_ERROR_FAILED; + case PP_VIDEO_CAPTURE_STATUS_STOPPED: + case PP_VIDEO_CAPTURE_STATUS_STOPPING: + break; + } + status_ = PP_VIDEO_CAPTURE_STATUS_STARTING; + GetDispatcher()->Send(new PpapiHostMsg_PPBVideoCapture_StartCapture( + INTERFACE_ID_PPB_VIDEO_CAPTURE_DEV, host_resource(), + requested_info, buffer_count)); + return PP_OK; + } + + virtual int32_t ReuseBuffer(uint32_t buffer) { + if (buffer >= buffer_in_use_.size() || !buffer_in_use_[buffer]) + return PP_ERROR_BADARGUMENT; + GetDispatcher()->Send(new PpapiHostMsg_PPBVideoCapture_ReuseBuffer( + INTERFACE_ID_PPB_VIDEO_CAPTURE_DEV, host_resource(), buffer)); + return PP_OK; + } + + virtual int32_t StopCapture() { + switch (status_) { + case PP_VIDEO_CAPTURE_STATUS_STOPPED: + case PP_VIDEO_CAPTURE_STATUS_STOPPING: + default: + return PP_ERROR_FAILED; + case PP_VIDEO_CAPTURE_STATUS_STARTING: + case PP_VIDEO_CAPTURE_STATUS_STARTED: + case PP_VIDEO_CAPTURE_STATUS_PAUSED: + break; + } + buffer_in_use_.clear(); + status_ = PP_VIDEO_CAPTURE_STATUS_STOPPING; + GetDispatcher()->Send(new PpapiHostMsg_PPBVideoCapture_StopCapture( + INTERFACE_ID_PPB_VIDEO_CAPTURE_DEV, host_resource())); + return PP_OK; + } + + bool OnStatus(uint32_t status) { + switch (status) { + case PP_VIDEO_CAPTURE_STATUS_STARTING: + case PP_VIDEO_CAPTURE_STATUS_STOPPING: + default: + // Those states are not sent by the browser. + NOTREACHED(); + return false; + case PP_VIDEO_CAPTURE_STATUS_STARTED: + switch (status_) { + case PP_VIDEO_CAPTURE_STATUS_STARTING: + case PP_VIDEO_CAPTURE_STATUS_PAUSED: + break; + default: + return false; + } + break; + case PP_VIDEO_CAPTURE_STATUS_PAUSED: + switch (status_) { + case PP_VIDEO_CAPTURE_STATUS_STARTING: + case PP_VIDEO_CAPTURE_STATUS_STARTED: + break; + default: + return false; + } + break; + case PP_VIDEO_CAPTURE_STATUS_STOPPED: + if (status_ != PP_VIDEO_CAPTURE_STATUS_STOPPING) + return false; + break; + } + status_ = status; + return true; + } + + void set_status(uint32_t status) { status_ = status; } + + void SetBufferCount(size_t count) { + buffer_in_use_ = std::vector<bool>(count); + } + void SetBufferInUse(uint32_t buffer) { + DCHECK(buffer < buffer_in_use_.size()); + buffer_in_use_[buffer] = true; + } + + private: + uint32_t status_; + std::vector<bool> buffer_in_use_; + DISALLOW_COPY_AND_ASSIGN(VideoCapture); +}; + +VideoCapture::VideoCapture(const HostResource& resource) + : PluginResource(resource), + status_(PP_VIDEO_CAPTURE_STATUS_STOPPED) { +} + +VideoCapture::~VideoCapture() { +} + +VideoCapture* VideoCapture::AsVideoCapture() { + return this; +} + +ppapi::thunk::PPB_VideoCapture_API* VideoCapture::AsPPB_VideoCapture_API() { + return this; +} + +PPB_VideoCapture_Proxy::PPB_VideoCapture_Proxy(Dispatcher* dispatcher, + const void* target_interface) + : InterfaceProxy(dispatcher, target_interface) { +} + +PPB_VideoCapture_Proxy::~PPB_VideoCapture_Proxy() { +} + +// static +const InterfaceProxy::Info* PPB_VideoCapture_Proxy::GetInfo() { + static const Info info = { + ppapi::thunk::GetPPB_VideoCapture_Thunk(), + PPB_VIDEO_CAPTURE_DEV_INTERFACE, + INTERFACE_ID_PPB_VIDEO_CAPTURE_DEV, + false, + &CreatePPBVideoCaptureProxy, + }; + return &info; +} + +// static +PP_Resource PPB_VideoCapture_Proxy::CreateProxyResource(PP_Instance instance) { + PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); + if (!dispatcher) + return 0; + + HostResource result; + dispatcher->Send(new PpapiHostMsg_PPBVideoCapture_Create( + INTERFACE_ID_PPB_VIDEO_CAPTURE_DEV, instance, &result)); + if (result.is_null()) + return 0; + + linked_ptr<VideoCapture> object(new VideoCapture(result)); + return PluginResourceTracker::GetInstance()->AddResource(object); +} + +bool PPB_VideoCapture_Proxy::OnMessageReceived(const IPC::Message& msg) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(PPB_VideoCapture_Proxy, msg) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoCapture_Create, OnMsgCreate) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoCapture_StartCapture, + OnMsgStartCapture) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoCapture_ReuseBuffer, + OnMsgReuseBuffer) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoCapture_StopCapture, + OnMsgStopCapture) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + // TODO(brettw) handle bad messages! + return handled; +} + +void PPB_VideoCapture_Proxy::OnMsgCreate(PP_Instance instance, + HostResource* result_resource) { + HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); + if (!dispatcher) + return; + PP_Resource resource = ppb_video_capture_target()->Create(instance); + result_resource->SetHostResource(instance, resource); +} + +void PPB_VideoCapture_Proxy::OnMsgStartCapture( + const HostResource& resource, + const PP_VideoCaptureDeviceInfo_Dev& info, + uint32_t buffers) { + EnterHostFromHostResource<PPB_VideoCapture_API> enter(resource); + if (enter.succeeded()) + enter.object()->StartCapture(info, buffers); +} + +void PPB_VideoCapture_Proxy::OnMsgReuseBuffer(const HostResource& resource, + uint32_t buffer) { + EnterHostFromHostResource<PPB_VideoCapture_API> enter(resource); + if (enter.succeeded()) + enter.object()->ReuseBuffer(buffer); +} + +void PPB_VideoCapture_Proxy::OnMsgStopCapture(const HostResource& resource) { + EnterHostFromHostResource<PPB_VideoCapture_API> enter(resource); + if (enter.succeeded()) + enter.object()->StopCapture(); +} + +PPP_VideoCapture_Proxy::PPP_VideoCapture_Proxy(Dispatcher* dispatcher, + const void* target_interface) + : InterfaceProxy(dispatcher, target_interface) { +} + +PPP_VideoCapture_Proxy::~PPP_VideoCapture_Proxy() { +} + +// static +const InterfaceProxy::Info* PPP_VideoCapture_Proxy::GetInfo() { + static const Info info = { + &ppp_video_capture, + PPP_VIDEO_CAPTURE_DEV_INTERFACE, + INTERFACE_ID_PPP_VIDEO_CAPTURE_DEV, + false, + &CreatePPPVideoCaptureProxy, + }; + return &info; +} + +bool PPP_VideoCapture_Proxy::OnMessageReceived(const IPC::Message& msg) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(PPP_VideoCapture_Proxy, msg) + IPC_MESSAGE_HANDLER(PpapiMsg_PPPVideoCapture_OnDeviceInfo, + OnMsgOnDeviceInfo) + IPC_MESSAGE_HANDLER(PpapiMsg_PPPVideoCapture_OnStatus, OnMsgOnStatus) + IPC_MESSAGE_HANDLER(PpapiMsg_PPPVideoCapture_OnError, OnMsgOnError) + IPC_MESSAGE_HANDLER(PpapiMsg_PPPVideoCapture_OnBufferReady, + OnMsgOnBufferReady) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + // TODO(brettw) handle bad messages! + return handled; +} + +void PPP_VideoCapture_Proxy::OnMsgOnDeviceInfo( + const HostResource& host_resource, + const PP_VideoCaptureDeviceInfo_Dev& info, + const std::vector<PPPVideoCapture_Buffer>& buffers) { + EnterPluginFromHostResource<PPB_VideoCapture_API> enter(host_resource); + PluginResourceTracker* tracker = PluginResourceTracker::GetInstance(); + PP_Resource resource = tracker->PluginResourceForHostResource(host_resource); + if (!resource || !ppp_video_capture_target() || enter.failed()) + return; + + scoped_array<PP_Resource> resources(new PP_Resource[buffers.size()]); + for (size_t i = 0; i < buffers.size(); ++i) { + // We assume that the browser created a new set of resources. + DCHECK(!tracker->PluginResourceForHostResource(buffers[i].resource)); + resources[i] = PPB_Buffer_Proxy::AddProxyResource(buffers[i].resource, + buffers[i].handle, + buffers[i].size); + } + static_cast<VideoCapture*>(enter.object())->SetBufferCount(buffers.size()); + ppp_video_capture_target()->OnDeviceInfo( + host_resource.instance(), + resource, + &info, + buffers.size(), + resources.get()); + for (size_t i = 0; i < buffers.size(); ++i) + tracker->ReleaseResource(resources[i]); +} + +void PPP_VideoCapture_Proxy::OnMsgOnStatus(const HostResource& host_resource, + uint32_t status) { + EnterPluginFromHostResource<PPB_VideoCapture_API> enter(host_resource); + PluginResourceTracker* tracker = PluginResourceTracker::GetInstance(); + PP_Resource resource = tracker->PluginResourceForHostResource(host_resource); + if (!resource || !ppp_video_capture_target() || enter.failed()) + return; + + if (!static_cast<VideoCapture*>(enter.object())->OnStatus(status)) + return; + ppp_video_capture_target()->OnStatus( + host_resource.instance(), resource, status); +} + +void PPP_VideoCapture_Proxy::OnMsgOnError(const HostResource& host_resource, + uint32_t error_code) { + EnterPluginFromHostResource<PPB_VideoCapture_API> enter(host_resource); + PluginResourceTracker* tracker = PluginResourceTracker::GetInstance(); + PP_Resource resource = tracker->PluginResourceForHostResource(host_resource); + if (!resource || !ppp_video_capture_target() || enter.failed()) + return; + static_cast<VideoCapture*>(enter.object())->set_status( + PP_VIDEO_CAPTURE_STATUS_STOPPED); + ppp_video_capture_target()->OnError( + host_resource.instance(), resource, error_code); +} + +void PPP_VideoCapture_Proxy::OnMsgOnBufferReady( + const HostResource& host_resource, uint32_t buffer) { + EnterPluginFromHostResource<PPB_VideoCapture_API> enter(host_resource); + PluginResourceTracker* tracker = PluginResourceTracker::GetInstance(); + PP_Resource resource = tracker->PluginResourceForHostResource(host_resource); + if (!resource || !ppp_video_capture_target() || enter.failed()) + return; + static_cast<VideoCapture*>(enter.object())->SetBufferInUse(buffer); + ppp_video_capture_target()->OnBufferReady( + host_resource.instance(), resource, buffer); +} + +} // namespace proxy +} // namespace pp diff --git a/ppapi/proxy/ppb_video_capture_proxy.h b/ppapi/proxy/ppb_video_capture_proxy.h new file mode 100644 index 0000000..34b6536 --- /dev/null +++ b/ppapi/proxy/ppb_video_capture_proxy.h @@ -0,0 +1,78 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_PPB_VIDEO_CAPTURE_PROXY_H_ +#define PPAPI_PPB_VIDEO_CAPTURE_PROXY_H_ + +#include "ppapi/c/pp_instance.h" +#include "ppapi/proxy/interface_proxy.h" +#include "ppapi/proxy/serialized_structs.h" + +struct PPB_VideoCapture_Dev; +struct PPP_VideoCapture_Dev; +struct PP_VideoCaptureDeviceInfo_Dev; + +namespace pp { +namespace proxy { + +class HostResource; + +class PPB_VideoCapture_Proxy : public InterfaceProxy { + public: + PPB_VideoCapture_Proxy(Dispatcher* dispatcher, const void* target_interface); + virtual ~PPB_VideoCapture_Proxy(); + + static const Info* GetInfo(); + + static PP_Resource CreateProxyResource(PP_Instance instance); + + const PPB_VideoCapture_Dev* ppb_video_capture_target() const { + return static_cast<const PPB_VideoCapture_Dev*>(target_interface()); + } + + // InterfaceProxy implementation. + virtual bool OnMessageReceived(const IPC::Message& msg); + + private: + // Message handlers. + void OnMsgCreate(PP_Instance instance, HostResource* result_resource); + void OnMsgStartCapture(const HostResource& resource, + const PP_VideoCaptureDeviceInfo_Dev& info, + uint32_t buffers); + void OnMsgReuseBuffer(const HostResource& resource, + uint32_t buffer); + void OnMsgStopCapture(const HostResource& resource); +}; + +class PPP_VideoCapture_Proxy : public InterfaceProxy { + public: + PPP_VideoCapture_Proxy(Dispatcher* dispatcher, const void* target_interface); + virtual ~PPP_VideoCapture_Proxy(); + + static const Info* GetInfo(); + + const PPP_VideoCapture_Dev* ppp_video_capture_target() const { + return static_cast<const PPP_VideoCapture_Dev*>(target_interface()); + } + + // InterfaceProxy implementation. + virtual bool OnMessageReceived(const IPC::Message& msg); + + private: + // Message handlers. + void OnMsgOnDeviceInfo(const HostResource& video_capture, + const PP_VideoCaptureDeviceInfo_Dev& info, + const std::vector<PPPVideoCapture_Buffer>& buffers); + void OnMsgOnStatus(const HostResource& video_capture, + uint32_t status); + void OnMsgOnError(const HostResource& video_capture, + uint32_t error_code); + void OnMsgOnBufferReady(const HostResource& video_capture, + uint32_t buffer); +}; + +} // namespace proxy +} // namespace pp + +#endif // PPAPI_PPB_VIDEO_CAPTURE_PROXY_H_ diff --git a/ppapi/proxy/resource_creation_proxy.cc b/ppapi/proxy/resource_creation_proxy.cc index dd87a84..be65bcb 100644 --- a/ppapi/proxy/resource_creation_proxy.cc +++ b/ppapi/proxy/resource_creation_proxy.cc @@ -31,6 +31,7 @@ #include "ppapi/proxy/ppb_surface_3d_proxy.h" #include "ppapi/proxy/ppb_url_loader_proxy.h" #include "ppapi/proxy/ppb_url_request_info_proxy.h" +#include "ppapi/proxy/ppb_video_capture_proxy.h" #include "ppapi/proxy/ppb_video_decoder_proxy.h" #include "ppapi/shared_impl/font_impl.h" #include "ppapi/shared_impl/function_group_base.h" @@ -293,8 +294,7 @@ PP_Resource ResourceCreationProxy::CreateURLRequestInfo(PP_Instance instance) { } PP_Resource ResourceCreationProxy::CreateVideoCapture(PP_Instance instance) { - NOTIMPLEMENTED(); - return 0; + return PPB_VideoCapture_Proxy::CreateProxyResource(instance); } PP_Resource ResourceCreationProxy::CreateVideoDecoder( diff --git a/ppapi/proxy/serialized_structs.h b/ppapi/proxy/serialized_structs.h index 516d53d..dd83396 100644 --- a/ppapi/proxy/serialized_structs.h +++ b/ppapi/proxy/serialized_structs.h @@ -113,6 +113,12 @@ struct PPBURLLoader_UpdateProgress_Params { int64_t total_bytes_to_be_received; }; +struct PPPVideoCapture_Buffer { + pp::proxy::HostResource resource; + uint32_t size; + base::SharedMemoryHandle handle; +}; + #if defined(OS_WIN) typedef HANDLE ImageHandle; #elif defined(OS_MACOSX) |