Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Unified Diff: webkit/plugins/ppapi/ppb_video_capture_impl.cc

Issue 9234064: Implement device enumeration for PPB_VideoCapture_Dev. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webkit/plugins/ppapi/ppb_video_capture_impl.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webkit/plugins/ppapi/ppb_video_capture_impl.cc
diff --git a/webkit/plugins/ppapi/ppb_video_capture_impl.cc b/webkit/plugins/ppapi/ppb_video_capture_impl.cc
index 63a19a4cbc607ca3df5339a8a6fd8057c41af20e..cab216e8bcf8daff2f90c85adf7388424feacb25 100644
--- a/webkit/plugins/ppapi/ppb_video_capture_impl.cc
+++ b/webkit/plugins/ppapi/ppb_video_capture_impl.cc
@@ -7,13 +7,17 @@
#include <algorithm>
#include <string>
+#include "base/bind.h"
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "ppapi/c/dev/pp_video_capture_dev.h"
#include "ppapi/c/dev/ppb_video_capture_dev.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/shared_impl/ppapi_globals.h"
+#include "ppapi/shared_impl/ppb_device_ref_shared.h"
#include "ppapi/shared_impl/resource_tracker.h"
+#include "ppapi/shared_impl/tracked_callback.h"
#include "ppapi/thunk/enter.h"
#include "webkit/plugins/ppapi/common.h"
#include "webkit/plugins/ppapi/plugin_module.h"
@@ -21,10 +25,12 @@
#include "webkit/plugins/ppapi/ppb_buffer_impl.h"
#include "webkit/plugins/ppapi/resource_helper.h"
+using ppapi::DeviceRefData;
using ppapi::PpapiGlobals;
using ppapi::thunk::EnterResourceNoLock;
using ppapi::thunk::PPB_Buffer_API;
using ppapi::thunk::PPB_VideoCapture_API;
+using ppapi::TrackedCallback;
namespace {
@@ -37,18 +43,17 @@ namespace webkit {
namespace ppapi {
PPB_VideoCapture_Impl::PPB_VideoCapture_Impl(PP_Instance instance)
- : Resource(::ppapi::OBJECT_IS_IMPL, instance),
+ : PPB_VideoCapture_Shared(instance),
buffer_count_hint_(0),
ppp_videocapture_(NULL),
- status_(PP_VIDEO_CAPTURE_STATUS_STOPPED),
- is_dead_(false) {
+ capability_() {
}
PPB_VideoCapture_Impl::~PPB_VideoCapture_Impl() {
+ Close();
}
bool PPB_VideoCapture_Impl::Init() {
- DCHECK(!is_dead_);
PluginInstance* instance = ResourceHelper::GetPluginInstance(this);
if (!instance)
return false;
@@ -57,188 +62,61 @@ bool PPB_VideoCapture_Impl::Init() {
if (!ppp_videocapture_)
return false;
- platform_video_capture_.reset(
- instance->delegate()->CreateVideoCapture(this));
- return !!platform_video_capture_.get();
-}
-
-PPB_VideoCapture_API* PPB_VideoCapture_Impl::AsPPB_VideoCapture_API() {
- return this;
-}
-
-void PPB_VideoCapture_Impl::LastPluginRefWasDeleted() {
- if (platform_video_capture_.get())
- StopCapture();
- DCHECK(buffers_.empty());
- ppp_videocapture_ = NULL;
- is_dead_ = true;
-
- ::ppapi::Resource::LastPluginRefWasDeleted();
-}
-
-int32_t PPB_VideoCapture_Impl::StartCapture(
- const PP_VideoCaptureDeviceInfo_Dev& requested_info,
- uint32_t buffer_count) {
- DCHECK(!is_dead_);
- 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;
- }
- DCHECK(buffers_.empty());
-
- // Clamp the buffer count to between 1 and |kMaxBuffers|.
- buffer_count_hint_ = std::min(std::max(buffer_count, 1U), kMaxBuffers);
- media::VideoCapture::VideoCaptureCapability capability = {
- requested_info.width,
- requested_info.height,
- requested_info.frames_per_second,
- 0, // ignored.
- media::VideoFrame::I420,
- false, // ignored
- };
- status_ = PP_VIDEO_CAPTURE_STATUS_STARTING;
- AddRef(); // Balanced in |OnRemoved()|.
- platform_video_capture_->StartCapture(this, capability);
- return PP_OK;
-}
-
-int32_t PPB_VideoCapture_Impl::ReuseBuffer(uint32_t buffer) {
- DCHECK(!is_dead_);
- if (buffer >= buffers_.size() || !buffers_[buffer].in_use)
- return PP_ERROR_BADARGUMENT;
- buffers_[buffer].in_use = false;
- return PP_OK;
-}
-
-int32_t PPB_VideoCapture_Impl::StopCapture() {
- DCHECK(!is_dead_);
- 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;
- }
- ReleaseBuffers();
- status_ = PP_VIDEO_CAPTURE_STATUS_STOPPING;
- platform_video_capture_->StopCapture(this);
- return PP_OK;
+ return true;
}
void PPB_VideoCapture_Impl::OnStarted(media::VideoCapture* capture) {
- if (is_dead_)
- return;
-
- switch (status_) {
- case PP_VIDEO_CAPTURE_STATUS_STARTING:
- case PP_VIDEO_CAPTURE_STATUS_PAUSED:
- break;
- case PP_VIDEO_CAPTURE_STATUS_STOPPED:
- case PP_VIDEO_CAPTURE_STATUS_STOPPING:
- case PP_VIDEO_CAPTURE_STATUS_STARTED:
- default:
- return;
- }
- status_ = PP_VIDEO_CAPTURE_STATUS_STARTED;
- SendStatus();
+ if (SetStatus(PP_VIDEO_CAPTURE_STATUS_STARTED, false))
+ SendStatus();
}
void PPB_VideoCapture_Impl::OnStopped(media::VideoCapture* capture) {
- if (is_dead_)
- return;
-
- switch (status_) {
- case PP_VIDEO_CAPTURE_STATUS_STOPPING:
- break;
- case PP_VIDEO_CAPTURE_STATUS_STARTING:
- case PP_VIDEO_CAPTURE_STATUS_PAUSED:
- case PP_VIDEO_CAPTURE_STATUS_STOPPED:
- case PP_VIDEO_CAPTURE_STATUS_STARTED:
- default:
- return;
- }
- status_ = PP_VIDEO_CAPTURE_STATUS_STOPPED;
- SendStatus();
+ if (SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPED, false))
+ SendStatus();
}
void PPB_VideoCapture_Impl::OnPaused(media::VideoCapture* capture) {
- if (is_dead_)
- return;
-
- switch (status_) {
- case PP_VIDEO_CAPTURE_STATUS_STARTING:
- case PP_VIDEO_CAPTURE_STATUS_STARTED:
- break;
- case PP_VIDEO_CAPTURE_STATUS_STOPPED:
- case PP_VIDEO_CAPTURE_STATUS_STOPPING:
- case PP_VIDEO_CAPTURE_STATUS_PAUSED:
- default:
- return;
- }
- status_ = PP_VIDEO_CAPTURE_STATUS_PAUSED;
- SendStatus();
+ if (SetStatus(PP_VIDEO_CAPTURE_STATUS_PAUSED, false))
+ SendStatus();
}
void PPB_VideoCapture_Impl::OnError(media::VideoCapture* capture,
int error_code) {
- if (is_dead_)
- return;
-
// Today, the media layer only sends "1" as an error.
DCHECK(error_code == 1);
// It either comes because some error was detected while starting (e.g. 2
// conflicting "master" resolution), or because the browser failed to start
// the capture.
- status_ = PP_VIDEO_CAPTURE_STATUS_STOPPED;
+ SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPED, true);
ppp_videocapture_->OnError(pp_instance(), pp_resource(), PP_ERROR_FAILED);
}
void PPB_VideoCapture_Impl::OnRemoved(media::VideoCapture* capture) {
- Release();
}
void PPB_VideoCapture_Impl::OnBufferReady(
media::VideoCapture* capture,
scoped_refptr<media::VideoCapture::VideoFrameBuffer> buffer) {
- if (!is_dead_) {
- DCHECK(buffer.get());
- for (uint32_t i = 0; i < buffers_.size(); ++i) {
- if (!buffers_[i].in_use) {
- // TODO(ihf): Switch to a size calculation based on stride.
- // Stride is filled out now but not more meaningful than size
- // until wjia unifies VideoFrameBuffer and media::VideoFrame.
- size_t size = std::min(static_cast<size_t>(buffers_[i].buffer->size()),
- buffer->buffer_size);
- memcpy(buffers_[i].data, buffer->memory_pointer, size);
- buffers_[i].in_use = true;
- platform_video_capture_->FeedBuffer(buffer);
- ppp_videocapture_->OnBufferReady(pp_instance(), pp_resource(), i);
- return;
- }
+ DCHECK(buffer.get());
+ for (uint32_t i = 0; i < buffers_.size(); ++i) {
+ if (!buffers_[i].in_use) {
+ // TODO(ihf): Switch to a size calculation based on stride.
+ // Stride is filled out now but not more meaningful than size
+ // until wjia unifies VideoFrameBuffer and media::VideoFrame.
+ size_t size = std::min(static_cast<size_t>(buffers_[i].buffer->size()),
+ buffer->buffer_size);
+ memcpy(buffers_[i].data, buffer->memory_pointer, size);
+ buffers_[i].in_use = true;
+ platform_video_capture_->FeedBuffer(buffer);
+ ppp_videocapture_->OnBufferReady(pp_instance(), pp_resource(), i);
+ return;
}
}
- // Even after we have stopped and are dead we have to return buffers that
- // are in flight to us. Otherwise VideoCaptureController will not tear down.
- platform_video_capture_->FeedBuffer(buffer);
}
void PPB_VideoCapture_Impl::OnDeviceInfoReceived(
media::VideoCapture* capture,
const media::VideoCaptureParams& device_info) {
- // No need to call |ReleaseBuffers()|: if we're dead, |StopCapture()| should
- // already have been called.
- if (is_dead_)
- return;
-
PP_VideoCaptureDeviceInfo_Dev info = {
device_info.width,
device_info.height,
@@ -277,7 +155,7 @@ void PPB_VideoCapture_Impl::OnDeviceInfoReceived(
// We couldn't allocate/map buffers at all. Send an error and stop the
// capture.
ppp_videocapture_->OnError(pp_instance(), pp_resource(), PP_ERROR_NOMEMORY);
- status_ = PP_VIDEO_CAPTURE_STATUS_STOPPING;
+ SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPING, true);
platform_video_capture_->StopCapture(this);
return;
}
@@ -286,8 +164,112 @@ void PPB_VideoCapture_Impl::OnDeviceInfoReceived(
buffers_.size(), resources.get());
}
+void PPB_VideoCapture_Impl::OnInitialized(media::VideoCapture* capture,
+ bool succeeded) {
+ DCHECK(capture == platform_video_capture_.get());
+
+ OnOpenComplete(succeeded ? PP_OK : PP_ERROR_FAILED);
+}
+
+int32_t PPB_VideoCapture_Impl::InternalEnumerateDevices(
+ PP_Resource* devices,
+ PP_CompletionCallback callback) {
+ PluginInstance* instance = ResourceHelper::GetPluginInstance(this);
+ if (!instance)
+ return PP_ERROR_FAILED;
+
+ devices_ = devices;
+ enumerate_devices_callback_ = new TrackedCallback(this, callback);
+ instance->delegate()->EnumerateDevices(
+ PP_DEVICETYPE_DEV_VIDEOCAPTURE,
+ base::Bind(&PPB_VideoCapture_Impl::EnumerateDevicesCallbackFunc,
+ AsWeakPtr()));
+ return PP_OK_COMPLETIONPENDING;
+}
+
+int32_t PPB_VideoCapture_Impl::InternalOpen(
+ const std::string& device_id,
+ const PP_VideoCaptureDeviceInfo_Dev& requested_info,
+ uint32_t buffer_count,
+ PP_CompletionCallback callback) {
+ // It is able to complete synchronously if the default device is used.
+ bool sync_completion = device_id.empty();
+
+ if (!callback.func && !sync_completion)
+ return PP_ERROR_BLOCKS_MAIN_THREAD;
+
+ PluginInstance* instance = ResourceHelper::GetPluginInstance(this);
+ if (!instance)
+ return PP_ERROR_FAILED;
+
+ SetRequestedInfo(requested_info, buffer_count);
+
+ DCHECK(!platform_video_capture_.get());
+ platform_video_capture_ =
+ instance->delegate()->CreateVideoCapture(device_id, this);
+
+ if (sync_completion) {
+ OnInitialized(platform_video_capture_.get(), true);
+ return PP_OK;
+ } else {
+ open_callback_ = new TrackedCallback(this, callback);
+ return PP_OK_COMPLETIONPENDING;
+ }
+}
+
+int32_t PPB_VideoCapture_Impl::InternalStartCapture() {
+ DCHECK(buffers_.empty());
+ platform_video_capture_->StartCapture(this, capability_);
+ return PP_OK;
+}
+
+int32_t PPB_VideoCapture_Impl::InternalReuseBuffer(uint32_t buffer) {
+ if (buffer >= buffers_.size() || !buffers_[buffer].in_use)
+ return PP_ERROR_BADARGUMENT;
+ buffers_[buffer].in_use = false;
+ return PP_OK;
+}
+
+int32_t PPB_VideoCapture_Impl::InternalStopCapture() {
+ ReleaseBuffers();
+ platform_video_capture_->StopCapture(this);
+ return PP_OK;
+}
+
+void PPB_VideoCapture_Impl::InternalClose() {
+ StopCapture();
+ DCHECK(buffers_.empty());
+
+ DetachPlatformVideoCapture();
+}
+
+int32_t PPB_VideoCapture_Impl::InternalStartCapture0_1(
+ const PP_VideoCaptureDeviceInfo_Dev& requested_info,
+ uint32_t buffer_count) {
+ PluginInstance* instance = ResourceHelper::GetPluginInstance(this);
+ if (!instance) {
+ SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPED, true);
+ return PP_ERROR_FAILED;
+ }
+
+ DCHECK(buffers_.empty());
+
+ SetRequestedInfo(requested_info, buffer_count);
+
+ DetachPlatformVideoCapture();
+ platform_video_capture_ =
+ instance->delegate()->CreateVideoCapture("", this);
+ platform_video_capture_->StartCapture(this, capability_);
+
+ return PP_OK;
+}
+
+const PPB_VideoCapture_Impl::DeviceRefDataVector&
+ PPB_VideoCapture_Impl::InternalGetDeviceRefData() const {
+ return devices_data_;
+}
+
void PPB_VideoCapture_Impl::ReleaseBuffers() {
- DCHECK(!is_dead_);
::ppapi::ResourceTracker* tracker = PpapiGlobals::Get()->GetResourceTracker();
for (size_t i = 0; i < buffers_.size(); ++i) {
buffers_[i].buffer->Unmap();
@@ -297,10 +279,41 @@ void PPB_VideoCapture_Impl::ReleaseBuffers() {
}
void PPB_VideoCapture_Impl::SendStatus() {
- DCHECK(!is_dead_);
ppp_videocapture_->OnStatus(pp_instance(), pp_resource(), status_);
}
+void PPB_VideoCapture_Impl::SetRequestedInfo(
+ const PP_VideoCaptureDeviceInfo_Dev& device_info,
+ uint32_t buffer_count) {
+ // Clamp the buffer count to between 1 and |kMaxBuffers|.
+ buffer_count_hint_ = std::min(std::max(buffer_count, 1U), kMaxBuffers);
+
+ capability_.width = device_info.width;
+ capability_.height = device_info.height;
+ capability_.max_fps = device_info.frames_per_second;
+ capability_.expected_capture_delay = 0; // Ignored.
+ capability_.raw_type = media::VideoFrame::I420;
+ capability_.interlaced = false; // Ignored.
+}
+
+void PPB_VideoCapture_Impl::DetachPlatformVideoCapture() {
+ if (platform_video_capture_.get()) {
+ platform_video_capture_->DetachEventHandler();
+ platform_video_capture_ = NULL;
+ }
+}
+
+void PPB_VideoCapture_Impl::EnumerateDevicesCallbackFunc(
+ int request_id,
+ bool succeeded,
+ const DeviceRefDataVector& devices) {
+ devices_data_.clear();
+ if (succeeded)
+ devices_data_ = devices;
+
+ OnEnumerateDevicesComplete(succeeded ? PP_OK : PP_ERROR_FAILED, devices);
+}
+
PPB_VideoCapture_Impl::BufferInfo::BufferInfo()
: in_use(false),
data(NULL),
« no previous file with comments | « webkit/plugins/ppapi/ppb_video_capture_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698