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

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

Issue 7553003: Video Capture Pepper API (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Make Clang happy Created 9 years, 4 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') | webkit/plugins/ppapi/resource_creation_impl.h » ('j') | 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
new file mode 100644
index 0000000000000000000000000000000000000000..c112fce5e8b3503c9908d5cc378f29d1c17dbabc
--- /dev/null
+++ b/webkit/plugins/ppapi/ppb_video_capture_impl.cc
@@ -0,0 +1,271 @@
+// Copyright (c) 2011 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 "webkit/plugins/ppapi/ppb_video_capture_impl.h"
+
+#include <algorithm>
+#include <string>
+
+#include "base/logging.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/thunk/enter.h"
+#include "webkit/plugins/ppapi/common.h"
+#include "webkit/plugins/ppapi/plugin_module.h"
+#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
+#include "webkit/plugins/ppapi/ppb_buffer_impl.h"
+#include "webkit/plugins/ppapi/resource_tracker.h"
+
+using ppapi::thunk::EnterResourceNoLock;
+using ppapi::thunk::PPB_Buffer_API;
+using ppapi::thunk::PPB_VideoCapture_API;
+
+namespace webkit {
+namespace ppapi {
+
+PPB_VideoCapture_Impl::PPB_VideoCapture_Impl(PluginInstance* instance)
+ : Resource(instance),
+ buffer_count_hint_(0),
+ ppp_videocapture_(NULL),
+ status_(PP_VIDEO_CAPTURE_STATUS_STOPPED) {
+}
+
+PPB_VideoCapture_Impl::~PPB_VideoCapture_Impl() {
+ if (platform_video_capture_.get())
+ StopCapture();
+}
+
+bool PPB_VideoCapture_Impl::Init() {
+ ppp_videocapture_ =
+ static_cast<const PPP_VideoCapture_Dev*>(instance()->module()->
+ GetPluginInterface(PPP_VIDEO_CAPTURE_DEV_INTERFACE));
+ 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;
+}
+
+int32_t PPB_VideoCapture_Impl::StartCapture(
+ 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;
+ }
+ DCHECK(buffers_.empty());
+
+ buffer_count_hint_ = std::min(buffer_count, 1U);
+ media::VideoCapture::VideoCaptureCapability capability = {
+ requested_info.width,
+ requested_info.height,
+ requested_info.frames_per_second,
+ 0, // ignored.
+ media::VideoFrame::I420,
+ false, // ignored
+ false // resolution_fixed
+ };
+ status_ = PP_VIDEO_CAPTURE_STATUS_STARTING;
+ platform_video_capture_->StartCapture(this, capability);
+ return PP_OK;
+}
+
+int32_t PPB_VideoCapture_Impl::ReuseBuffer(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::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;
+ }
+ ReleaseBuffers();
+ status_ = PP_VIDEO_CAPTURE_STATUS_STOPPING;
+ platform_video_capture_->StopCapture(this);
+ return PP_OK;
+}
+
+void PPB_VideoCapture_Impl::OnStarted(media::VideoCapture* capture) {
+ 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();
+}
+
+void PPB_VideoCapture_Impl::OnStopped(media::VideoCapture* capture) {
+ 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();
+}
+
+void PPB_VideoCapture_Impl::OnPaused(media::VideoCapture* capture) {
+ 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();
+}
+
+void PPB_VideoCapture_Impl::OnError(media::VideoCapture* capture,
+ int error_code) {
+ // 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;
+ ppp_videocapture_->OnError(instance()->pp_instance(),
+ ScopedResourceId(this).id,
+ PP_ERROR_FAILED);
+}
+
+void PPB_VideoCapture_Impl::OnBufferReady(
+ media::VideoCapture* capture,
+ scoped_refptr<media::VideoCapture::VideoFrameBuffer> buffer) {
+ DCHECK(buffer.get());
+ for (uint32_t i = 0; i < buffers_.size(); ++i) {
+ if (!buffers_[i].in_use) {
+ // TODO(piman): it looks like stride isn't actually used/filled.
+ DCHECK(buffer->stride == 0);
+ size_t size = std::min(static_cast<size_t>(buffers_[i].buffer->size()),
+ buffer->buffer_size);
+ memcpy(buffers_[i].data, buffer->memory_pointer, size);
+ platform_video_capture_->FeedBuffer(buffer);
+ ppp_videocapture_->OnBufferReady(instance()->pp_instance(),
+ ScopedResourceId(this).id,
+ i);
+ return;
+ }
+ }
+ // TODO(piman): signal dropped buffers ?
+ platform_video_capture_->FeedBuffer(buffer);
+}
+
+void PPB_VideoCapture_Impl::OnDeviceInfoReceived(
+ media::VideoCapture* capture,
+ const media::VideoCaptureParams& device_info) {
+ PP_VideoCaptureDeviceInfo_Dev info = {
+ device_info.width,
+ device_info.height,
+ device_info.frame_per_second
+ };
+ ReleaseBuffers();
+
+ // Allocate buffers. We keep a reference to them, that is released in
+ // ReleaseBuffers.
+ // YUV 4:2:0
+ int uv_width = info.width / 2;
+ int uv_height = info.height / 2;
+ size_t size = info.width * info.height + 2 * uv_width * uv_height;
+ scoped_array<PP_Resource> resources(new PP_Resource[buffer_count_hint_]);
+
+ buffers_.reserve(buffer_count_hint_);
+ for (size_t i = 0; i < buffer_count_hint_; ++i) {
+ resources[i] = PPB_Buffer_Impl::Create(instance(), size);
+ if (!resources[i])
+ break;
+
+ EnterResourceNoLock<PPB_Buffer_API> enter(resources[i], true);
+ DCHECK(enter.succeeded());
+
+ BufferInfo info;
+ info.buffer = static_cast<PPB_Buffer_Impl*>(enter.object());
+ info.data = info.buffer->Map();
+ if (!info.data) {
+ ResourceTracker::Get()->UnrefResource(resources[i]);
+ break;
+ }
+ buffers_.push_back(info);
+ }
+
+ if (buffers_.empty()) {
+ // We couldn't allocate/map buffers at all. Send an error and stop the
+ // capture.
+ ppp_videocapture_->OnError(instance()->pp_instance(),
+ ScopedResourceId(this).id,
+ PP_ERROR_NOMEMORY);
+ status_ = PP_VIDEO_CAPTURE_STATUS_STOPPING;
+ platform_video_capture_->StopCapture(this);
+ return;
+ }
+
+ ppp_videocapture_->OnDeviceInfo(instance()->pp_instance(),
+ ScopedResourceId(this).id,
+ &info,
+ buffers_.size(),
+ resources.get());
+}
+
+void PPB_VideoCapture_Impl::ReleaseBuffers() {
+ ResourceTracker *tracker = ResourceTracker::Get();
+ for (size_t i = 0; i < buffers_.size(); ++i) {
+ buffers_[i].buffer->Unmap();
+ tracker->UnrefResource(buffers_[i].buffer->GetReferenceNoAddRef());
+ }
+ buffers_.clear();
+}
+
+void PPB_VideoCapture_Impl::SendStatus() {
+ ppp_videocapture_->OnStatus(instance()->pp_instance(),
+ ScopedResourceId(this).id,
+ status_);
+}
+
+PPB_VideoCapture_Impl::BufferInfo::BufferInfo()
+ : in_use(false),
+ data(NULL),
+ buffer() {
+}
+
+PPB_VideoCapture_Impl::BufferInfo::~BufferInfo() {
+}
+
+} // namespace ppapi
+} // namespace webkit
« no previous file with comments | « webkit/plugins/ppapi/ppb_video_capture_impl.h ('k') | webkit/plugins/ppapi/resource_creation_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698