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

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: 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 status_(PP_VIDEO_CAPTURE_STATUS_STOPPED) {
33 ppp_videocapture_ =
brettw 2011/08/02 17:17:44 I'd initialize this to null in the initializer lis
piman 2011/08/03 00:44:41 Done.
34 static_cast<const PPP_VideoCapture_Dev*>(instance->module()->
35 GetPluginInterface(PPP_VIDEO_CAPTURE_DEV_INTERFACE));
36 }
37
38 PPB_VideoCapture_Impl::~PPB_VideoCapture_Impl() {
39 if (platform_video_capture_.get())
40 StopCapture();
41 }
42
43 bool PPB_VideoCapture_Impl::Init() {
44 platform_video_capture_.reset(
45 instance()->delegate()->CreateVideoCapture(this));
46 return ppp_videocapture_ && platform_video_capture_.get();
47 }
48
49 PPB_VideoCapture_API* PPB_VideoCapture_Impl::AsPPB_VideoCapture_API() {
50 return this;
51 }
52
53 int32_t PPB_VideoCapture_Impl::StartCapture(
54 const PP_VideoCaptureDeviceInfo_Dev& requested_info,
55 uint32_t buffer_count) {
56 switch (status_) {
57 case PP_VIDEO_CAPTURE_STATUS_STARTING:
58 case PP_VIDEO_CAPTURE_STATUS_STARTED:
59 case PP_VIDEO_CAPTURE_STATUS_PAUSED:
60 default:
61 return PP_ERROR_FAILED;
62 case PP_VIDEO_CAPTURE_STATUS_STOPPED:
63 case PP_VIDEO_CAPTURE_STATUS_STOPPING:
64 break;
65 }
66 DCHECK(buffers_.empty());
67
68 buffer_count_hint_ = std::min(buffer_count, 1U);
69 media::VideoCapture::VideoCaptureCapability capability = {
70 requested_info.width,
71 requested_info.height,
72 requested_info.frames_per_second,
73 0, // ignored.
74 media::VideoFrame::I420,
75 false, // ignored
76 false // resolution_fixed
77 };
78 status_ = PP_VIDEO_CAPTURE_STATUS_STARTING;
79 platform_video_capture_->StartCapture(this, capability);
80 return PP_OK;
81 }
82
83 int32_t PPB_VideoCapture_Impl::ReuseBuffer(uint32_t buffer) {
84 if (buffer >= buffers_.size() || !buffers_[buffer].in_use)
85 return PP_ERROR_BADARGUMENT;
86 buffers_[buffer].in_use = false;
87 return PP_OK;
88 }
89
90 int32_t PPB_VideoCapture_Impl::StopCapture() {
91 switch (status_) {
92 case PP_VIDEO_CAPTURE_STATUS_STOPPED:
93 case PP_VIDEO_CAPTURE_STATUS_STOPPING:
94 default:
95 return PP_ERROR_FAILED;
wjia(left Chromium) 2011/08/02 16:22:28 Is this a fatal error, or just warning? It might b
piman 2011/08/03 00:44:41 It's essentially silent, except if the plugin look
96 case PP_VIDEO_CAPTURE_STATUS_STARTING:
97 case PP_VIDEO_CAPTURE_STATUS_STARTED:
98 case PP_VIDEO_CAPTURE_STATUS_PAUSED:
99 break;
100 }
101 FreeBuffers();
102 status_ = PP_VIDEO_CAPTURE_STATUS_STOPPING;
103 platform_video_capture_->StopCapture(this);
104 return PP_OK;
105 }
106
107 void PPB_VideoCapture_Impl::OnStarted(media::VideoCapture* capture) {
108 switch (status_) {
109 case PP_VIDEO_CAPTURE_STATUS_STARTING:
110 case PP_VIDEO_CAPTURE_STATUS_PAUSED:
111 break;
112 case PP_VIDEO_CAPTURE_STATUS_STOPPED:
113 case PP_VIDEO_CAPTURE_STATUS_STOPPING:
114 case PP_VIDEO_CAPTURE_STATUS_STARTED:
115 default:
116 return;
117 }
118 status_ = PP_VIDEO_CAPTURE_STATUS_STARTED;
119 SendStatus();
120 }
121
122 void PPB_VideoCapture_Impl::OnStopped(media::VideoCapture* capture) {
123 switch (status_) {
124 case PP_VIDEO_CAPTURE_STATUS_STOPPING:
125 break;
126 case PP_VIDEO_CAPTURE_STATUS_STARTING:
127 case PP_VIDEO_CAPTURE_STATUS_PAUSED:
128 case PP_VIDEO_CAPTURE_STATUS_STOPPED:
129 case PP_VIDEO_CAPTURE_STATUS_STARTED:
130 default:
131 return;
132 }
133 status_ = PP_VIDEO_CAPTURE_STATUS_STOPPED;
134 SendStatus();
135 }
136
137 void PPB_VideoCapture_Impl::OnPaused(media::VideoCapture* capture) {
138 switch (status_) {
139 case PP_VIDEO_CAPTURE_STATUS_STARTING:
140 case PP_VIDEO_CAPTURE_STATUS_STARTED:
141 break;
142 case PP_VIDEO_CAPTURE_STATUS_STOPPED:
143 case PP_VIDEO_CAPTURE_STATUS_STOPPING:
144 case PP_VIDEO_CAPTURE_STATUS_PAUSED:
145 default:
146 return;
147 }
148 status_ = PP_VIDEO_CAPTURE_STATUS_PAUSED;
149 SendStatus();
150 }
151
152 void PPB_VideoCapture_Impl::OnError(media::VideoCapture* capture,
153 int error_code) {
154 // Today, the media layer only sends "1" as an error.
155 DCHECK(error_code == 1);
156 // It either comes because some error was detected while starting (e.g. 2
157 // conflicting "master" resolution), or because the browser failed to start
158 // the capture.
159 status_ = PP_VIDEO_CAPTURE_STATUS_STOPPED;
160 ppp_videocapture_->OnError(instance()->pp_instance(),
161 ScopedResourceId(this).id,
162 PP_ERROR_FAILED);
163 }
164
165 void PPB_VideoCapture_Impl::OnBufferReady(
166 media::VideoCapture* capture,
wjia(left Chromium) 2011/08/02 16:22:28 This |capture| looks like an alien since PPB_Video
piman 2011/08/03 00:44:41 So, I was kinda wondering about that, but decided
167 scoped_refptr<media::VideoCapture::VideoFrameBuffer> buffer) {
wjia(left Chromium) 2011/08/02 16:22:28 it would be good to check buffer (not a NULL point
piman 2011/08/03 00:44:41 Is there a reason the VideoCaptureImpl would send
wjia(left Chromium) 2011/08/03 02:40:00 I meant DCHECK which has been added.
168 if (!buffers_.empty()) {
169 for (uint32_t i = 0; i < buffers_.size(); ++i) {
170 if (!buffers_[i].in_use) {
171 // TODO(piman): it looks like stride isn't actually used/filled.
172 DCHECK(buffer->stride == 0);
173 size_t size = std::min(buffers_[i].buffer->size(), buffer->buffer_size);
174 memcpy(buffers_[i].data, buffer->memory_pointer, size);
wjia(left Chromium) 2011/08/02 16:22:28 would it be good to call "platform_video_capture_-
piman 2011/08/03 00:44:41 Done.
175 ppp_videocapture_->OnBufferReady(instance()->pp_instance(),
176 ScopedResourceId(this).id,
177 i);
178 break;
179 }
180 }
181 }
182 // TODO(piman): signal dropped buffers ?
183 platform_video_capture_->FeedBuffer(buffer);
184 }
185
186 void PPB_VideoCapture_Impl::OnDeviceInfoReceived(
187 media::VideoCapture* capture,
188 const media::VideoCaptureParams& device_info) {
189 PP_VideoCaptureDeviceInfo_Dev info = {
190 device_info.width,
191 device_info.height,
192 device_info.frame_per_second
193 };
194 FreeBuffers();
wjia(left Chromium) 2011/08/02 16:22:28 is it guaranteed that no buffer is in use by plugi
piman 2011/08/03 00:44:41 The plugin is responsible for keeping its own refe
195
196 // Allocate buffers. We keep a reference to them, that is released in
197 // FreeBuffers.
198 // YUV 4:2:0
199 int uv_width = info.width / 2;
200 int uv_height = info.height / 2;
201 size_t size = info.width * info.height + 2 * uv_width * uv_height;
202 scoped_array<PP_Resource> resources(new PP_Resource[buffer_count_hint_]);
203
204 buffers_.reserve(buffer_count_hint_);
205 for (size_t i = 0; i < buffer_count_hint_; ++i) {
206 resources[i] = PPB_Buffer_Impl::Create(instance(), size);
207 if (!resources[i]) {
208 break;
209 }
210
211 EnterResourceNoLock<PPB_Buffer_API> enter(resources[i], true);
212 DCHECK(enter.succeeded());
213
214 BufferInfo info;
215 info.buffer = static_cast<PPB_Buffer_Impl*>(enter.object());
216 info.data = info.buffer->Map();
217 if (!info.data) {
218 ResourceTracker::Get()->UnrefResource(resources[i]);
219 break;
220 }
221 buffers_.push_back(info);
222 }
223
224 if (buffers_.empty()) {
225 // We couldn't allocate/map buffers at all. Send an error and stop the
226 // capture.
227 ppp_videocapture_->OnError(instance()->pp_instance(),
228 ScopedResourceId(this).id,
229 PP_ERROR_NOMEMORY);
230 status_ = PP_VIDEO_CAPTURE_STATUS_STOPPING;
231 platform_video_capture_->StopCapture(this);
232 return;
233 }
234
235 ppp_videocapture_->OnDeviceInfo(instance()->pp_instance(),
236 ScopedResourceId(this).id,
237 &info,
238 buffers_.size(),
239 resources.get());
240 }
241
242 void PPB_VideoCapture_Impl::FreeBuffers() {
243 ResourceTracker *tracker = ResourceTracker::Get();
244 for (size_t i = 0; i < buffers_.size(); ++i) {
245 buffers_[i].buffer->Unmap();
246 tracker->UnrefResource(buffers_[i].buffer->GetReferenceNoAddRef());
247 }
248 buffers_.clear();
249 }
250
251 void PPB_VideoCapture_Impl::SendStatus() {
252 ppp_videocapture_->OnStatus(instance()->pp_instance(),
253 ScopedResourceId(this).id,
254 status_);
255 }
256
257 } // namespace ppapi
258 } // namespace webkit
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698