diff options
author | yzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-10 22:15:10 +0000 |
---|---|---|
committer | yzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-10 22:15:10 +0000 |
commit | 33eccce577eb48d787df7ec5dd0651e87d2eb567 (patch) | |
tree | 6bac12cce99cb325dc2cd9529da83cdce8a99368 /ppapi | |
parent | 52ce533c5f826a0e0cbee12fda81ec8952a19563 (diff) | |
download | chromium_src-33eccce577eb48d787df7ec5dd0651e87d2eb567.zip chromium_src-33eccce577eb48d787df7ec5dd0651e87d2eb567.tar.gz chromium_src-33eccce577eb48d787df7ec5dd0651e87d2eb567.tar.bz2 |
Introduce PPB_VideoCapture_Dev v0.3:
- Add MonitorDeviceChange().
- Change EnumerateDevices() to use PP_ArrayOutput.
- Update the video_capture manual test.
TEST=None
BUG=137799
Review URL: https://chromiumcodereview.appspot.com/11437036
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@172150 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
-rw-r--r-- | ppapi/api/dev/ppb_video_capture_dev.idl | 48 | ||||
-rw-r--r-- | ppapi/c/dev/ppb_video_capture_dev.h | 72 | ||||
-rw-r--r-- | ppapi/cpp/dev/video_capture_dev.cc | 78 | ||||
-rw-r--r-- | ppapi/cpp/dev/video_capture_dev.h | 2 | ||||
-rw-r--r-- | ppapi/examples/video_capture/video_capture.cc | 128 | ||||
-rw-r--r-- | ppapi/examples/video_capture/video_capture.html | 110 | ||||
-rw-r--r-- | ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c | 78 | ||||
-rw-r--r-- | ppapi/proxy/device_enumeration_resource_helper.cc | 51 | ||||
-rw-r--r-- | ppapi/proxy/device_enumeration_resource_helper.h | 4 | ||||
-rw-r--r-- | ppapi/proxy/flash_resource_unittest.cc | 10 | ||||
-rw-r--r-- | ppapi/proxy/ppapi_messages.h | 3 | ||||
-rw-r--r-- | ppapi/proxy/video_capture_resource.cc | 79 | ||||
-rw-r--r-- | ppapi/proxy/video_capture_resource.h | 20 | ||||
-rw-r--r-- | ppapi/thunk/interfaces_ppb_public_dev.h | 2 | ||||
-rw-r--r-- | ppapi/thunk/ppb_video_capture_api.h | 8 | ||||
-rw-r--r-- | ppapi/thunk/ppb_video_capture_thunk.cc | 40 |
16 files changed, 550 insertions, 183 deletions
diff --git a/ppapi/api/dev/ppb_video_capture_dev.idl b/ppapi/api/dev/ppb_video_capture_dev.idl index 179f353..8937960 100644 --- a/ppapi/api/dev/ppb_video_capture_dev.idl +++ b/ppapi/api/dev/ppb_video_capture_dev.idl @@ -7,7 +7,8 @@ * This file defines the <code>PPB_VideoCapture_Dev</code> interface. */ label Chrome { - M19 = 0.2 + M19 = 0.2, + M25 = 0.3 }; /** @@ -65,12 +66,57 @@ interface PPB_VideoCapture_Dev { * - the ref count of the returned |devices| has already been increased by 1 * for the caller. */ + [deprecate=0.3] int32_t EnumerateDevices( [in] PP_Resource video_capture, [out] PP_Resource devices, [in] PP_CompletionCallback callback); /** + * Enumerates video capture devices. + * + * @param[in] video_capture A <code>PP_Resource</code> corresponding to a + * video capture resource. + * @param[in] output An output array which will receive + * <code>PPB_DeviceRef_Dev</code> resources on success. Please note that the + * ref count of those resources has already been increased by 1 for the + * caller. + * @param[in] callback A <code>PP_CompletionCallback</code> to run on + * completion. + * + * @return An error code from <code>pp_errors.h</code>. + */ + [version=0.3] + int32_t EnumerateDevices( + [in] PP_Resource video_capture, + [in] PP_ArrayOutput output, + [in] PP_CompletionCallback callback); + + /** + * Requests device change notifications. + * + * @param[in] video_capture A <code>PP_Resource</code> corresponding to a + * video capture resource. + * @param[in] callback The callback to receive notifications. If not NULL, it + * will be called once for the currently available devices, and then every + * time the list of available devices changes. All calls will happen on the + * same thread as the one on which MonitorDeviceChange() is called. It will + * receive notifications until <code>video_capture</code> is destroyed or + * <code>MonitorDeviceChange()</code> is called to set a new callback for + * <code>video_capture</code>. You can pass NULL to cancel sending + * notifications. + * @param[inout] user_data An opaque pointer that will be passed to + * <code>callback</code>. + * + * @return An error code from <code>pp_errors.h</code>. + */ + [version=0.3] + int32_t MonitorDeviceChange( + [in] PP_Resource video_capture, + [in] PP_MonitorDeviceChangeCallback callback, + [inout] mem_t user_data); + + /** * Opens a video capture device. |device_ref| identifies a video capture * device. It could be one of the resource in the array returned by * |EnumerateDevices()|, or 0 which means the default device. diff --git a/ppapi/c/dev/ppb_video_capture_dev.h b/ppapi/c/dev/ppb_video_capture_dev.h index baec914..a4704b2 100644 --- a/ppapi/c/dev/ppb_video_capture_dev.h +++ b/ppapi/c/dev/ppb_video_capture_dev.h @@ -3,12 +3,14 @@ * found in the LICENSE file. */ -/* From dev/ppb_video_capture_dev.idl modified Tue Oct 30 17:39:32 2012. */ +/* From dev/ppb_video_capture_dev.idl modified Wed Dec 05 13:18:10 2012. */ #ifndef PPAPI_C_DEV_PPB_VIDEO_CAPTURE_DEV_H_ #define PPAPI_C_DEV_PPB_VIDEO_CAPTURE_DEV_H_ #include "ppapi/c/dev/pp_video_capture_dev.h" +#include "ppapi/c/dev/ppb_device_ref_dev.h" +#include "ppapi/c/pp_array_output.h" #include "ppapi/c/pp_bool.h" #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_instance.h" @@ -17,7 +19,8 @@ #include "ppapi/c/pp_stdint.h" #define PPB_VIDEOCAPTURE_DEV_INTERFACE_0_2 "PPB_VideoCapture(Dev);0.2" -#define PPB_VIDEOCAPTURE_DEV_INTERFACE PPB_VIDEOCAPTURE_DEV_INTERFACE_0_2 +#define PPB_VIDEOCAPTURE_DEV_INTERFACE_0_3 "PPB_VideoCapture(Dev);0.3" +#define PPB_VIDEOCAPTURE_DEV_INTERFACE PPB_VIDEOCAPTURE_DEV_INTERFACE_0_3 /** * @file @@ -58,7 +61,7 @@ * 4:2:0, one byte per pixel, tightly packed (width x height Y values, then * width/2 x height/2 U values, then width/2 x height/2 V values). */ -struct PPB_VideoCapture_Dev_0_2 { +struct PPB_VideoCapture_Dev_0_3 { /** * Creates a new VideoCapture. */ @@ -68,22 +71,44 @@ struct PPB_VideoCapture_Dev_0_2 { */ PP_Bool (*IsVideoCapture)(PP_Resource video_capture); /** - * Enumerates video capture devices. Once the operation is completed - * successfully, |devices| will be set to a PPB_ResourceArray_Dev resource, - * which holds a list of PPB_DeviceRef_Dev resources. + * Enumerates video capture devices. + * + * @param[in] video_capture A <code>PP_Resource</code> corresponding to a + * video capture resource. + * @param[in] output An output array which will receive + * <code>PPB_DeviceRef_Dev</code> resources on success. Please note that the + * ref count of those resources has already been increased by 1 for the + * caller. + * @param[in] callback A <code>PP_CompletionCallback</code> to run on + * completion. * - * Please note that: - * - this method ignores the previous value pointed to by |devices| (won't - * release reference even if it is not 0); - * - |devices| must be valid until |callback| is called, if the method - * returns PP_OK_COMPLETIONPENDING; - * - the ref count of the returned |devices| has already been increased by 1 - * for the caller. + * @return An error code from <code>pp_errors.h</code>. */ int32_t (*EnumerateDevices)(PP_Resource video_capture, - PP_Resource* devices, + struct PP_ArrayOutput output, struct PP_CompletionCallback callback); /** + * Requests device change notifications. + * + * @param[in] video_capture A <code>PP_Resource</code> corresponding to a + * video capture resource. + * @param[in] callback The callback to receive notifications. If not NULL, it + * will be called once for the currently available devices, and then every + * time the list of available devices changes. All calls will happen on the + * same thread as the one on which MonitorDeviceChange() is called. It will + * receive notifications until <code>video_capture</code> is destroyed or + * <code>MonitorDeviceChange()</code> is called to set a new callback for + * <code>video_capture</code>. You can pass NULL to cancel sending + * notifications. + * @param[inout] user_data An opaque pointer that will be passed to + * <code>callback</code>. + * + * @return An error code from <code>pp_errors.h</code>. + */ + int32_t (*MonitorDeviceChange)(PP_Resource video_capture, + PP_MonitorDeviceChangeCallback callback, + void* user_data); + /** * Opens a video capture device. |device_ref| identifies a video capture * device. It could be one of the resource in the array returned by * |EnumerateDevices()|, or 0 which means the default device. @@ -134,7 +159,24 @@ struct PPB_VideoCapture_Dev_0_2 { void (*Close)(PP_Resource video_capture); }; -typedef struct PPB_VideoCapture_Dev_0_2 PPB_VideoCapture_Dev; +typedef struct PPB_VideoCapture_Dev_0_3 PPB_VideoCapture_Dev; + +struct PPB_VideoCapture_Dev_0_2 { + PP_Resource (*Create)(PP_Instance instance); + PP_Bool (*IsVideoCapture)(PP_Resource video_capture); + int32_t (*EnumerateDevices)(PP_Resource video_capture, + PP_Resource* devices, + struct PP_CompletionCallback callback); + int32_t (*Open)(PP_Resource video_capture, + PP_Resource device_ref, + const struct PP_VideoCaptureDeviceInfo_Dev* requested_info, + uint32_t buffer_count, + struct PP_CompletionCallback callback); + int32_t (*StartCapture)(PP_Resource video_capture); + int32_t (*ReuseBuffer)(PP_Resource video_capture, uint32_t buffer); + int32_t (*StopCapture)(PP_Resource video_capture); + void (*Close)(PP_Resource video_capture); +}; /** * @} */ diff --git a/ppapi/cpp/dev/video_capture_dev.cc b/ppapi/cpp/dev/video_capture_dev.cc index 3aa234f..46fdb59 100644 --- a/ppapi/cpp/dev/video_capture_dev.cc +++ b/ppapi/cpp/dev/video_capture_dev.cc @@ -18,10 +18,17 @@ template <> const char* interface_name<PPB_VideoCapture_Dev_0_2>() { return PPB_VIDEOCAPTURE_DEV_INTERFACE_0_2; } +template <> const char* interface_name<PPB_VideoCapture_Dev_0_3>() { + return PPB_VIDEOCAPTURE_DEV_INTERFACE_0_3; +} + } // namespace VideoCapture_Dev::VideoCapture_Dev(const InstanceHandle& instance) { - if (has_interface<PPB_VideoCapture_Dev_0_2>()) { + if (has_interface<PPB_VideoCapture_Dev_0_3>()) { + PassRefFromConstructor(get_interface<PPB_VideoCapture_Dev_0_3>()->Create( + instance.pp_instance())); + } else if (has_interface<PPB_VideoCapture_Dev_0_2>()) { PassRefFromConstructor(get_interface<PPB_VideoCapture_Dev_0_2>()->Create( instance.pp_instance())); } @@ -36,24 +43,43 @@ VideoCapture_Dev::~VideoCapture_Dev() { // static bool VideoCapture_Dev::IsAvailable() { - return has_interface<PPB_VideoCapture_Dev_0_2>(); + return has_interface<PPB_VideoCapture_Dev_0_3>() || + has_interface<PPB_VideoCapture_Dev_0_2>(); } int32_t VideoCapture_Dev::EnumerateDevices( const CompletionCallbackWithOutput<std::vector<DeviceRef_Dev> >& callback) { - if (!has_interface<PPB_VideoCapture_Dev_0_2>()) - return callback.MayForce(PP_ERROR_NOINTERFACE); - if (!callback.pp_completion_callback().func) - return callback.MayForce(PP_ERROR_BLOCKS_MAIN_THREAD); - - // ArrayOutputCallbackConverter is responsible to delete it. - ResourceArray_Dev::ArrayOutputCallbackData* data = - new ResourceArray_Dev::ArrayOutputCallbackData( - callback.output(), callback.pp_completion_callback()); - return get_interface<PPB_VideoCapture_Dev_0_2>()->EnumerateDevices( - pp_resource(), &data->resource_array_output, - PP_MakeCompletionCallback( - &ResourceArray_Dev::ArrayOutputCallbackConverter, data)); + if (has_interface<PPB_VideoCapture_Dev_0_3>()) { + return get_interface<PPB_VideoCapture_Dev_0_3>()->EnumerateDevices( + pp_resource(), callback.output(), callback.pp_completion_callback()); + } + + if (has_interface<PPB_VideoCapture_Dev_0_2>()) { + if (!callback.pp_completion_callback().func) + return callback.MayForce(PP_ERROR_BLOCKS_MAIN_THREAD); + + // ArrayOutputCallbackConverter is responsible to delete it. + ResourceArray_Dev::ArrayOutputCallbackData* data = + new ResourceArray_Dev::ArrayOutputCallbackData( + callback.output(), callback.pp_completion_callback()); + return get_interface<PPB_VideoCapture_Dev_0_2>()->EnumerateDevices( + pp_resource(), &data->resource_array_output, + PP_MakeCompletionCallback( + &ResourceArray_Dev::ArrayOutputCallbackConverter, data)); + } + + return callback.MayForce(PP_ERROR_NOINTERFACE); +} + +int32_t VideoCapture_Dev::MonitorDeviceChange( + PP_MonitorDeviceChangeCallback callback, + void* user_data) { + if (has_interface<PPB_VideoCapture_Dev_0_3>()) { + return get_interface<PPB_VideoCapture_Dev_0_3>()->MonitorDeviceChange( + pp_resource(), callback, user_data); + } + + return PP_ERROR_NOINTERFACE; } int32_t VideoCapture_Dev::Open( @@ -61,6 +87,11 @@ int32_t VideoCapture_Dev::Open( const PP_VideoCaptureDeviceInfo_Dev& requested_info, uint32_t buffer_count, const CompletionCallback& callback) { + if (has_interface<PPB_VideoCapture_Dev_0_3>()) { + return get_interface<PPB_VideoCapture_Dev_0_3>()->Open( + pp_resource(), device_ref.pp_resource(), &requested_info, buffer_count, + callback.pp_completion_callback()); + } if (has_interface<PPB_VideoCapture_Dev_0_2>()) { return get_interface<PPB_VideoCapture_Dev_0_2>()->Open( pp_resource(), device_ref.pp_resource(), &requested_info, buffer_count, @@ -71,6 +102,10 @@ int32_t VideoCapture_Dev::Open( } int32_t VideoCapture_Dev::StartCapture() { + if (has_interface<PPB_VideoCapture_Dev_0_3>()) { + return get_interface<PPB_VideoCapture_Dev_0_3>()->StartCapture( + pp_resource()); + } if (has_interface<PPB_VideoCapture_Dev_0_2>()) { return get_interface<PPB_VideoCapture_Dev_0_2>()->StartCapture( pp_resource()); @@ -80,6 +115,10 @@ int32_t VideoCapture_Dev::StartCapture() { } int32_t VideoCapture_Dev::ReuseBuffer(uint32_t buffer) { + if (has_interface<PPB_VideoCapture_Dev_0_3>()) { + return get_interface<PPB_VideoCapture_Dev_0_3>()->ReuseBuffer(pp_resource(), + buffer); + } if (has_interface<PPB_VideoCapture_Dev_0_2>()) { return get_interface<PPB_VideoCapture_Dev_0_2>()->ReuseBuffer(pp_resource(), buffer); @@ -89,6 +128,10 @@ int32_t VideoCapture_Dev::ReuseBuffer(uint32_t buffer) { } int32_t VideoCapture_Dev::StopCapture() { + if (has_interface<PPB_VideoCapture_Dev_0_3>()) { + return get_interface<PPB_VideoCapture_Dev_0_3>()->StopCapture( + pp_resource()); + } if (has_interface<PPB_VideoCapture_Dev_0_2>()) { return get_interface<PPB_VideoCapture_Dev_0_2>()->StopCapture( pp_resource()); @@ -98,8 +141,11 @@ int32_t VideoCapture_Dev::StopCapture() { } void VideoCapture_Dev::Close() { - if (has_interface<PPB_VideoCapture_Dev_0_2>()) + if (has_interface<PPB_VideoCapture_Dev_0_3>()) { + get_interface<PPB_VideoCapture_Dev_0_3>()->Close(pp_resource()); + } else if (has_interface<PPB_VideoCapture_Dev_0_2>()) { get_interface<PPB_VideoCapture_Dev_0_2>()->Close(pp_resource()); + } } } // namespace pp diff --git a/ppapi/cpp/dev/video_capture_dev.h b/ppapi/cpp/dev/video_capture_dev.h index 45d68c62f6..649254e 100644 --- a/ppapi/cpp/dev/video_capture_dev.h +++ b/ppapi/cpp/dev/video_capture_dev.h @@ -29,6 +29,8 @@ class VideoCapture_Dev : public Resource { int32_t EnumerateDevices( const CompletionCallbackWithOutput<std::vector<DeviceRef_Dev> >& callback); + int32_t MonitorDeviceChange(PP_MonitorDeviceChangeCallback callback, + void* user_data); int32_t Open(const DeviceRef_Dev& device_ref, const PP_VideoCaptureDeviceInfo_Dev& requested_info, uint32_t buffer_count, diff --git a/ppapi/examples/video_capture/video_capture.cc b/ppapi/examples/video_capture/video_capture.cc index 8e080e1..b95fcac 100644 --- a/ppapi/examples/video_capture/video_capture.cc +++ b/ppapi/examples/video_capture/video_capture.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <assert.h> +#include <stdlib.h> #include <string.h> #include <map> @@ -33,11 +33,13 @@ // Assert |context_| isn't holding any GL Errors. Done as a macro instead of a // function to preserve line number information in the failure message. -#define assertNoGLError() \ - assert(!gles2_if_->GetError(context_->pp_resource())); +#define AssertNoGLError() \ + PP_DCHECK(!gles2_if_->GetError(context_->pp_resource())); namespace { +const char* const kDelimiter = "#__#"; + // This object is the global object representing this plugin library as long // as it is loaded. class VCDemoModule : public pp::Module { @@ -124,10 +126,16 @@ class VCDemoInstance : public pp::Instance, void CreateYUVTextures(); void Open(const pp::DeviceRef_Dev& device); + void Stop(); + void Start(); void EnumerateDevicesFinished(int32_t result, std::vector<pp::DeviceRef_Dev>& devices); void OpenFinished(int32_t result); + static void MonitorDeviceChangeCallback(void* user_data, + uint32_t device_count, + const PP_Resource devices[]); + pp::Size position_size_; bool is_painting_; bool needs_paint_; @@ -145,7 +153,8 @@ class VCDemoInstance : public pp::Instance, // Owned data. pp::Graphics3D* context_; - std::vector<pp::DeviceRef_Dev> devices_; + std::vector<pp::DeviceRef_Dev> enumerate_devices_; + std::vector<pp::DeviceRef_Dev> monitor_devices_; }; VCDemoInstance::VCDemoInstance(PP_Instance instance, pp::Module* module) @@ -162,7 +171,7 @@ VCDemoInstance::VCDemoInstance(PP_Instance instance, pp::Module* module) context_(NULL) { gles2_if_ = static_cast<const struct PPB_OpenGLES2*>( module->GetBrowserInterface(PPB_OPENGLES2_INTERFACE)); - assert(gles2_if_); + PP_DCHECK(gles2_if_); capture_info_.width = 320; capture_info_.height = 240; @@ -170,6 +179,7 @@ VCDemoInstance::VCDemoInstance(PP_Instance instance, pp::Module* module) } VCDemoInstance::~VCDemoInstance() { + video_capture_.MonitorDeviceChange(NULL, NULL); delete context_; } @@ -192,27 +202,43 @@ void VCDemoInstance::HandleMessage(const pp::Var& message_data) { if (message_data.is_string()) { std::string event = message_data.AsString(); if (event == "PageInitialized") { + int32_t result = video_capture_.MonitorDeviceChange( + &VCDemoInstance::MonitorDeviceChangeCallback, this); + if (result != PP_OK) + PostMessage(pp::Var("MonitorDeviceChangeFailed")); + pp::CompletionCallbackWithOutput<std::vector<pp::DeviceRef_Dev> > callback = callback_factory_.NewCallbackWithOutput( &VCDemoInstance::EnumerateDevicesFinished); - video_capture_.EnumerateDevices(callback); + result = video_capture_.EnumerateDevices(callback); + if (result != PP_OK_COMPLETIONPENDING) + PostMessage(pp::Var("EnumerationFailed")); } else if (event == "UseDefault") { Open(pp::DeviceRef_Dev()); } else if (event == "Stop") { - video_capture_.StopCapture(); - } - } else if (message_data.is_number()) { - int index = message_data.AsInt(); - if (index >= 0 && index < static_cast<int>(devices_.size())) { - Open(devices_[index]); - } else { - assert(false); + Stop(); + } else if (event == "Start") { + Start(); + } else if (event.find("Monitor:") == 0) { + std::string index_str = event.substr(strlen("Monitor:")); + int index = atoi(index_str.c_str()); + if (index >= 0 && index < static_cast<int>(monitor_devices_.size())) + Open(monitor_devices_[index]); + else + PP_NOTREACHED(); + } else if (event.find("Enumerate:") == 0) { + std::string index_str = event.substr(strlen("Enumerate:")); + int index = atoi(index_str.c_str()); + if (index >= 0 && index < static_cast<int>(enumerate_devices_.size())) + Open(enumerate_devices_[index]); + else + PP_NOTREACHED(); } } } void VCDemoInstance::InitGL() { - assert(position_size_.width() && position_size_.height()); + PP_DCHECK(position_size_.width() && position_size_.height()); is_painting_ = false; delete context_; @@ -230,7 +256,7 @@ void VCDemoInstance::InitGL() { PP_GRAPHICS3DATTRIB_NONE, }; context_ = new pp::Graphics3D(this, attributes); - assert(!context_->is_null()); + PP_DCHECK(!context_->is_null()); // Set viewport window size and clear color bit. gles2_if_->ClearColor(context_->pp_resource(), 1, 0, 0, 1); @@ -239,13 +265,13 @@ void VCDemoInstance::InitGL() { position_size_.width(), position_size_.height()); BindGraphics(*context_); - assertNoGLError(); + AssertNoGLError(); CreateGLObjects(); } void VCDemoInstance::Render() { - assert(!is_painting_); + PP_DCHECK(!is_painting_); is_painting_ = true; needs_paint_ = false; if (texture_y_) { @@ -267,7 +293,7 @@ void VCDemoInstance::PaintFinished(int32_t result) { GLuint VCDemoInstance::CreateTexture(int32_t width, int32_t height, int unit) { GLuint texture_id; gles2_if_->GenTextures(context_->pp_resource(), 1, &texture_id); - assertNoGLError(); + AssertNoGLError(); // Assign parameters. gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0 + unit); gles2_if_->BindTexture(context_->pp_resource(), GL_TEXTURE_2D, texture_id); @@ -288,7 +314,7 @@ GLuint VCDemoInstance::CreateTexture(int32_t width, int32_t height, int unit) { gles2_if_->TexImage2D( context_->pp_resource(), GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); - assertNoGLError(); + AssertNoGLError(); return texture_id; } @@ -347,7 +373,7 @@ void VCDemoInstance::CreateGLObjects() { context, gles2_if_->GetUniformLocation(context, program, "color_matrix"), 1, GL_FALSE, kColorMatrix); - assertNoGLError(); + AssertNoGLError(); // Assign vertex positions and texture coordinates to buffers for use in // shader program. @@ -361,12 +387,12 @@ void VCDemoInstance::CreateGLObjects() { gles2_if_->BindBuffer(context, GL_ARRAY_BUFFER, buffer); gles2_if_->BufferData(context, GL_ARRAY_BUFFER, sizeof(kVertices), kVertices, GL_STATIC_DRAW); - assertNoGLError(); + AssertNoGLError(); GLint pos_location = gles2_if_->GetAttribLocation( context, program, "a_position"); GLint tc_location = gles2_if_->GetAttribLocation( context, program, "a_texCoord"); - assertNoGLError(); + AssertNoGLError(); gles2_if_->EnableVertexAttribArray(context, pos_location); gles2_if_->VertexAttribPointer(context, pos_location, 2, GL_FLOAT, GL_FALSE, 0, 0); @@ -374,7 +400,7 @@ void VCDemoInstance::CreateGLObjects() { gles2_if_->VertexAttribPointer( context, tc_location, 2, GL_FLOAT, GL_FALSE, 0, static_cast<float*>(0) + 8); // Skip position coordinates. - assertNoGLError(); + AssertNoGLError(); } void VCDemoInstance::CreateShader( @@ -401,20 +427,30 @@ void VCDemoInstance::CreateYUVTextures() { void VCDemoInstance::Open(const pp::DeviceRef_Dev& device) { pp::CompletionCallback callback = callback_factory_.NewCallback( &VCDemoInstance::OpenFinished); - video_capture_.Open(device, capture_info_, 4, callback); + int32_t result = video_capture_.Open(device, capture_info_, 4, callback); + if (result != PP_OK_COMPLETIONPENDING) + PostMessage(pp::Var("OpenFailed")); +} + +void VCDemoInstance::Stop() { + if (video_capture_.StopCapture() != PP_OK) + PostMessage(pp::Var("StopFailed")); +} + +void VCDemoInstance::Start() { + if (video_capture_.StartCapture() != PP_OK) + PostMessage(pp::Var("StartFailed")); } void VCDemoInstance::EnumerateDevicesFinished( int32_t result, - std::vector<pp::DeviceRef_Dev>& devices) { - static const char* const kDelimiter = "#__#"; - + std::vector<pp::DeviceRef_Dev>& devices) { if (result == PP_OK) { - devices_.swap(devices); - std::string device_names; - for (size_t index = 0; index < devices_.size(); ++index) { - pp::Var name = devices_[index].GetName(); - assert(name.is_string()); + enumerate_devices_.swap(devices); + std::string device_names = "Enumerate:"; + for (size_t index = 0; index < enumerate_devices_.size(); ++index) { + pp::Var name = enumerate_devices_[index].GetName(); + PP_DCHECK(name.is_string()); if (index != 0) device_names += kDelimiter; @@ -427,11 +463,31 @@ void VCDemoInstance::EnumerateDevicesFinished( } void VCDemoInstance::OpenFinished(int32_t result) { - if (result == PP_OK) { - video_capture_.StartCapture(); - } else { + if (result == PP_OK) + Start(); + else PostMessage(pp::Var("OpenFailed")); +} + +// static +void VCDemoInstance::MonitorDeviceChangeCallback(void* user_data, + uint32_t device_count, + const PP_Resource devices[]) { + VCDemoInstance* thiz = static_cast<VCDemoInstance*>(user_data); + + std::string device_names = "Monitor:"; + thiz->monitor_devices_.clear(); + thiz->monitor_devices_.reserve(device_count); + for (size_t index = 0; index < device_count; ++index) { + thiz->monitor_devices_.push_back(pp::DeviceRef_Dev(devices[index])); + pp::Var name = thiz->monitor_devices_.back().GetName(); + PP_DCHECK(name.is_string()); + + if (index != 0) + device_names += kDelimiter; + device_names += name.AsString(); } + thiz->PostMessage(pp::Var(device_names)); } pp::Instance* VCDemoModule::CreateInstance(PP_Instance instance) { diff --git a/ppapi/examples/video_capture/video_capture.html b/ppapi/examples/video_capture/video_capture.html index 5b62c76..1c85577 100644 --- a/ppapi/examples/video_capture/video_capture.html +++ b/ppapi/examples/video_capture/video_capture.html @@ -8,34 +8,80 @@ <head> <title>Video Capture Example</title> <script type="text/javascript"> - var device_array = []; + var monitor_device_array = []; + var enumerate_device_array = []; + var monitor_notification_count = 0; function HandleMessage(message_event) { if (message_event.data) { + var status = document.getElementById('status'); if (message_event.data == 'EnumerationFailed') { - var status = document.getElementById('status'); status.innerText = 'Device enumeration failed!'; + } else if (message_event.data == 'MonitorDeviceChangeFailed') { + status.innerText = 'Monitor device change failed!'; } else if (message_event.data == 'OpenFailed') { - var status = document.getElementById('status'); status.innerText = 'Open device failed!'; + } else if (message_event.data == 'StartFailed') { + status.innerText = 'Start capturing failed!'; + } else if (message_event.data == 'StopFailed') { + status.innerText = 'Stop capturing failed!'; } else { - device_array = message_event.data.split('#__#'); - - var list = document.getElementById('device_list'); - for (var i = 0; i < device_array.length; ++i) { - var list_item = document.createElement('li'); - var link = document.createElement('a'); - link.href = 'javascript:UseDesignatedDevice(' + i + ');'; - link.innerText = device_array[i]; - list_item.appendChild(link); - list.appendChild(list_item); - } + AddDevices(message_event.data); } } } - function UseDesignatedDevice(index) { - UseDevice(device_array[index], index); + function AddDevices(command) { + var serialized_names = ''; + var is_monitor = false; + if (command.search('Monitor:') == 0) { + serialized_names = command.substr(8); + is_monitor = true; + monitor_notification_count++; + var counter = document.getElementById('notification_counter'); + counter.innerText = monitor_notification_count; + } else if (command.search('Enumerate:') == 0) { + serialized_names = command.substr(10); + } else { + status.innerText = 'Unrecognized command!'; + return; + } + + var storage = serialized_names.length != 0 ? + serialized_names.split('#__#') : []; + if (is_monitor) + monitor_device_array = storage; + else + enumerate_device_array = storage; + + var list = document.getElementById( + is_monitor ? 'monitor_list' : 'enumerate_list'); + if (list) { + while (list.firstChild) + list.removeChild(list.firstChild); + + for (var i = 0; i < storage.length; ++i) { + AppendDevice( + list, storage[i], + 'javascript:UseDesignatedDevice(' + is_monitor + ',' + i + ');'); + } + } + } + + function AppendDevice(list, text, href) { + var list_item = document.createElement('li'); + var link = document.createElement('a'); + link.href = href; + link.innerText = text; + list_item.appendChild(link); + list.appendChild(list_item); + } + + function UseDesignatedDevice(is_monitor, index) { + if (is_monitor) + UseDevice(monitor_device_array[index], 'Monitor:' + index); + else + UseDevice(enumerate_device_array[index], 'Enumerate:' + index); } function UseDefaultDevice() { @@ -52,10 +98,7 @@ available_devices.parentNode.removeChild(available_devices); var control_panel = document.getElementById('control_panel'); - var link = document.createElement('a'); - link.href = 'javascript:Stop();'; - link.innerText = 'Stop'; - control_panel.appendChild(link); + control_panel.style.display = ''; } function Stop() { @@ -63,6 +106,11 @@ plugin.postMessage('Stop'); } + function Start() { + var plugin = document.getElementById('plugin'); + plugin.postMessage('Start'); + } + function Initialize() { var plugin = document.getElementById('plugin'); plugin.addEventListener('message', HandleMessage, false); @@ -81,11 +129,27 @@ </div> <div id="available_devices"> Available device(s), choose one to open: - <ul id="device_list"> - <li><a href="javascript:UseDefaultDevice();">Default</a></li> + <ul> + <li><a href="javascript:UseDefaultDevice();"> + Default - use NULL device ref</a></li> </ul> + <div> + <ul>List retrieved by MonitorDeviceChange(), will change when + pluging/unpluging devices: (Notifications received: + <span style="font-weight:bold" id="notification_counter">0</span> + )</ul> + <ul id="monitor_list"/> + </div> + <div> + <ul>List retrieved by EnumerateDevices(), never updated after the page is + initialized:</ul> + <ul id="enumerate_list"/> + </div> </div> - <div id="control_panel"></div> + <div id="control_panel" style="display:none"> + <a href="javascript:Stop();">Stop</a> + <a href="javascript:Start();">Start</a> + <div/> <div id="status"></div> </body> </html> diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c index b3772d9..5443705 100644 --- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c +++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c @@ -198,6 +198,7 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_TextInput_Dev_0_1; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_TextInput_Dev_0_2; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_URLUtil_Dev_0_6; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoCapture_Dev_0_2; +static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoCapture_Dev_0_3; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoDecoder_Dev_0_16; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_View_Dev_0_1; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Widget_Dev_0_3; @@ -2106,6 +2107,64 @@ void Pnacl_M19_PPB_VideoCapture_Dev_Close(PP_Resource video_capture) { /* End wrapper methods for PPB_VideoCapture_Dev_0_2 */ +/* Begin wrapper methods for PPB_VideoCapture_Dev_0_3 */ + +static __attribute__((pnaclcall)) +PP_Resource Pnacl_M25_PPB_VideoCapture_Dev_Create(PP_Instance instance) { + const struct PPB_VideoCapture_Dev_0_3 *iface = Pnacl_WrapperInfo_PPB_VideoCapture_Dev_0_3.real_iface; + return iface->Create(instance); +} + +static __attribute__((pnaclcall)) +PP_Bool Pnacl_M25_PPB_VideoCapture_Dev_IsVideoCapture(PP_Resource video_capture) { + const struct PPB_VideoCapture_Dev_0_3 *iface = Pnacl_WrapperInfo_PPB_VideoCapture_Dev_0_3.real_iface; + return iface->IsVideoCapture(video_capture); +} + +static __attribute__((pnaclcall)) +int32_t Pnacl_M25_PPB_VideoCapture_Dev_EnumerateDevices(PP_Resource video_capture, struct PP_ArrayOutput output, struct PP_CompletionCallback callback) { + const struct PPB_VideoCapture_Dev_0_3 *iface = Pnacl_WrapperInfo_PPB_VideoCapture_Dev_0_3.real_iface; + return iface->EnumerateDevices(video_capture, output, callback); +} + +static __attribute__((pnaclcall)) +int32_t Pnacl_M25_PPB_VideoCapture_Dev_MonitorDeviceChange(PP_Resource video_capture, PP_MonitorDeviceChangeCallback callback, void* user_data) { + const struct PPB_VideoCapture_Dev_0_3 *iface = Pnacl_WrapperInfo_PPB_VideoCapture_Dev_0_3.real_iface; + return iface->MonitorDeviceChange(video_capture, callback, user_data); +} + +static __attribute__((pnaclcall)) +int32_t Pnacl_M25_PPB_VideoCapture_Dev_Open(PP_Resource video_capture, PP_Resource device_ref, const struct PP_VideoCaptureDeviceInfo_Dev* requested_info, uint32_t buffer_count, struct PP_CompletionCallback callback) { + const struct PPB_VideoCapture_Dev_0_3 *iface = Pnacl_WrapperInfo_PPB_VideoCapture_Dev_0_3.real_iface; + return iface->Open(video_capture, device_ref, requested_info, buffer_count, callback); +} + +static __attribute__((pnaclcall)) +int32_t Pnacl_M25_PPB_VideoCapture_Dev_StartCapture(PP_Resource video_capture) { + const struct PPB_VideoCapture_Dev_0_3 *iface = Pnacl_WrapperInfo_PPB_VideoCapture_Dev_0_3.real_iface; + return iface->StartCapture(video_capture); +} + +static __attribute__((pnaclcall)) +int32_t Pnacl_M25_PPB_VideoCapture_Dev_ReuseBuffer(PP_Resource video_capture, uint32_t buffer) { + const struct PPB_VideoCapture_Dev_0_3 *iface = Pnacl_WrapperInfo_PPB_VideoCapture_Dev_0_3.real_iface; + return iface->ReuseBuffer(video_capture, buffer); +} + +static __attribute__((pnaclcall)) +int32_t Pnacl_M25_PPB_VideoCapture_Dev_StopCapture(PP_Resource video_capture) { + const struct PPB_VideoCapture_Dev_0_3 *iface = Pnacl_WrapperInfo_PPB_VideoCapture_Dev_0_3.real_iface; + return iface->StopCapture(video_capture); +} + +static __attribute__((pnaclcall)) +void Pnacl_M25_PPB_VideoCapture_Dev_Close(PP_Resource video_capture) { + const struct PPB_VideoCapture_Dev_0_3 *iface = Pnacl_WrapperInfo_PPB_VideoCapture_Dev_0_3.real_iface; + iface->Close(video_capture); +} + +/* End wrapper methods for PPB_VideoCapture_Dev_0_3 */ + /* Begin wrapper methods for PPB_VideoDecoder_Dev_0_16 */ static __attribute__((pnaclcall)) @@ -3944,6 +4003,18 @@ struct PPB_VideoCapture_Dev_0_2 Pnacl_Wrappers_PPB_VideoCapture_Dev_0_2 = { .Close = (void (*)(PP_Resource video_capture))&Pnacl_M19_PPB_VideoCapture_Dev_Close }; +struct PPB_VideoCapture_Dev_0_3 Pnacl_Wrappers_PPB_VideoCapture_Dev_0_3 = { + .Create = (PP_Resource (*)(PP_Instance instance))&Pnacl_M25_PPB_VideoCapture_Dev_Create, + .IsVideoCapture = (PP_Bool (*)(PP_Resource video_capture))&Pnacl_M25_PPB_VideoCapture_Dev_IsVideoCapture, + .EnumerateDevices = (int32_t (*)(PP_Resource video_capture, struct PP_ArrayOutput output, struct PP_CompletionCallback callback))&Pnacl_M25_PPB_VideoCapture_Dev_EnumerateDevices, + .MonitorDeviceChange = (int32_t (*)(PP_Resource video_capture, PP_MonitorDeviceChangeCallback callback, void* user_data))&Pnacl_M25_PPB_VideoCapture_Dev_MonitorDeviceChange, + .Open = (int32_t (*)(PP_Resource video_capture, PP_Resource device_ref, const struct PP_VideoCaptureDeviceInfo_Dev* requested_info, uint32_t buffer_count, struct PP_CompletionCallback callback))&Pnacl_M25_PPB_VideoCapture_Dev_Open, + .StartCapture = (int32_t (*)(PP_Resource video_capture))&Pnacl_M25_PPB_VideoCapture_Dev_StartCapture, + .ReuseBuffer = (int32_t (*)(PP_Resource video_capture, uint32_t buffer))&Pnacl_M25_PPB_VideoCapture_Dev_ReuseBuffer, + .StopCapture = (int32_t (*)(PP_Resource video_capture))&Pnacl_M25_PPB_VideoCapture_Dev_StopCapture, + .Close = (void (*)(PP_Resource video_capture))&Pnacl_M25_PPB_VideoCapture_Dev_Close +}; + struct PPB_VideoDecoder_Dev_0_16 Pnacl_Wrappers_PPB_VideoDecoder_Dev_0_16 = { .Create = (PP_Resource (*)(PP_Instance instance, PP_Resource context, PP_VideoDecoder_Profile profile))&Pnacl_M14_PPB_VideoDecoder_Dev_Create, .IsVideoDecoder = (PP_Bool (*)(PP_Resource resource))&Pnacl_M14_PPB_VideoDecoder_Dev_IsVideoDecoder, @@ -4760,6 +4831,12 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoCapture_Dev_0_2 = { .real_iface = NULL }; +static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoCapture_Dev_0_3 = { + .iface_macro = PPB_VIDEOCAPTURE_DEV_INTERFACE_0_3, + .wrapped_iface = (void *) &Pnacl_Wrappers_PPB_VideoCapture_Dev_0_3, + .real_iface = NULL +}; + static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoDecoder_Dev_0_16 = { .iface_macro = PPB_VIDEODECODER_DEV_INTERFACE_0_16, .wrapped_iface = (void *) &Pnacl_Wrappers_PPB_VideoDecoder_Dev_0_16, @@ -5159,6 +5236,7 @@ static struct __PnaclWrapperInfo *s_ppb_wrappers[] = { &Pnacl_WrapperInfo_PPB_TextInput_Dev_0_2, &Pnacl_WrapperInfo_PPB_URLUtil_Dev_0_6, &Pnacl_WrapperInfo_PPB_VideoCapture_Dev_0_2, + &Pnacl_WrapperInfo_PPB_VideoCapture_Dev_0_3, &Pnacl_WrapperInfo_PPB_VideoDecoder_Dev_0_16, &Pnacl_WrapperInfo_PPB_View_Dev_0_1, &Pnacl_WrapperInfo_PPB_Widget_Dev_0_3, diff --git a/ppapi/proxy/device_enumeration_resource_helper.cc b/ppapi/proxy/device_enumeration_resource_helper.cc index 2796439..2b51c27 100644 --- a/ppapi/proxy/device_enumeration_resource_helper.cc +++ b/ppapi/proxy/device_enumeration_resource_helper.cc @@ -71,6 +71,21 @@ int32_t DeviceEnumerationResourceHelper::EnumerateDevices( return PP_OK_COMPLETIONPENDING; } +int32_t DeviceEnumerationResourceHelper::EnumerateDevicesSync( + const PP_ArrayOutput& output) { + std::vector<DeviceRefData> devices; + int32_t result = + owner_->SyncCall<PpapiPluginMsg_DeviceEnumeration_EnumerateDevicesReply>( + PluginResource::RENDERER, + PpapiHostMsg_DeviceEnumeration_EnumerateDevices(), + &devices); + + if (result == PP_OK) + result = WriteToArrayOutput(devices, output); + + return result; +} + int32_t DeviceEnumerationResourceHelper::MonitorDeviceChange( PP_MonitorDeviceChangeCallback callback, void* user_data) { @@ -148,22 +163,10 @@ void DeviceEnumerationResourceHelper::OnPluginMsgEnumerateDevicesReply( return; int32_t result = params.result(); - if (result == PP_OK) { - ArrayWriter writer(output); - if (writer.is_valid()) { - std::vector<scoped_refptr<Resource> > device_resources; - for (size_t i = 0; i < devices.size(); ++i) { - device_resources.push_back(new PPB_DeviceRef_Shared( - OBJECT_IS_PROXY, owner_->pp_instance(), devices[i])); - } - if (!writer.StoreResourceVector(device_resources)) - result = PP_ERROR_FAILED; - } else { - result = PP_ERROR_BADARGUMENT; - } - } + if (result == PP_OK) + result = WriteToArrayOutput(devices, output); - callback->Run(params.result()); + callback->Run(result); } void DeviceEnumerationResourceHelper::OnPluginMsgNotifyDeviceChange( @@ -196,5 +199,23 @@ void DeviceEnumerationResourceHelper::OnPluginMsgNotifyDeviceChange( PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(elements[index]); } +int32_t DeviceEnumerationResourceHelper::WriteToArrayOutput( + const std::vector<DeviceRefData>& devices, + const PP_ArrayOutput& output) { + ArrayWriter writer(output); + if (!writer.is_valid()) + return PP_ERROR_BADARGUMENT; + + std::vector<scoped_refptr<Resource> > device_resources; + for (size_t i = 0; i < devices.size(); ++i) { + device_resources.push_back(new PPB_DeviceRef_Shared( + OBJECT_IS_PROXY, owner_->pp_instance(), devices[i])); + } + if (!writer.StoreResourceVector(device_resources)) + return PP_ERROR_FAILED; + + return PP_OK; +} + } // namespace proxy } // namespace ppapi diff --git a/ppapi/proxy/device_enumeration_resource_helper.h b/ppapi/proxy/device_enumeration_resource_helper.h index 744a0eb..6c266eb 100644 --- a/ppapi/proxy/device_enumeration_resource_helper.h +++ b/ppapi/proxy/device_enumeration_resource_helper.h @@ -40,6 +40,7 @@ class PPAPI_PROXY_EXPORT DeviceEnumerationResourceHelper scoped_refptr<TrackedCallback> callback); int32_t EnumerateDevices(const PP_ArrayOutput& output, scoped_refptr<TrackedCallback> callback); + int32_t EnumerateDevicesSync(const PP_ArrayOutput& output); int32_t MonitorDeviceChange(PP_MonitorDeviceChangeCallback callback, void* user_data); @@ -64,6 +65,9 @@ class PPAPI_PROXY_EXPORT DeviceEnumerationResourceHelper uint32_t callback_id, const std::vector<DeviceRefData>& devices); + int32_t WriteToArrayOutput(const std::vector<DeviceRefData>& devices, + const PP_ArrayOutput& output); + // Not owned by this object. PluginResource* owner_; diff --git a/ppapi/proxy/flash_resource_unittest.cc b/ppapi/proxy/flash_resource_unittest.cc index be083ed..ab22077 100644 --- a/ppapi/proxy/flash_resource_unittest.cc +++ b/ppapi/proxy/flash_resource_unittest.cc @@ -33,18 +33,18 @@ TEST_F(FlashResourceTest, EnumerateVideoCaptureDevices) { // Set up a sync call handler that should return this message. std::vector<ppapi::DeviceRefData> reply_device_ref_data; int32_t expected_result = PP_OK; - PpapiPluginMsg_VideoCapture_EnumerateDevicesReply reply_msg( + PpapiPluginMsg_DeviceEnumeration_EnumerateDevicesReply reply_msg( reply_device_ref_data); ResourceSyncCallHandler enumerate_video_devices_handler( &sink(), - PpapiHostMsg_VideoCapture_EnumerateDevices::ID, + PpapiHostMsg_DeviceEnumeration_EnumerateDevices::ID, expected_result, reply_msg); sink().AddFilter(&enumerate_video_devices_handler); // Set up the arguments to the call. ScopedPPResource video_capture(ScopedPPResource::PassRef(), - ::ppapi::thunk::GetPPB_VideoCapture_Dev_0_2_Thunk()->Create( + ::ppapi::thunk::GetPPB_VideoCapture_Dev_0_3_Thunk()->Create( pp_instance())); std::vector<PP_Resource> unused; PP_ArrayOutput output; @@ -59,9 +59,9 @@ TEST_F(FlashResourceTest, EnumerateVideoCaptureDevices) { // Check the result is as expected. EXPECT_EQ(expected_result, actual_result); - // Should have sent an "VideoCapture_EnumerateDevices" message. + // Should have sent an "DeviceEnumeration_EnumerateDevices" message. ASSERT_TRUE(enumerate_video_devices_handler.last_handled_msg().type() == - PpapiHostMsg_VideoCapture_EnumerateDevices::ID); + PpapiHostMsg_DeviceEnumeration_EnumerateDevices::ID); // Remove the filter or it will be destroyed before the sink() is destroyed. sink().RemoveFilter(&enumerate_video_devices_handler); diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index 3ccc3df..b964e1f 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -1704,9 +1704,6 @@ IPC_MESSAGE_CONTROL0(PpapiHostMsg_VideoCapture_StopCapture) IPC_MESSAGE_CONTROL0(PpapiHostMsg_VideoCapture_Close) // VideoCapture_Dev, plugin -> host -> plugin -IPC_MESSAGE_CONTROL0(PpapiHostMsg_VideoCapture_EnumerateDevices) -IPC_MESSAGE_CONTROL1(PpapiPluginMsg_VideoCapture_EnumerateDevicesReply, - std::vector<ppapi::DeviceRefData> /* devices */) IPC_MESSAGE_CONTROL3(PpapiHostMsg_VideoCapture_Open, std::string /* device_id */, PP_VideoCaptureDeviceInfo_Dev /* requested_info */, diff --git a/ppapi/proxy/video_capture_resource.cc b/ppapi/proxy/video_capture_resource.cc index 7264b85..ca88adf 100644 --- a/ppapi/proxy/video_capture_resource.cc +++ b/ppapi/proxy/video_capture_resource.cc @@ -12,7 +12,6 @@ #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/ppb_buffer_proxy.h" #include "ppapi/proxy/resource_message_params.h" -#include "ppapi/shared_impl/array_writer.h" #include "ppapi/shared_impl/proxy_lock.h" #include "ppapi/shared_impl/tracked_callback.h" @@ -25,7 +24,7 @@ VideoCaptureResource::VideoCaptureResource( PluginDispatcher* dispatcher) : PluginResource(connection, instance), open_state_(BEFORE_OPEN), - has_pending_enum_devices_callback_(false) { + ALLOW_THIS_IN_INITIALIZER_LIST(enumeration_helper_(this)) { SendCreate(RENDERER, PpapiHostMsg_VideoCapture_Create()); ppp_video_capture_impl_ = static_cast<const PPP_VideoCapture_Dev*>( @@ -38,6 +37,9 @@ VideoCaptureResource::~VideoCaptureResource() { void VideoCaptureResource::OnReplyReceived( const ResourceMessageReplyParams& params, const IPC::Message& msg) { + if (enumeration_helper_.HandleReply(params, msg)) + return; + if (params.sequence()) { PluginResource::OnReplyReceived(params, msg); return; @@ -60,22 +62,22 @@ void VideoCaptureResource::OnReplyReceived( IPC_END_MESSAGE_MAP() } -int32_t VideoCaptureResource::EnumerateDevices( +int32_t VideoCaptureResource::EnumerateDevices0_2( PP_Resource* devices, scoped_refptr<TrackedCallback> callback) { - if (has_pending_enum_devices_callback_) - return PP_ERROR_INPROGRESS; + return enumeration_helper_.EnumerateDevices0_2(devices, callback); +} - has_pending_enum_devices_callback_ = true; +int32_t VideoCaptureResource::EnumerateDevices( + const PP_ArrayOutput& output, + scoped_refptr<TrackedCallback> callback) { + return enumeration_helper_.EnumerateDevices(output, callback); +} - Call<PpapiPluginMsg_VideoCapture_EnumerateDevicesReply>( - RENDERER, - PpapiHostMsg_VideoCapture_EnumerateDevices(), - base::Bind(&VideoCaptureResource::OnPluginMsgEnumerateDevicesReply, - this, - devices, - callback)); - return PP_OK_COMPLETIONPENDING; +int32_t VideoCaptureResource::MonitorDeviceChange( + PP_MonitorDeviceChangeCallback callback, + void* user_data) { + return enumeration_helper_.MonitorDeviceChange(callback, user_data); } int32_t VideoCaptureResource::Open( @@ -102,7 +104,6 @@ int32_t VideoCaptureResource::StartCapture() { if (open_state_ != OPENED) return PP_ERROR_FAILED; - buffer_in_use_.clear(); Post(RENDERER, PpapiHostMsg_VideoCapture_StartCapture()); return PP_OK; } @@ -136,28 +137,11 @@ void VideoCaptureResource::Close() { int32_t VideoCaptureResource::EnumerateDevicesSync( const PP_ArrayOutput& devices) { - ArrayWriter output; - output.set_pp_array_output(devices); - if (!output.is_valid()) - return PP_ERROR_BADARGUMENT; - - std::vector<ppapi::DeviceRefData> device_ref_data; - int32_t result = SyncCall<PpapiPluginMsg_VideoCapture_EnumerateDevicesReply>( - RENDERER, - PpapiHostMsg_VideoCapture_EnumerateDevices(), - &device_ref_data); - - std::vector<scoped_refptr<Resource> > device_resources; - for (size_t i = 0; i < device_ref_data.size(); ++i) { - scoped_refptr<Resource> resource(new PPB_DeviceRef_Shared( - OBJECT_IS_PROXY, pp_instance(), device_ref_data[i])); - device_resources.push_back(resource); - } - - if (!output.StoreResourceVector(device_resources)) - return PP_ERROR_FAILED; + return enumeration_helper_.EnumerateDevicesSync(devices); +} - return result; +void VideoCaptureResource::LastPluginRefWasDeleted() { + enumeration_helper_.LastPluginRefWasDeleted(); } void VideoCaptureResource::OnPluginMsgOnDeviceInfo( @@ -247,29 +231,8 @@ void VideoCaptureResource::OnPluginMsgOpenReply( open_callback_->Run(params.result()); } -void VideoCaptureResource::OnPluginMsgEnumerateDevicesReply( - PP_Resource* devices_output, - scoped_refptr<TrackedCallback> callback, - const ResourceMessageReplyParams& params, - const std::vector<DeviceRefData>& devices) { - if (!TrackedCallback::IsPending(callback)) - return; - - DCHECK(has_pending_enum_devices_callback_); - has_pending_enum_devices_callback_ = false; - - if (params.result() == PP_OK && devices_output) { - // devices_output points to the resource array of PP_ArrayOutput. In C++, - // it's typically allocated in VideoCapture_Dev. - *devices_output = PPB_DeviceRef_Shared::CreateResourceArray( - OBJECT_IS_PROXY, pp_instance(), devices); - } - - callback->Run(params.result()); -} - void VideoCaptureResource::SetBufferInUse(uint32_t buffer_index) { - DCHECK(buffer_index < buffer_in_use_.size()); + CHECK(buffer_index < buffer_in_use_.size()); buffer_in_use_[buffer_index] = true; } diff --git a/ppapi/proxy/video_capture_resource.h b/ppapi/proxy/video_capture_resource.h index 7e7eedb..e533ef0 100644 --- a/ppapi/proxy/video_capture_resource.h +++ b/ppapi/proxy/video_capture_resource.h @@ -7,6 +7,7 @@ #include "base/compiler_specific.h" #include "ppapi/c/dev/ppp_video_capture_dev.h" +#include "ppapi/proxy/device_enumeration_resource_helper.h" #include "ppapi/proxy/plugin_resource.h" #include "ppapi/thunk/ppb_video_capture_api.h" @@ -28,9 +29,15 @@ class VideoCaptureResource } // PPB_VideoCapture_API implementation. - virtual int32_t EnumerateDevices( + virtual int32_t EnumerateDevices0_2( PP_Resource* devices, scoped_refptr<TrackedCallback> callback) OVERRIDE; + virtual int32_t EnumerateDevices( + const PP_ArrayOutput& output, + scoped_refptr<TrackedCallback> callback) OVERRIDE; + virtual int32_t MonitorDeviceChange( + PP_MonitorDeviceChangeCallback callback, + void* user_data) OVERRIDE; virtual int32_t Open(const std::string& device_id, const PP_VideoCaptureDeviceInfo_Dev& requested_info, uint32_t buffer_count, @@ -41,6 +48,10 @@ class VideoCaptureResource virtual void Close() OVERRIDE; virtual int32_t EnumerateDevicesSync(const PP_ArrayOutput& devices) OVERRIDE; + protected: + // Resource override. + virtual void LastPluginRefWasDeleted() OVERRIDE; + private: enum OpenState { BEFORE_OPEN, @@ -64,11 +75,6 @@ class VideoCaptureResource uint32_t buffer); void OnPluginMsgOpenReply(const ResourceMessageReplyParams& params); - void OnPluginMsgEnumerateDevicesReply( - PP_Resource* devices_output, - scoped_refptr<TrackedCallback> callback, - const ResourceMessageReplyParams& params, - const std::vector<DeviceRefData>& devices); void SetBufferInUse(uint32_t buffer_index); @@ -82,7 +88,7 @@ class VideoCaptureResource scoped_refptr<TrackedCallback> open_callback_; OpenState open_state_; - bool has_pending_enum_devices_callback_; + DeviceEnumerationResourceHelper enumeration_helper_; DISALLOW_COPY_AND_ASSIGN(VideoCaptureResource); }; diff --git a/ppapi/thunk/interfaces_ppb_public_dev.h b/ppapi/thunk/interfaces_ppb_public_dev.h index 08ddc59..d380cad 100644 --- a/ppapi/thunk/interfaces_ppb_public_dev.h +++ b/ppapi/thunk/interfaces_ppb_public_dev.h @@ -63,6 +63,8 @@ PROXIED_IFACE(PPB_Instance, PPB_TEXTINPUT_DEV_INTERFACE_0_1, PPB_TextInput_Dev_0_1) PROXIED_IFACE(NoAPIName, PPB_VIDEOCAPTURE_DEV_INTERFACE_0_2, PPB_VideoCapture_Dev_0_2) +PROXIED_IFACE(NoAPIName, PPB_VIDEOCAPTURE_DEV_INTERFACE_0_3, + PPB_VideoCapture_Dev_0_3) PROXIED_IFACE(PPB_VideoDecoder, PPB_VIDEODECODER_DEV_INTERFACE_0_16, PPB_VideoDecoder_Dev_0_16) UNPROXIED_IFACE(PPB_Widget, PPB_WIDGET_DEV_INTERFACE_0_3, PPB_Widget_Dev_0_3) diff --git a/ppapi/thunk/ppb_video_capture_api.h b/ppapi/thunk/ppb_video_capture_api.h index a12e201..baa7e00 100644 --- a/ppapi/thunk/ppb_video_capture_api.h +++ b/ppapi/thunk/ppb_video_capture_api.h @@ -15,7 +15,6 @@ namespace ppapi { -struct DeviceRefData; class TrackedCallback; namespace thunk { @@ -24,8 +23,13 @@ class PPB_VideoCapture_API { public: virtual ~PPB_VideoCapture_API() {} - virtual int32_t EnumerateDevices(PP_Resource* devices, + virtual int32_t EnumerateDevices0_2( + PP_Resource* devices, + scoped_refptr<TrackedCallback> callback) = 0; + virtual int32_t EnumerateDevices(const PP_ArrayOutput& output, scoped_refptr<TrackedCallback> callback) = 0; + virtual int32_t MonitorDeviceChange(PP_MonitorDeviceChangeCallback callback, + void* user_data) = 0; virtual int32_t Open(const std::string& device_id, const PP_VideoCaptureDeviceInfo_Dev& requested_info, uint32_t buffer_count, diff --git a/ppapi/thunk/ppb_video_capture_thunk.cc b/ppapi/thunk/ppb_video_capture_thunk.cc index 1ab038f..9d6571e 100644 --- a/ppapi/thunk/ppb_video_capture_thunk.cc +++ b/ppapi/thunk/ppb_video_capture_thunk.cc @@ -30,17 +30,37 @@ PP_Bool IsVideoCapture(PP_Resource resource) { return PP_FromBool(enter.succeeded()); } +int32_t EnumerateDevices0_2(PP_Resource video_capture, + PP_Resource* devices, + PP_CompletionCallback callback) { + EnterVideoCapture enter(video_capture, callback, true); + if (enter.failed()) + return enter.retval(); + + return enter.SetResult(enter.object()->EnumerateDevices0_2(devices, + enter.callback())); +} + int32_t EnumerateDevices(PP_Resource video_capture, - PP_Resource* devices, + PP_ArrayOutput output, PP_CompletionCallback callback) { EnterVideoCapture enter(video_capture, callback, true); if (enter.failed()) return enter.retval(); - return enter.SetResult(enter.object()->EnumerateDevices(devices, + return enter.SetResult(enter.object()->EnumerateDevices(output, enter.callback())); } +int32_t MonitorDeviceChange(PP_Resource video_capture, + PP_MonitorDeviceChangeCallback callback, + void* user_data) { + EnterVideoCapture enter(video_capture, true); + if (enter.failed()) + return enter.retval(); + return enter.object()->MonitorDeviceChange(callback, user_data); +} + int32_t Open(PP_Resource video_capture, PP_Resource device_ref, const PP_VideoCaptureDeviceInfo_Dev* requested_info, @@ -95,7 +115,19 @@ void Close(PP_Resource video_capture) { const PPB_VideoCapture_Dev_0_2 g_ppb_video_capture_0_2_thunk = { &Create, &IsVideoCapture, + &EnumerateDevices0_2, + &Open, + &StartCapture, + &ReuseBuffer, + &StopCapture, + &Close +}; + +const PPB_VideoCapture_Dev_0_3 g_ppb_video_capture_0_3_thunk = { + &Create, + &IsVideoCapture, &EnumerateDevices, + &MonitorDeviceChange, &Open, &StartCapture, &ReuseBuffer, @@ -109,5 +141,9 @@ const PPB_VideoCapture_Dev_0_2* GetPPB_VideoCapture_Dev_0_2_Thunk() { return &g_ppb_video_capture_0_2_thunk; } +const PPB_VideoCapture_Dev_0_3* GetPPB_VideoCapture_Dev_0_3_Thunk() { + return &g_ppb_video_capture_0_3_thunk; +} + } // namespace thunk } // namespace ppapi |