Index: ppapi/proxy/ppb_video_capture_proxy.cc |
diff --git a/ppapi/proxy/ppb_video_capture_proxy.cc b/ppapi/proxy/ppb_video_capture_proxy.cc |
index 3df4de8d6cd1d1d9874203e619193cabe0e98df3..e6bbd10cbb795cb64c734ce783f90707b687eae3 100644 |
--- a/ppapi/proxy/ppb_video_capture_proxy.cc |
+++ b/ppapi/proxy/ppb_video_capture_proxy.cc |
@@ -1,12 +1,12 @@ |
-// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
+// Copyright (c) 2012 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/compiler_specific.h" |
#include "base/logging.h" |
+#include "base/memory/ref_counted.h" |
#include "build/build_config.h" |
#include "ppapi/c/pp_errors.h" |
#include "ppapi/c/pp_resource.h" |
@@ -18,6 +18,10 @@ |
#include "ppapi/proxy/plugin_dispatcher.h" |
#include "ppapi/proxy/ppapi_messages.h" |
#include "ppapi/proxy/ppb_buffer_proxy.h" |
+#include "ppapi/shared_impl/ppapi_globals.h" |
+#include "ppapi/shared_impl/ppb_resource_array_shared.h" |
+#include "ppapi/shared_impl/resource_tracker.h" |
+#include "ppapi/shared_impl/tracked_callback.h" |
#include "ppapi/thunk/ppb_buffer_api.h" |
#include "ppapi/thunk/ppb_buffer_trusted_api.h" |
#include "ppapi/thunk/ppb_video_capture_api.h" |
@@ -147,86 +151,19 @@ class VideoCapture : public ppapi::thunk::PPB_VideoCapture_API, |
virtual ppapi::thunk::PPB_VideoCapture_API* AsPPB_VideoCapture_API() OVERRIDE; |
// PPB_VideoCapture_API implementation. |
+ virtual int32_t EnumerateDevices(PP_CompletionCallback callback) OVERRIDE; |
+ virtual PP_Resource GetDevices() OVERRIDE; |
virtual int32_t StartCapture( |
+ const std::string& device_id, |
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( |
- API_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( |
- API_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( |
- API_ID_PPB_VIDEO_CAPTURE_DEV, host_resource())); |
- return PP_OK; |
- } |
+ uint32_t buffer_count) OVERRIDE; |
+ virtual int32_t ReuseBuffer(uint32_t buffer) OVERRIDE; |
+ virtual int32_t StopCapture() OVERRIDE; |
+ virtual const std::vector<DeviceRefData>& GetDeviceRefData() const OVERRIDE; |
- 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 OnEnumerateDevicesComplete(int32_t result, |
+ const std::vector<DeviceRefData>& devices); |
+ bool OnStatus(uint32_t status); |
void set_status(uint32_t status) { status_ = status; } |
@@ -245,23 +182,157 @@ class VideoCapture : public ppapi::thunk::PPB_VideoCapture_API, |
uint32_t status_; |
std::vector<bool> buffer_in_use_; |
+ |
+ scoped_refptr<TrackedCallback> enumerate_devices_callback_; |
+ |
+ // A resource array holding the enumeration result. When nonzero, we're |
+ // holding a reference to it. |
+ PP_Resource devices_; |
+ |
DISALLOW_COPY_AND_ASSIGN(VideoCapture); |
}; |
VideoCapture::VideoCapture(const HostResource& resource) |
: Resource(resource), |
- status_(PP_VIDEO_CAPTURE_STATUS_STOPPED) { |
+ status_(PP_VIDEO_CAPTURE_STATUS_STOPPED), |
+ devices_(0) { |
} |
VideoCapture::~VideoCapture() { |
+ if (devices_) |
+ PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(devices_); |
} |
ppapi::thunk::PPB_VideoCapture_API* VideoCapture::AsPPB_VideoCapture_API() { |
return this; |
} |
+int32_t VideoCapture::EnumerateDevices(PP_CompletionCallback callback) { |
+ if (!callback.func) |
+ return PP_ERROR_BLOCKS_MAIN_THREAD; |
+ if (TrackedCallback::IsPending(enumerate_devices_callback_)) |
+ return PP_ERROR_INPROGRESS; |
+ |
+ enumerate_devices_callback_ = new TrackedCallback(this, callback); |
+ GetDispatcher()->Send(new PpapiHostMsg_PPBVideoCapture_EnumerateDevices( |
+ API_ID_PPB_VIDEO_CAPTURE_DEV, host_resource())); |
+ return PP_OK_COMPLETIONPENDING; |
+} |
+ |
+PP_Resource VideoCapture::GetDevices() { |
+ if (devices_) |
+ PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(devices_); |
+ return devices_; |
+} |
+ |
+int32_t VideoCapture::StartCapture( |
+ const std::string& device_id, |
+ 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: |
+ case PP_VIDEO_CAPTURE_STATUS_STOPPING: |
+ default: |
+ return PP_ERROR_FAILED; |
+ case PP_VIDEO_CAPTURE_STATUS_STOPPED: |
+ break; |
+ } |
+ buffer_in_use_.clear(); |
+ status_ = PP_VIDEO_CAPTURE_STATUS_STARTING; |
+ GetDispatcher()->Send(new PpapiHostMsg_PPBVideoCapture_StartCapture( |
+ API_ID_PPB_VIDEO_CAPTURE_DEV, host_resource(), device_id, |
+ requested_info, buffer_count)); |
+ return PP_OK; |
+} |
+ |
+int32_t VideoCapture::ReuseBuffer(uint32_t buffer) { |
+ if (buffer >= buffer_in_use_.size() || !buffer_in_use_[buffer]) |
+ return PP_ERROR_BADARGUMENT; |
+ GetDispatcher()->Send(new PpapiHostMsg_PPBVideoCapture_ReuseBuffer( |
+ API_ID_PPB_VIDEO_CAPTURE_DEV, host_resource(), buffer)); |
+ return PP_OK; |
+} |
+ |
+int32_t VideoCapture::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; |
+ } |
+ status_ = PP_VIDEO_CAPTURE_STATUS_STOPPING; |
+ GetDispatcher()->Send(new PpapiHostMsg_PPBVideoCapture_StopCapture( |
+ API_ID_PPB_VIDEO_CAPTURE_DEV, host_resource())); |
+ return PP_OK; |
+} |
+ |
+const std::vector<DeviceRefData>& VideoCapture::GetDeviceRefData() const { |
+ // This should never be called at the plugin side. |
+ NOTREACHED(); |
+ static std::vector<DeviceRefData> result; |
+ return result; |
+} |
+ |
+void VideoCapture::OnEnumerateDevicesComplete( |
+ int32_t result, |
+ const std::vector<DeviceRefData>& devices) { |
+ if (devices_) { |
+ PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(devices_); |
+ devices_ = 0; |
+ } |
+ |
+ if (result == PP_OK) { |
+ devices_ = PPB_DeviceRef_Shared::CreateResourceArray(false, pp_instance(), |
+ devices); |
+ } |
+ |
+ TrackedCallback::ClearAndRun(&enumerate_devices_callback_, result); |
+} |
+ |
+bool VideoCapture::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; |
+} |
+ |
PPB_VideoCapture_Proxy::PPB_VideoCapture_Proxy(Dispatcher* dispatcher) |
- : InterfaceProxy(dispatcher) { |
+ : InterfaceProxy(dispatcher), |
+ ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)) { |
} |
PPB_VideoCapture_Proxy::~PPB_VideoCapture_Proxy() { |
@@ -285,12 +356,17 @@ 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_EnumerateDevices, |
+ OnMsgEnumerateDevices) |
IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoCapture_StartCapture, |
OnMsgStartCapture) |
IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoCapture_ReuseBuffer, |
OnMsgReuseBuffer) |
IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoCapture_StopCapture, |
OnMsgStopCapture) |
+ |
+ IPC_MESSAGE_HANDLER(PpapiMsg_PPBVideoCapture_EnumerateDevicesACK, |
+ OnMsgEnumerateDevicesACK) |
IPC_MESSAGE_UNHANDLED(handled = false) |
IPC_END_MESSAGE_MAP() |
// TODO(brettw) handle bad messages! |
@@ -307,13 +383,24 @@ void PPB_VideoCapture_Proxy::OnMsgCreate(PP_Instance instance, |
} |
} |
+void PPB_VideoCapture_Proxy::OnMsgEnumerateDevices( |
+ const HostResource& resource) { |
+ EnterHostFromHostResourceForceCallback<PPB_VideoCapture_API> enter( |
+ resource, callback_factory_, |
+ &PPB_VideoCapture_Proxy::EnumerateDevicesACKInHost, resource); |
+ |
+ if (enter.succeeded()) |
+ enter.SetResult(enter.object()->EnumerateDevices(enter.callback())); |
+} |
+ |
void PPB_VideoCapture_Proxy::OnMsgStartCapture( |
const HostResource& resource, |
+ const std::string& device_id, |
const PP_VideoCaptureDeviceInfo_Dev& info, |
uint32_t buffers) { |
EnterHostFromHostResource<PPB_VideoCapture_API> enter(resource); |
if (enter.succeeded()) |
- enter.object()->StartCapture(info, buffers); |
+ enter.object()->StartCapture(device_id, info, buffers); |
} |
void PPB_VideoCapture_Proxy::OnMsgReuseBuffer(const HostResource& resource, |
@@ -329,6 +416,27 @@ void PPB_VideoCapture_Proxy::OnMsgStopCapture(const HostResource& resource) { |
enter.object()->StopCapture(); |
} |
+void PPB_VideoCapture_Proxy::OnMsgEnumerateDevicesACK( |
+ const HostResource& resource, |
+ int32_t result, |
+ const std::vector<ppapi::DeviceRefData>& devices) { |
+ EnterPluginFromHostResource<PPB_VideoCapture_API> enter(resource); |
+ if (enter.succeeded()) { |
+ static_cast<VideoCapture*>(enter.object())->OnEnumerateDevicesComplete( |
+ result, devices); |
+ } |
+} |
+ |
+void PPB_VideoCapture_Proxy::EnumerateDevicesACKInHost( |
+ int32_t result, |
+ const HostResource& resource) { |
+ EnterHostFromHostResource<PPB_VideoCapture_API> enter(resource); |
+ dispatcher()->Send(new PpapiMsg_PPBVideoCapture_EnumerateDevicesACK( |
+ API_ID_PPB_VIDEO_CAPTURE_DEV, resource, result, |
+ enter.succeeded() && result == PP_OK ? |
+ enter.object()->GetDeviceRefData() : std::vector<DeviceRefData>())); |
+} |
+ |
PPP_VideoCapture_Proxy::PPP_VideoCapture_Proxy(Dispatcher* dispatcher) |
: InterfaceProxy(dispatcher), |
ppp_video_capture_impl_(NULL) { |