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

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: Changes in response to Antoine's comments. Created 8 years, 11 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
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 f2cb26cd87ab95516792e47f40bc078db904a5e9..fe10a975edb8508236f2d6541dba0c93eb5ffccf 100644
--- a/webkit/plugins/ppapi/ppb_video_capture_impl.cc
+++ b/webkit/plugins/ppapi/ppb_video_capture_impl.cc
@@ -1,4 +1,4 @@
-// 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.
@@ -7,12 +7,15 @@
#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/thunk/enter.h"
#include "webkit/plugins/ppapi/common.h"
@@ -21,10 +24,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 {
@@ -41,14 +46,18 @@ PPB_VideoCapture_Impl::PPB_VideoCapture_Impl(PP_Instance instance)
buffer_count_hint_(0),
ppp_videocapture_(NULL),
status_(PP_VIDEO_CAPTURE_STATUS_STOPPED),
- is_dead_(false) {
+ devices_(0),
+ capability_() {
}
PPB_VideoCapture_Impl::~PPB_VideoCapture_Impl() {
+ StopCapture();
+ DCHECK(buffers_.empty());
+ ClearCachedDeviceResourceArray();
+ DetachPlatformVideoCapture();
}
bool PPB_VideoCapture_Impl::Init() {
- DCHECK(!is_dead_);
PluginInstance* instance = ResourceHelper::GetPluginInstance(this);
if (!instance)
return false;
@@ -57,59 +66,83 @@ bool PPB_VideoCapture_Impl::Init() {
if (!ppp_videocapture_)
return false;
- platform_video_capture_.reset(
- instance->delegate()->CreateVideoCapture(this));
- return !!platform_video_capture_.get();
+ return true;
}
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;
+int32_t PPB_VideoCapture_Impl::EnumerateDevices(
+ PP_CompletionCallback callback) {
+ if (!callback.func)
+ return PP_ERROR_BLOCKS_MAIN_THREAD;
+ if (TrackedCallback::IsPending(enumerate_devices_callback_))
+ return PP_ERROR_INPROGRESS;
- ::ppapi::Resource::LastPluginRefWasDeleted();
+ PluginInstance* instance = ResourceHelper::GetPluginInstance(this);
+ if (!instance)
+ return PP_ERROR_FAILED;
+
+ enumerate_devices_callback_ = new TrackedCallback(this, callback);
+ instance->delegate()->EnumerateDevices(
+ PP_DEVICETYPE_DEV_VIDEOCAPTURE,
+ base::Bind(&PPB_VideoCapture_Impl::OnEnumerateDevicesComplete,
+ AsWeakPtr()));
+ return PP_OK_COMPLETIONPENDING;
+}
+
+PP_Resource PPB_VideoCapture_Impl::GetDevices() {
+ if (devices_)
+ PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(devices_);
+ return devices_;
}
int32_t PPB_VideoCapture_Impl::StartCapture(
+ const std::string& device_id,
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:
+ case PP_VIDEO_CAPTURE_STATUS_STOPPING:
default:
return PP_ERROR_FAILED;
case PP_VIDEO_CAPTURE_STATUS_STOPPED:
- case PP_VIDEO_CAPTURE_STATUS_STOPPING:
break;
}
+
+ PluginInstance* instance = ResourceHelper::GetPluginInstance(this);
+ if (!instance)
+ return PP_ERROR_FAILED;
+
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
- };
+
+ capability_.width = requested_info.width;
+ capability_.height = requested_info.height;
+ capability_.max_fps = requested_info.frames_per_second;
+ capability_.expected_capture_delay = 0; // Ignored.
+ capability_.raw_type = media::VideoFrame::I420;
+ capability_.interlaced = false; // Ignored.
+
status_ = PP_VIDEO_CAPTURE_STATUS_STARTING;
- AddRef(); // Balanced in |OnRemoved()|.
- platform_video_capture_->StartCapture(this, capability);
+
+ DetachPlatformVideoCapture();
+ platform_video_capture_ =
+ instance->delegate()->CreateVideoCapture(device_id, this);
+ // If |device_id| is not empty, StartCapture() will be performed in the
+ // OnInitialized() handler.
+ if (device_id.empty())
+ 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;
@@ -117,7 +150,6 @@ int32_t PPB_VideoCapture_Impl::ReuseBuffer(uint32_t buffer) {
}
int32_t PPB_VideoCapture_Impl::StopCapture() {
- DCHECK(!is_dead_);
switch (status_) {
case PP_VIDEO_CAPTURE_STATUS_STOPPED:
case PP_VIDEO_CAPTURE_STATUS_STOPPING:
@@ -128,16 +160,20 @@ int32_t PPB_VideoCapture_Impl::StopCapture() {
case PP_VIDEO_CAPTURE_STATUS_PAUSED:
break;
}
+ DCHECK(platform_video_capture_.get());
+
ReleaseBuffers();
status_ = PP_VIDEO_CAPTURE_STATUS_STOPPING;
platform_video_capture_->StopCapture(this);
return PP_OK;
}
-void PPB_VideoCapture_Impl::OnStarted(media::VideoCapture* capture) {
- if (is_dead_)
- return;
+const std::vector<DeviceRefData>&
+ PPB_VideoCapture_Impl::GetDeviceRefData() const {
+ return devices_data_;
+}
+void PPB_VideoCapture_Impl::OnStarted(media::VideoCapture* capture) {
switch (status_) {
case PP_VIDEO_CAPTURE_STATUS_STARTING:
case PP_VIDEO_CAPTURE_STATUS_PAUSED:
@@ -153,9 +189,6 @@ void PPB_VideoCapture_Impl::OnStarted(media::VideoCapture* capture) {
}
void PPB_VideoCapture_Impl::OnStopped(media::VideoCapture* capture) {
- if (is_dead_)
- return;
-
switch (status_) {
case PP_VIDEO_CAPTURE_STATUS_STOPPING:
break;
@@ -166,14 +199,12 @@ void PPB_VideoCapture_Impl::OnStopped(media::VideoCapture* capture) {
default:
return;
}
+
status_ = PP_VIDEO_CAPTURE_STATUS_STOPPED;
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:
@@ -190,9 +221,6 @@ void PPB_VideoCapture_Impl::OnPaused(media::VideoCapture* capture) {
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
@@ -203,42 +231,31 @@ void PPB_VideoCapture_Impl::OnError(media::VideoCapture* capture,
}
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,
@@ -286,8 +303,22 @@ 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());
+
+ if (status_ != PP_VIDEO_CAPTURE_STATUS_STARTING)
+ return;
+
+ if (succeeded) {
+ platform_video_capture_->StartCapture(this, capability_);
+ } else {
+ status_ = PP_VIDEO_CAPTURE_STATUS_STOPPED;
+ SendStatus();
+ }
+}
+
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 +328,43 @@ 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::ClearCachedDeviceResourceArray() {
+ if (devices_)
+ PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(devices_);
+ devices_ = 0;
+
+ devices_data_.clear();
+}
+
+void PPB_VideoCapture_Impl::DetachPlatformVideoCapture() {
+ if (platform_video_capture_.get()) {
+ platform_video_capture_->DetachEventHandler();
+ platform_video_capture_ = NULL;
+ }
+}
+
+void PPB_VideoCapture_Impl::OnEnumerateDevicesComplete(
+ int request_id,
+ bool succeeded,
+ const std::vector<::ppapi::DeviceRefData>& devices) {
+ ClearCachedDeviceResourceArray();
brettw 2012/02/06 21:51:52 This seems like it's a good opportunity to move in
yzshen1 2012/02/10 07:10:44 Done. I moved shared code into shared_impl and als
+ if (succeeded) {
+ devices_data_ = devices;
+ devices_ = ::ppapi::PPB_DeviceRef_Shared::CreateResourceArray(
+ true, pp_instance(), devices_data_);
+ }
+
+ if (!TrackedCallback::IsPending(enumerate_devices_callback_)) {
+ NOTREACHED();
+ return;
+ }
+ TrackedCallback::ClearAndRun(&enumerate_devices_callback_,
+ succeeded ? PP_OK : PP_ERROR_FAILED);
+}
+
PPB_VideoCapture_Impl::BufferInfo::BufferInfo()
: in_use(false),
data(NULL),

Powered by Google App Engine
This is Rietveld 408576698