| 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) {
|
|
|