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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "webkit/plugins/ppapi/ppb_video_capture_impl.h"
6
7 #include <algorithm>
8 #include <string>
9
10 #include "base/logging.h"
11 #include "ppapi/c/dev/pp_video_capture_dev.h"
12 #include "ppapi/c/dev/ppb_video_capture_dev.h"
13 #include "ppapi/c/pp_completion_callback.h"
14 #include "ppapi/c/pp_errors.h"
15 #include "ppapi/thunk/enter.h"
16 #include "webkit/plugins/ppapi/common.h"
17 #include "webkit/plugins/ppapi/plugin_module.h"
18 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
19 #include "webkit/plugins/ppapi/ppb_buffer_impl.h"
20 #include "webkit/plugins/ppapi/resource_tracker.h"
21
22 using ppapi::thunk::EnterResourceNoLock;
23 using ppapi::thunk::PPB_Buffer_API;
24 using ppapi::thunk::PPB_VideoCapture_API;
25
26 namespace webkit {
27 namespace ppapi {
28
29 PPB_VideoCapture_Impl::PPB_VideoCapture_Impl(PluginInstance* instance)
30 : Resource(instance),
31 buffer_count_hint_(0),
32 ppp_videocapture_(NULL),
33 status_(PP_VIDEO_CAPTURE_STATUS_STOPPED) {
34 }
35
36 PPB_VideoCapture_Impl::~PPB_VideoCapture_Impl() {
37 if (platform_video_capture_.get())
38 StopCapture();
39 }
40
41 bool PPB_VideoCapture_Impl::Init() {
42 ppp_videocapture_ =
43 static_cast<const PPP_VideoCapture_Dev*>(instance()->module()->
44 GetPluginInterface(PPP_VIDEO_CAPTURE_DEV_INTERFACE));
45 if (!ppp_videocapture_)
46 return false;
47
48 platform_video_capture_.reset(
49 instance()->delegate()->CreateVideoCapture(this));
50 return !!platform_video_capture_.get();
51 }
52
53 PPB_VideoCapture_API* PPB_VideoCapture_Impl::AsPPB_VideoCapture_API() {
54 return this;
55 }
56
57 int32_t PPB_VideoCapture_Impl::StartCapture(
58 const PP_VideoCaptureDeviceInfo_Dev& requested_info,
59 uint32_t buffer_count) {
60 switch (status_) {
61 case PP_VIDEO_CAPTURE_STATUS_STARTING:
62 case PP_VIDEO_CAPTURE_STATUS_STARTED:
63 case PP_VIDEO_CAPTURE_STATUS_PAUSED:
64 default:
65 return PP_ERROR_FAILED;
66 case PP_VIDEO_CAPTURE_STATUS_STOPPED:
67 case PP_VIDEO_CAPTURE_STATUS_STOPPING:
68 break;
69 }
70 DCHECK(buffers_.empty());
71
72 buffer_count_hint_ = std::min(buffer_count, 1U);
73 media::VideoCapture::VideoCaptureCapability capability = {
74 requested_info.width,
75 requested_info.height,
76 requested_info.frames_per_second,
77 0, // ignored.
78 media::VideoFrame::I420,
79 false, // ignored
80 false // resolution_fixed
81 };
82 status_ = PP_VIDEO_CAPTURE_STATUS_STARTING;
83 platform_video_capture_->StartCapture(this, capability);
84 return PP_OK;
85 }
86
87 int32_t PPB_VideoCapture_Impl::ReuseBuffer(uint32_t buffer) {
88 if (buffer >= buffers_.size() || !buffers_[buffer].in_use)
89 return PP_ERROR_BADARGUMENT;
90 buffers_[buffer].in_use = false;
91 return PP_OK;
92 }
93
94 int32_t PPB_VideoCapture_Impl::StopCapture() {
95 switch (status_) {
96 case PP_VIDEO_CAPTURE_STATUS_STOPPED:
97 case PP_VIDEO_CAPTURE_STATUS_STOPPING:
98 default:
99 return PP_ERROR_FAILED;
100 case PP_VIDEO_CAPTURE_STATUS_STARTING:
101 case PP_VIDEO_CAPTURE_STATUS_STARTED:
102 case PP_VIDEO_CAPTURE_STATUS_PAUSED:
103 break;
104 }
105 ReleaseBuffers();
106 status_ = PP_VIDEO_CAPTURE_STATUS_STOPPING;
107 platform_video_capture_->StopCapture(this);
108 return PP_OK;
109 }
110
111 void PPB_VideoCapture_Impl::OnStarted(media::VideoCapture* capture) {
112 switch (status_) {
113 case PP_VIDEO_CAPTURE_STATUS_STARTING:
114 case PP_VIDEO_CAPTURE_STATUS_PAUSED:
115 break;
116 case PP_VIDEO_CAPTURE_STATUS_STOPPED:
117 case PP_VIDEO_CAPTURE_STATUS_STOPPING:
118 case PP_VIDEO_CAPTURE_STATUS_STARTED:
119 default:
120 return;
121 }
122 status_ = PP_VIDEO_CAPTURE_STATUS_STARTED;
123 SendStatus();
124 }
125
126 void PPB_VideoCapture_Impl::OnStopped(media::VideoCapture* capture) {
127 switch (status_) {
128 case PP_VIDEO_CAPTURE_STATUS_STOPPING:
129 break;
130 case PP_VIDEO_CAPTURE_STATUS_STARTING:
131 case PP_VIDEO_CAPTURE_STATUS_PAUSED:
132 case PP_VIDEO_CAPTURE_STATUS_STOPPED:
133 case PP_VIDEO_CAPTURE_STATUS_STARTED:
134 default:
135 return;
136 }
137 status_ = PP_VIDEO_CAPTURE_STATUS_STOPPED;
138 SendStatus();
139 }
140
141 void PPB_VideoCapture_Impl::OnPaused(media::VideoCapture* capture) {
142 switch (status_) {
143 case PP_VIDEO_CAPTURE_STATUS_STARTING:
144 case PP_VIDEO_CAPTURE_STATUS_STARTED:
145 break;
146 case PP_VIDEO_CAPTURE_STATUS_STOPPED:
147 case PP_VIDEO_CAPTURE_STATUS_STOPPING:
148 case PP_VIDEO_CAPTURE_STATUS_PAUSED:
149 default:
150 return;
151 }
152 status_ = PP_VIDEO_CAPTURE_STATUS_PAUSED;
153 SendStatus();
154 }
155
156 void PPB_VideoCapture_Impl::OnError(media::VideoCapture* capture,
157 int error_code) {
158 // Today, the media layer only sends "1" as an error.
159 DCHECK(error_code == 1);
160 // It either comes because some error was detected while starting (e.g. 2
161 // conflicting "master" resolution), or because the browser failed to start
162 // the capture.
163 status_ = PP_VIDEO_CAPTURE_STATUS_STOPPED;
164 ppp_videocapture_->OnError(instance()->pp_instance(),
165 ScopedResourceId(this).id,
166 PP_ERROR_FAILED);
167 }
168
169 void PPB_VideoCapture_Impl::OnBufferReady(
170 media::VideoCapture* capture,
171 scoped_refptr<media::VideoCapture::VideoFrameBuffer> buffer) {
172 DCHECK(buffer.get());
173 for (uint32_t i = 0; i < buffers_.size(); ++i) {
174 if (!buffers_[i].in_use) {
175 // TODO(piman): it looks like stride isn't actually used/filled.
176 DCHECK(buffer->stride == 0);
177 size_t size = std::min(static_cast<size_t>(buffers_[i].buffer->size()),
178 buffer->buffer_size);
179 memcpy(buffers_[i].data, buffer->memory_pointer, size);
180 platform_video_capture_->FeedBuffer(buffer);
181 ppp_videocapture_->OnBufferReady(instance()->pp_instance(),
182 ScopedResourceId(this).id,
183 i);
184 return;
185 }
186 }
187 // TODO(piman): signal dropped buffers ?
188 platform_video_capture_->FeedBuffer(buffer);
189 }
190
191 void PPB_VideoCapture_Impl::OnDeviceInfoReceived(
192 media::VideoCapture* capture,
193 const media::VideoCaptureParams& device_info) {
194 PP_VideoCaptureDeviceInfo_Dev info = {
195 device_info.width,
196 device_info.height,
197 device_info.frame_per_second
198 };
199 ReleaseBuffers();
200
201 // Allocate buffers. We keep a reference to them, that is released in
202 // ReleaseBuffers.
203 // YUV 4:2:0
204 int uv_width = info.width / 2;
205 int uv_height = info.height / 2;
206 size_t size = info.width * info.height + 2 * uv_width * uv_height;
207 scoped_array<PP_Resource> resources(new PP_Resource[buffer_count_hint_]);
208
209 buffers_.reserve(buffer_count_hint_);
210 for (size_t i = 0; i < buffer_count_hint_; ++i) {
211 resources[i] = PPB_Buffer_Impl::Create(instance(), size);
212 if (!resources[i])
213 break;
214
215 EnterResourceNoLock<PPB_Buffer_API> enter(resources[i], true);
216 DCHECK(enter.succeeded());
217
218 BufferInfo info;
219 info.buffer = static_cast<PPB_Buffer_Impl*>(enter.object());
220 info.data = info.buffer->Map();
221 if (!info.data) {
222 ResourceTracker::Get()->UnrefResource(resources[i]);
223 break;
224 }
225 buffers_.push_back(info);
226 }
227
228 if (buffers_.empty()) {
229 // We couldn't allocate/map buffers at all. Send an error and stop the
230 // capture.
231 ppp_videocapture_->OnError(instance()->pp_instance(),
232 ScopedResourceId(this).id,
233 PP_ERROR_NOMEMORY);
234 status_ = PP_VIDEO_CAPTURE_STATUS_STOPPING;
235 platform_video_capture_->StopCapture(this);
236 return;
237 }
238
239 ppp_videocapture_->OnDeviceInfo(instance()->pp_instance(),
240 ScopedResourceId(this).id,
241 &info,
242 buffers_.size(),
243 resources.get());
244 }
245
246 void PPB_VideoCapture_Impl::ReleaseBuffers() {
247 ResourceTracker *tracker = ResourceTracker::Get();
248 for (size_t i = 0; i < buffers_.size(); ++i) {
249 buffers_[i].buffer->Unmap();
250 tracker->UnrefResource(buffers_[i].buffer->GetReferenceNoAddRef());
251 }
252 buffers_.clear();
253 }
254
255 void PPB_VideoCapture_Impl::SendStatus() {
256 ppp_videocapture_->OnStatus(instance()->pp_instance(),
257 ScopedResourceId(this).id,
258 status_);
259 }
260
261 PPB_VideoCapture_Impl::BufferInfo::BufferInfo()
262 : in_use(false),
263 data(NULL),
264 buffer() {
265 }
266
267 PPB_VideoCapture_Impl::BufferInfo::~BufferInfo() {
268 }
269
270 } // namespace ppapi
271 } // namespace webkit
OLDNEW
« 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