OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/renderer/pepper/pepper_video_capture_host.h" | 5 #include "content/renderer/pepper/pepper_video_capture_host.h" |
6 | 6 |
7 #include "content/renderer/pepper/host_globals.h" | 7 #include "content/renderer/pepper/host_globals.h" |
8 #include "content/renderer/pepper/pepper_media_device_manager.h" | 8 #include "content/renderer/pepper/pepper_media_device_manager.h" |
9 #include "content/renderer/pepper/pepper_platform_video_capture.h" | 9 #include "content/renderer/pepper/pepper_platform_video_capture.h" |
10 #include "content/renderer/pepper/pepper_plugin_instance_impl.h" | 10 #include "content/renderer/pepper/pepper_plugin_instance_impl.h" |
(...skipping 23 matching lines...) Expand all Loading... |
34 | 34 |
35 namespace content { | 35 namespace content { |
36 | 36 |
37 PepperVideoCaptureHost::PepperVideoCaptureHost(RendererPpapiHostImpl* host, | 37 PepperVideoCaptureHost::PepperVideoCaptureHost(RendererPpapiHostImpl* host, |
38 PP_Instance instance, | 38 PP_Instance instance, |
39 PP_Resource resource) | 39 PP_Resource resource) |
40 : ResourceHost(host->GetPpapiHost(), instance, resource), | 40 : ResourceHost(host->GetPpapiHost(), instance, resource), |
41 renderer_ppapi_host_(host), | 41 renderer_ppapi_host_(host), |
42 buffer_count_hint_(0), | 42 buffer_count_hint_(0), |
43 status_(PP_VIDEO_CAPTURE_STATUS_STOPPED), | 43 status_(PP_VIDEO_CAPTURE_STATUS_STOPPED), |
44 enumeration_helper_( | 44 enumeration_helper_(this, |
45 this, | 45 PepperMediaDeviceManager::GetForRenderView( |
46 PepperMediaDeviceManager::GetForRenderView( | 46 host->GetRenderViewForInstance(pp_instance())), |
47 host->GetRenderViewForInstance(pp_instance())), | 47 PP_DEVICETYPE_DEV_VIDEOCAPTURE, |
48 PP_DEVICETYPE_DEV_VIDEOCAPTURE, | 48 host->GetDocumentURL(instance)) {} |
49 host->GetDocumentURL(instance)) { | |
50 } | |
51 | 49 |
52 PepperVideoCaptureHost::~PepperVideoCaptureHost() { | 50 PepperVideoCaptureHost::~PepperVideoCaptureHost() { Close(); } |
53 Close(); | |
54 } | |
55 | 51 |
56 bool PepperVideoCaptureHost::Init() { | 52 bool PepperVideoCaptureHost::Init() { |
57 return !!renderer_ppapi_host_->GetPluginInstance(pp_instance()); | 53 return !!renderer_ppapi_host_->GetPluginInstance(pp_instance()); |
58 } | 54 } |
59 | 55 |
60 int32_t PepperVideoCaptureHost::OnResourceMessageReceived( | 56 int32_t PepperVideoCaptureHost::OnResourceMessageReceived( |
61 const IPC::Message& msg, | 57 const IPC::Message& msg, |
62 ppapi::host::HostMessageContext* context) { | 58 ppapi::host::HostMessageContext* context) { |
63 int32_t result = PP_ERROR_FAILED; | 59 int32_t result = PP_ERROR_FAILED; |
64 if (enumeration_helper_.HandleResourceMessage(msg, context, &result)) | 60 if (enumeration_helper_.HandleResourceMessage(msg, context, &result)) |
65 return result; | 61 return result; |
66 | 62 |
67 IPC_BEGIN_MESSAGE_MAP(PepperVideoCaptureHost, msg) | 63 IPC_BEGIN_MESSAGE_MAP(PepperVideoCaptureHost, msg) |
68 PPAPI_DISPATCH_HOST_RESOURCE_CALL( | 64 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoCapture_Open, OnOpen) |
69 PpapiHostMsg_VideoCapture_Open, | 65 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoCapture_StartCapture, |
70 OnOpen) | 66 OnStartCapture) |
71 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( | 67 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoCapture_ReuseBuffer, |
72 PpapiHostMsg_VideoCapture_StartCapture, | 68 OnReuseBuffer) |
73 OnStartCapture) | 69 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoCapture_StopCapture, |
74 PPAPI_DISPATCH_HOST_RESOURCE_CALL( | 70 OnStopCapture) |
75 PpapiHostMsg_VideoCapture_ReuseBuffer, | 71 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoCapture_Close, OnClose) |
76 OnReuseBuffer) | |
77 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( | |
78 PpapiHostMsg_VideoCapture_StopCapture, | |
79 OnStopCapture) | |
80 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( | |
81 PpapiHostMsg_VideoCapture_Close, | |
82 OnClose) | |
83 IPC_END_MESSAGE_MAP() | 72 IPC_END_MESSAGE_MAP() |
84 return PP_ERROR_FAILED; | 73 return PP_ERROR_FAILED; |
85 } | 74 } |
86 | 75 |
87 void PepperVideoCaptureHost::OnInitialized(media::VideoCapture* capture, | 76 void PepperVideoCaptureHost::OnInitialized(media::VideoCapture* capture, |
88 bool succeeded) { | 77 bool succeeded) { |
89 DCHECK(capture == platform_video_capture_.get()); | 78 DCHECK(capture == platform_video_capture_.get()); |
90 | 79 |
91 if (succeeded) { | 80 if (succeeded) { |
92 open_reply_context_.params.set_result(PP_OK); | 81 open_reply_context_.params.set_result(PP_OK); |
(...skipping 26 matching lines...) Expand all Loading... |
119 // Today, the media layer only sends "1" as an error. | 108 // Today, the media layer only sends "1" as an error. |
120 DCHECK(error_code == 1); | 109 DCHECK(error_code == 1); |
121 PostErrorReply(); | 110 PostErrorReply(); |
122 } | 111 } |
123 | 112 |
124 void PepperVideoCaptureHost::PostErrorReply() { | 113 void PepperVideoCaptureHost::PostErrorReply() { |
125 // It either comes because some error was detected while starting (e.g. 2 | 114 // It either comes because some error was detected while starting (e.g. 2 |
126 // conflicting "master" resolution), or because the browser failed to start | 115 // conflicting "master" resolution), or because the browser failed to start |
127 // the capture. | 116 // the capture. |
128 SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPED, true); | 117 SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPED, true); |
129 host()->SendUnsolicitedReply(pp_resource(), | 118 host()->SendUnsolicitedReply( |
130 PpapiPluginMsg_VideoCapture_OnError(PP_ERROR_FAILED)); | 119 pp_resource(), PpapiPluginMsg_VideoCapture_OnError(PP_ERROR_FAILED)); |
131 } | 120 } |
132 | 121 |
133 void PepperVideoCaptureHost::OnRemoved(media::VideoCapture* capture) { | 122 void PepperVideoCaptureHost::OnRemoved(media::VideoCapture* capture) {} |
134 } | |
135 | 123 |
136 void PepperVideoCaptureHost::OnFrameReady( | 124 void PepperVideoCaptureHost::OnFrameReady( |
137 media::VideoCapture* capture, | 125 media::VideoCapture* capture, |
138 const scoped_refptr<media::VideoFrame>& frame) { | 126 const scoped_refptr<media::VideoFrame>& frame) { |
139 DCHECK(frame.get()); | 127 DCHECK(frame.get()); |
140 | 128 |
141 if (alloc_size_ != frame->coded_size()) { | 129 if (alloc_size_ != frame->coded_size()) { |
142 AllocBuffers(frame->coded_size(), capture->CaptureFrameRate()); | 130 AllocBuffers(frame->coded_size(), capture->CaptureFrameRate()); |
143 alloc_size_ = frame->coded_size(); | 131 alloc_size_ = frame->coded_size(); |
144 } | 132 } |
(...skipping 16 matching lines...) Expand all Loading... |
161 const uint8* src = frame->data(j); | 149 const uint8* src = frame->data(j); |
162 const size_t row_bytes = frame->row_bytes(j); | 150 const size_t row_bytes = frame->row_bytes(j); |
163 const size_t src_stride = frame->stride(j); | 151 const size_t src_stride = frame->stride(j); |
164 for (int k = 0; k < frame->rows(j); ++k) { | 152 for (int k = 0; k < frame->rows(j); ++k) { |
165 memcpy(dst, src, row_bytes); | 153 memcpy(dst, src, row_bytes); |
166 dst += row_bytes; | 154 dst += row_bytes; |
167 src += src_stride; | 155 src += src_stride; |
168 } | 156 } |
169 } | 157 } |
170 buffers_[i].in_use = true; | 158 buffers_[i].in_use = true; |
171 host()->SendUnsolicitedReply(pp_resource(), | 159 host()->SendUnsolicitedReply( |
172 PpapiPluginMsg_VideoCapture_OnBufferReady(i)); | 160 pp_resource(), PpapiPluginMsg_VideoCapture_OnBufferReady(i)); |
173 return; | 161 return; |
174 } | 162 } |
175 } | 163 } |
176 } | 164 } |
177 | 165 |
178 void PepperVideoCaptureHost::AllocBuffers( | 166 void PepperVideoCaptureHost::AllocBuffers(const gfx::Size& resolution, |
179 const gfx::Size& resolution, | 167 int frame_rate) { |
180 int frame_rate) { | |
181 PP_VideoCaptureDeviceInfo_Dev info = { | 168 PP_VideoCaptureDeviceInfo_Dev info = { |
182 static_cast<uint32_t>(resolution.width()), | 169 static_cast<uint32_t>(resolution.width()), |
183 static_cast<uint32_t>(resolution.height()), | 170 static_cast<uint32_t>(resolution.height()), |
184 static_cast<uint32_t>(frame_rate) | 171 static_cast<uint32_t>(frame_rate)}; |
185 }; | |
186 ReleaseBuffers(); | 172 ReleaseBuffers(); |
187 | 173 |
188 const size_t size = media::VideoFrame::AllocationSize( | 174 const size_t size = media::VideoFrame::AllocationSize( |
189 media::VideoFrame::I420, gfx::Size(info.width, info.height)); | 175 media::VideoFrame::I420, gfx::Size(info.width, info.height)); |
190 | 176 |
191 ppapi::proxy::ResourceMessageReplyParams params(pp_resource(), 0); | 177 ppapi::proxy::ResourceMessageReplyParams params(pp_resource(), 0); |
192 | 178 |
193 // Allocate buffers. We keep a reference to them, that is released in | 179 // Allocate buffers. We keep a reference to them, that is released in |
194 // ReleaseBuffers. In the mean time, we prepare the resource and handle here | 180 // ReleaseBuffers. In the mean time, we prepare the resource and handle here |
195 // for sending below. | 181 // for sending below. |
196 std::vector<HostResource> buffer_host_resources; | 182 std::vector<HostResource> buffer_host_resources; |
197 buffers_.reserve(buffer_count_hint_); | 183 buffers_.reserve(buffer_count_hint_); |
198 ppapi::ResourceTracker* tracker = | 184 ppapi::ResourceTracker* tracker = HostGlobals::Get()->GetResourceTracker(); |
199 HostGlobals::Get()->GetResourceTracker(); | |
200 ppapi::proxy::HostDispatcher* dispatcher = | 185 ppapi::proxy::HostDispatcher* dispatcher = |
201 ppapi::proxy::HostDispatcher::GetForInstance(pp_instance()); | 186 ppapi::proxy::HostDispatcher::GetForInstance(pp_instance()); |
202 for (size_t i = 0; i < buffer_count_hint_; ++i) { | 187 for (size_t i = 0; i < buffer_count_hint_; ++i) { |
203 PP_Resource res = PPB_Buffer_Impl::Create(pp_instance(), size); | 188 PP_Resource res = PPB_Buffer_Impl::Create(pp_instance(), size); |
204 if (!res) | 189 if (!res) |
205 break; | 190 break; |
206 | 191 |
207 EnterResourceNoLock<PPB_Buffer_API> enter(res, true); | 192 EnterResourceNoLock<PPB_Buffer_API> enter(res, true); |
208 DCHECK(enter.succeeded()); | 193 DCHECK(enter.succeeded()); |
209 | 194 |
(...skipping 27 matching lines...) Expand all Loading... |
237 // TODO(piman/brettw): Change trusted interface to return a PP_FileHandle, | 222 // TODO(piman/brettw): Change trusted interface to return a PP_FileHandle, |
238 // those casts are ugly. | 223 // those casts are ugly. |
239 base::PlatformFile platform_file = | 224 base::PlatformFile platform_file = |
240 #if defined(OS_WIN) | 225 #if defined(OS_WIN) |
241 reinterpret_cast<HANDLE>(static_cast<intptr_t>(handle)); | 226 reinterpret_cast<HANDLE>(static_cast<intptr_t>(handle)); |
242 #elif defined(OS_POSIX) | 227 #elif defined(OS_POSIX) |
243 handle; | 228 handle; |
244 #else | 229 #else |
245 #error Not implemented. | 230 #error Not implemented. |
246 #endif | 231 #endif |
247 params.AppendHandle( | 232 params.AppendHandle(ppapi::proxy::SerializedHandle( |
248 ppapi::proxy::SerializedHandle( | 233 dispatcher->ShareHandleWithRemote(platform_file, false), size)); |
249 dispatcher->ShareHandleWithRemote(platform_file, false), | |
250 size)); | |
251 } | 234 } |
252 } | 235 } |
253 | 236 |
254 if (buffers_.empty()) { | 237 if (buffers_.empty()) { |
255 // We couldn't allocate/map buffers at all. Send an error and stop the | 238 // We couldn't allocate/map buffers at all. Send an error and stop the |
256 // capture. | 239 // capture. |
257 SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPING, true); | 240 SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPING, true); |
258 platform_video_capture_->StopCapture(this); | 241 platform_video_capture_->StopCapture(this); |
259 PostErrorReply(); | 242 PostErrorReply(); |
260 return; | 243 return; |
261 } | 244 } |
262 | 245 |
263 host()->Send(new PpapiPluginMsg_ResourceReply( | 246 host()->Send( |
264 params, PpapiPluginMsg_VideoCapture_OnDeviceInfo( | 247 new PpapiPluginMsg_ResourceReply(params, |
265 info, buffer_host_resources, size))); | 248 PpapiPluginMsg_VideoCapture_OnDeviceInfo( |
| 249 info, buffer_host_resources, size))); |
266 } | 250 } |
267 | 251 |
268 int32_t PepperVideoCaptureHost::OnOpen( | 252 int32_t PepperVideoCaptureHost::OnOpen( |
269 ppapi::host::HostMessageContext* context, | 253 ppapi::host::HostMessageContext* context, |
270 const std::string& device_id, | 254 const std::string& device_id, |
271 const PP_VideoCaptureDeviceInfo_Dev& requested_info, | 255 const PP_VideoCaptureDeviceInfo_Dev& requested_info, |
272 uint32_t buffer_count) { | 256 uint32_t buffer_count) { |
273 if (platform_video_capture_.get()) | 257 if (platform_video_capture_.get()) |
274 return PP_ERROR_FAILED; | 258 return PP_ERROR_FAILED; |
275 | 259 |
276 SetRequestedInfo(requested_info, buffer_count); | 260 SetRequestedInfo(requested_info, buffer_count); |
277 | 261 |
278 GURL document_url = renderer_ppapi_host_->GetDocumentURL(pp_instance()); | 262 GURL document_url = renderer_ppapi_host_->GetDocumentURL(pp_instance()); |
279 if (!document_url.is_valid()) | 263 if (!document_url.is_valid()) |
280 return PP_ERROR_FAILED; | 264 return PP_ERROR_FAILED; |
281 | 265 |
282 RenderViewImpl* render_view = static_cast<RenderViewImpl*>( | 266 RenderViewImpl* render_view = static_cast<RenderViewImpl*>( |
283 renderer_ppapi_host_->GetRenderViewForInstance(pp_instance())); | 267 renderer_ppapi_host_->GetRenderViewForInstance(pp_instance())); |
284 | 268 |
285 platform_video_capture_ = new PepperPlatformVideoCapture( | 269 platform_video_capture_ = new PepperPlatformVideoCapture( |
286 render_view->AsWeakPtr(), device_id, | 270 render_view->AsWeakPtr(), device_id, document_url, this); |
287 document_url, this); | |
288 | 271 |
289 open_reply_context_ = context->MakeReplyMessageContext(); | 272 open_reply_context_ = context->MakeReplyMessageContext(); |
290 | 273 |
291 return PP_OK_COMPLETIONPENDING; | 274 return PP_OK_COMPLETIONPENDING; |
292 } | 275 } |
293 | 276 |
294 int32_t PepperVideoCaptureHost::OnStartCapture( | 277 int32_t PepperVideoCaptureHost::OnStartCapture( |
295 ppapi::host::HostMessageContext* context) { | 278 ppapi::host::HostMessageContext* context) { |
296 if (!SetStatus(PP_VIDEO_CAPTURE_STATUS_STARTING, false) || | 279 if (!SetStatus(PP_VIDEO_CAPTURE_STATUS_STARTING, false) || |
297 !platform_video_capture_.get()) | 280 !platform_video_capture_.get()) |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 ppapi::ResourceTracker* tracker = HostGlobals::Get()->GetResourceTracker(); | 334 ppapi::ResourceTracker* tracker = HostGlobals::Get()->GetResourceTracker(); |
352 for (size_t i = 0; i < buffers_.size(); ++i) { | 335 for (size_t i = 0; i < buffers_.size(); ++i) { |
353 buffers_[i].buffer->Unmap(); | 336 buffers_[i].buffer->Unmap(); |
354 tracker->ReleaseResource(buffers_[i].buffer->pp_resource()); | 337 tracker->ReleaseResource(buffers_[i].buffer->pp_resource()); |
355 } | 338 } |
356 buffers_.clear(); | 339 buffers_.clear(); |
357 } | 340 } |
358 | 341 |
359 void PepperVideoCaptureHost::SendStatus() { | 342 void PepperVideoCaptureHost::SendStatus() { |
360 host()->SendUnsolicitedReply(pp_resource(), | 343 host()->SendUnsolicitedReply(pp_resource(), |
361 PpapiPluginMsg_VideoCapture_OnStatus(status_)); | 344 PpapiPluginMsg_VideoCapture_OnStatus(status_)); |
362 } | 345 } |
363 | 346 |
364 void PepperVideoCaptureHost::SetRequestedInfo( | 347 void PepperVideoCaptureHost::SetRequestedInfo( |
365 const PP_VideoCaptureDeviceInfo_Dev& device_info, | 348 const PP_VideoCaptureDeviceInfo_Dev& device_info, |
366 uint32_t buffer_count) { | 349 uint32_t buffer_count) { |
367 // Clamp the buffer count to between 1 and |kMaxBuffers|. | 350 // Clamp the buffer count to between 1 and |kMaxBuffers|. |
368 buffer_count_hint_ = std::min(std::max(buffer_count, 1U), kMaxBuffers); | 351 buffer_count_hint_ = std::min(std::max(buffer_count, 1U), kMaxBuffers); |
369 // Clamp the frame rate to between 1 and |kMaxFramesPerSecond - 1|. | 352 // Clamp the frame rate to between 1 and |kMaxFramesPerSecond - 1|. |
370 int frames_per_second = | 353 int frames_per_second = |
371 std::min(std::max(device_info.frames_per_second, 1U), | 354 std::min(std::max(device_info.frames_per_second, 1U), |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 } | 409 } |
427 break; | 410 break; |
428 } | 411 } |
429 } | 412 } |
430 | 413 |
431 status_ = status; | 414 status_ = status; |
432 return true; | 415 return true; |
433 } | 416 } |
434 | 417 |
435 PepperVideoCaptureHost::BufferInfo::BufferInfo() | 418 PepperVideoCaptureHost::BufferInfo::BufferInfo() |
436 : in_use(false), | 419 : in_use(false), data(NULL), buffer() {} |
437 data(NULL), | |
438 buffer() { | |
439 } | |
440 | 420 |
441 PepperVideoCaptureHost::BufferInfo::~BufferInfo() { | 421 PepperVideoCaptureHost::BufferInfo::~BufferInfo() {} |
442 } | |
443 | 422 |
444 } // namespace content | 423 } // namespace content |
OLD | NEW |