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 27 matching lines...) Expand all Loading... |
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_(this, | 44 enumeration_helper_(this, |
45 PepperMediaDeviceManager::GetForRenderView( | 45 PepperMediaDeviceManager::GetForRenderView( |
46 host->GetRenderViewForInstance(pp_instance())), | 46 host->GetRenderViewForInstance(pp_instance())), |
47 PP_DEVICETYPE_DEV_VIDEOCAPTURE, | 47 PP_DEVICETYPE_DEV_VIDEOCAPTURE, |
48 host->GetDocumentURL(instance)) { | 48 host->GetDocumentURL(instance)) {} |
49 } | |
50 | 49 |
51 PepperVideoCaptureHost::~PepperVideoCaptureHost() { | 50 PepperVideoCaptureHost::~PepperVideoCaptureHost() { Close(); } |
52 Close(); | |
53 } | |
54 | 51 |
55 bool PepperVideoCaptureHost::Init() { | 52 bool PepperVideoCaptureHost::Init() { |
56 return !!renderer_ppapi_host_->GetPluginInstance(pp_instance()); | 53 return !!renderer_ppapi_host_->GetPluginInstance(pp_instance()); |
57 } | 54 } |
58 | 55 |
59 int32_t PepperVideoCaptureHost::OnResourceMessageReceived( | 56 int32_t PepperVideoCaptureHost::OnResourceMessageReceived( |
60 const IPC::Message& msg, | 57 const IPC::Message& msg, |
61 ppapi::host::HostMessageContext* context) { | 58 ppapi::host::HostMessageContext* context) { |
62 int32_t result = PP_ERROR_FAILED; | 59 int32_t result = PP_ERROR_FAILED; |
63 if (enumeration_helper_.HandleResourceMessage(msg, context, &result)) | 60 if (enumeration_helper_.HandleResourceMessage(msg, context, &result)) |
64 return result; | 61 return result; |
65 | 62 |
66 IPC_BEGIN_MESSAGE_MAP(PepperVideoCaptureHost, msg) | 63 IPC_BEGIN_MESSAGE_MAP(PepperVideoCaptureHost, msg) |
67 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoCapture_Open, OnOpen) | 64 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoCapture_Open, OnOpen) |
68 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoCapture_StartCapture, | 65 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoCapture_StartCapture, |
69 OnStartCapture) | 66 OnStartCapture) |
70 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoCapture_ReuseBuffer, | 67 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoCapture_ReuseBuffer, |
71 OnReuseBuffer) | 68 OnReuseBuffer) |
72 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoCapture_StopCapture, | 69 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoCapture_StopCapture, |
73 OnStopCapture) | 70 OnStopCapture) |
74 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoCapture_Close, OnClose) | 71 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoCapture_Close, OnClose) |
75 IPC_END_MESSAGE_MAP() | 72 IPC_END_MESSAGE_MAP() |
76 return PP_ERROR_FAILED; | 73 return PP_ERROR_FAILED; |
77 } | 74 } |
78 | 75 |
79 void PepperVideoCaptureHost::OnInitialized(bool succeeded) { | 76 void PepperVideoCaptureHost::OnInitialized(media::VideoCapture* capture, |
| 77 bool succeeded) { |
| 78 DCHECK(capture == platform_video_capture_.get()); |
| 79 |
80 if (succeeded) { | 80 if (succeeded) { |
81 open_reply_context_.params.set_result(PP_OK); | 81 open_reply_context_.params.set_result(PP_OK); |
82 } else { | 82 } else { |
83 DetachPlatformVideoCapture(); | 83 DetachPlatformVideoCapture(); |
84 open_reply_context_.params.set_result(PP_ERROR_FAILED); | 84 open_reply_context_.params.set_result(PP_ERROR_FAILED); |
85 } | 85 } |
86 | 86 |
87 host()->SendReply(open_reply_context_, | 87 host()->SendReply(open_reply_context_, |
88 PpapiPluginMsg_VideoCapture_OpenReply()); | 88 PpapiPluginMsg_VideoCapture_OpenReply()); |
89 } | 89 } |
90 | 90 |
91 void PepperVideoCaptureHost::OnStarted() { | 91 void PepperVideoCaptureHost::OnStarted(media::VideoCapture* capture) { |
92 if (SetStatus(PP_VIDEO_CAPTURE_STATUS_STARTED, false)) | 92 if (SetStatus(PP_VIDEO_CAPTURE_STATUS_STARTED, false)) |
93 SendStatus(); | 93 SendStatus(); |
94 } | 94 } |
95 | 95 |
96 void PepperVideoCaptureHost::OnStopped() { | 96 void PepperVideoCaptureHost::OnStopped(media::VideoCapture* capture) { |
97 if (SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPED, false)) | 97 if (SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPED, false)) |
98 SendStatus(); | 98 SendStatus(); |
99 } | 99 } |
100 | 100 |
101 void PepperVideoCaptureHost::OnPaused() { | 101 void PepperVideoCaptureHost::OnPaused(media::VideoCapture* capture) { |
102 if (SetStatus(PP_VIDEO_CAPTURE_STATUS_PAUSED, false)) | 102 if (SetStatus(PP_VIDEO_CAPTURE_STATUS_PAUSED, false)) |
103 SendStatus(); | 103 SendStatus(); |
104 } | 104 } |
105 | 105 |
106 void PepperVideoCaptureHost::OnError() { | 106 void PepperVideoCaptureHost::OnError(media::VideoCapture* capture, |
| 107 int error_code) { |
| 108 // Today, the media layer only sends "1" as an error. |
| 109 DCHECK(error_code == 1); |
107 PostErrorReply(); | 110 PostErrorReply(); |
108 } | 111 } |
109 | 112 |
110 void PepperVideoCaptureHost::PostErrorReply() { | 113 void PepperVideoCaptureHost::PostErrorReply() { |
111 // 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 |
112 // conflicting "master" resolution), or because the browser failed to start | 115 // conflicting "master" resolution), or because the browser failed to start |
113 // the capture. | 116 // the capture. |
114 SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPED, true); | 117 SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPED, true); |
115 host()->SendUnsolicitedReply( | 118 host()->SendUnsolicitedReply( |
116 pp_resource(), PpapiPluginMsg_VideoCapture_OnError(PP_ERROR_FAILED)); | 119 pp_resource(), PpapiPluginMsg_VideoCapture_OnError(PP_ERROR_FAILED)); |
117 } | 120 } |
118 | 121 |
| 122 void PepperVideoCaptureHost::OnRemoved(media::VideoCapture* capture) {} |
| 123 |
119 void PepperVideoCaptureHost::OnFrameReady( | 124 void PepperVideoCaptureHost::OnFrameReady( |
120 const scoped_refptr<media::VideoFrame>& frame, | 125 media::VideoCapture* capture, |
121 media::VideoCaptureFormat format) { | 126 const scoped_refptr<media::VideoFrame>& frame) { |
122 DCHECK(frame.get()); | 127 DCHECK(frame.get()); |
123 | 128 |
124 if (alloc_size_ != frame->coded_size() || buffers_.empty()) { | 129 if (alloc_size_ != frame->coded_size()) { |
125 AllocBuffers(frame->coded_size(), format.frame_rate); | 130 AllocBuffers(frame->coded_size(), capture->CaptureFrameRate()); |
126 alloc_size_ = frame->coded_size(); | 131 alloc_size_ = frame->coded_size(); |
127 } | 132 } |
128 | 133 |
129 for (uint32_t i = 0; i < buffers_.size(); ++i) { | 134 for (uint32_t i = 0; i < buffers_.size(); ++i) { |
130 if (!buffers_[i].in_use) { | 135 if (!buffers_[i].in_use) { |
131 DCHECK_EQ(frame->format(), media::VideoFrame::I420); | 136 DCHECK_EQ(frame->format(), media::VideoFrame::I420); |
132 if (buffers_[i].buffer->size() < | 137 if (buffers_[i].buffer->size() < |
133 media::VideoFrame::AllocationSize(frame->format(), | 138 media::VideoFrame::AllocationSize(frame->format(), |
134 frame->coded_size())) { | 139 frame->coded_size())) { |
135 // TODO(ihf): handle size mismatches gracefully here. | 140 // TODO(ihf): handle size mismatches gracefully here. |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 #endif | 231 #endif |
227 params.AppendHandle(ppapi::proxy::SerializedHandle( | 232 params.AppendHandle(ppapi::proxy::SerializedHandle( |
228 dispatcher->ShareHandleWithRemote(platform_file, false), size)); | 233 dispatcher->ShareHandleWithRemote(platform_file, false), size)); |
229 } | 234 } |
230 } | 235 } |
231 | 236 |
232 if (buffers_.empty()) { | 237 if (buffers_.empty()) { |
233 // 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 |
234 // capture. | 239 // capture. |
235 SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPING, true); | 240 SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPING, true); |
236 platform_video_capture_->StopCapture(); | 241 platform_video_capture_->StopCapture(this); |
237 PostErrorReply(); | 242 PostErrorReply(); |
238 return; | 243 return; |
239 } | 244 } |
240 | 245 |
241 host()->Send( | 246 host()->Send( |
242 new PpapiPluginMsg_ResourceReply(params, | 247 new PpapiPluginMsg_ResourceReply(params, |
243 PpapiPluginMsg_VideoCapture_OnDeviceInfo( | 248 PpapiPluginMsg_VideoCapture_OnDeviceInfo( |
244 info, buffer_host_resources, size))); | 249 info, buffer_host_resources, size))); |
245 } | 250 } |
246 | 251 |
247 int32_t PepperVideoCaptureHost::OnOpen( | 252 int32_t PepperVideoCaptureHost::OnOpen( |
248 ppapi::host::HostMessageContext* context, | 253 ppapi::host::HostMessageContext* context, |
249 const std::string& device_id, | 254 const std::string& device_id, |
250 const PP_VideoCaptureDeviceInfo_Dev& requested_info, | 255 const PP_VideoCaptureDeviceInfo_Dev& requested_info, |
251 uint32_t buffer_count) { | 256 uint32_t buffer_count) { |
252 if (platform_video_capture_.get()) | 257 if (platform_video_capture_.get()) |
253 return PP_ERROR_FAILED; | 258 return PP_ERROR_FAILED; |
254 | 259 |
255 SetRequestedInfo(requested_info, buffer_count); | 260 SetRequestedInfo(requested_info, buffer_count); |
256 | 261 |
257 GURL document_url = renderer_ppapi_host_->GetDocumentURL(pp_instance()); | 262 GURL document_url = renderer_ppapi_host_->GetDocumentURL(pp_instance()); |
258 if (!document_url.is_valid()) | 263 if (!document_url.is_valid()) |
259 return PP_ERROR_FAILED; | 264 return PP_ERROR_FAILED; |
260 | 265 |
261 RenderViewImpl* render_view = static_cast<RenderViewImpl*>( | 266 RenderViewImpl* render_view = static_cast<RenderViewImpl*>( |
262 renderer_ppapi_host_->GetRenderViewForInstance(pp_instance())); | 267 renderer_ppapi_host_->GetRenderViewForInstance(pp_instance())); |
263 | 268 |
264 platform_video_capture_.reset(new PepperPlatformVideoCapture( | 269 platform_video_capture_ = new PepperPlatformVideoCapture( |
265 render_view->AsWeakPtr(), device_id, document_url, this)); | 270 render_view->AsWeakPtr(), device_id, document_url, this); |
266 | 271 |
267 open_reply_context_ = context->MakeReplyMessageContext(); | 272 open_reply_context_ = context->MakeReplyMessageContext(); |
268 | 273 |
269 return PP_OK_COMPLETIONPENDING; | 274 return PP_OK_COMPLETIONPENDING; |
270 } | 275 } |
271 | 276 |
272 int32_t PepperVideoCaptureHost::OnStartCapture( | 277 int32_t PepperVideoCaptureHost::OnStartCapture( |
273 ppapi::host::HostMessageContext* context) { | 278 ppapi::host::HostMessageContext* context) { |
274 if (!SetStatus(PP_VIDEO_CAPTURE_STATUS_STARTING, false) || | 279 if (!SetStatus(PP_VIDEO_CAPTURE_STATUS_STARTING, false) || |
275 !platform_video_capture_.get()) | 280 !platform_video_capture_.get()) |
276 return PP_ERROR_FAILED; | 281 return PP_ERROR_FAILED; |
277 | 282 |
278 DCHECK(buffers_.empty()); | 283 DCHECK(buffers_.empty()); |
279 | 284 |
280 // It's safe to call this regardless it's capturing or not, because | 285 // It's safe to call this regardless it's capturing or not, because |
281 // PepperPlatformVideoCapture maintains the state. | 286 // PepperPlatformVideoCapture maintains the state. |
282 platform_video_capture_->StartCapture(video_capture_params_); | 287 platform_video_capture_->StartCapture(this, video_capture_params_); |
283 return PP_OK; | 288 return PP_OK; |
284 } | 289 } |
285 | 290 |
286 int32_t PepperVideoCaptureHost::OnReuseBuffer( | 291 int32_t PepperVideoCaptureHost::OnReuseBuffer( |
287 ppapi::host::HostMessageContext* context, | 292 ppapi::host::HostMessageContext* context, |
288 uint32_t buffer) { | 293 uint32_t buffer) { |
289 if (buffer >= buffers_.size() || !buffers_[buffer].in_use) | 294 if (buffer >= buffers_.size() || !buffers_[buffer].in_use) |
290 return PP_ERROR_BADARGUMENT; | 295 return PP_ERROR_BADARGUMENT; |
291 buffers_[buffer].in_use = false; | 296 buffers_[buffer].in_use = false; |
292 return PP_OK; | 297 return PP_OK; |
(...skipping 11 matching lines...) Expand all Loading... |
304 | 309 |
305 int32_t PepperVideoCaptureHost::StopCapture() { | 310 int32_t PepperVideoCaptureHost::StopCapture() { |
306 if (!SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPING, false)) | 311 if (!SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPING, false)) |
307 return PP_ERROR_FAILED; | 312 return PP_ERROR_FAILED; |
308 | 313 |
309 DCHECK(platform_video_capture_.get()); | 314 DCHECK(platform_video_capture_.get()); |
310 | 315 |
311 ReleaseBuffers(); | 316 ReleaseBuffers(); |
312 // It's safe to call this regardless it's capturing or not, because | 317 // It's safe to call this regardless it's capturing or not, because |
313 // PepperPlatformVideoCapture maintains the state. | 318 // PepperPlatformVideoCapture maintains the state. |
314 platform_video_capture_->StopCapture(); | 319 platform_video_capture_->StopCapture(this); |
315 return PP_OK; | 320 return PP_OK; |
316 } | 321 } |
317 | 322 |
318 int32_t PepperVideoCaptureHost::Close() { | 323 int32_t PepperVideoCaptureHost::Close() { |
319 if (!platform_video_capture_.get()) | 324 if (!platform_video_capture_.get()) |
320 return PP_OK; | 325 return PP_OK; |
321 | 326 |
322 StopCapture(); | 327 StopCapture(); |
323 DCHECK(buffers_.empty()); | 328 DCHECK(buffers_.empty()); |
324 DetachPlatformVideoCapture(); | 329 DetachPlatformVideoCapture(); |
(...skipping 25 matching lines...) Expand all Loading... |
350 static_cast<uint32_t>(media::limits::kMaxFramesPerSecond - 1)); | 355 static_cast<uint32_t>(media::limits::kMaxFramesPerSecond - 1)); |
351 | 356 |
352 video_capture_params_.requested_format = media::VideoCaptureFormat( | 357 video_capture_params_.requested_format = media::VideoCaptureFormat( |
353 gfx::Size(device_info.width, device_info.height), | 358 gfx::Size(device_info.width, device_info.height), |
354 frames_per_second, | 359 frames_per_second, |
355 media::PIXEL_FORMAT_I420); | 360 media::PIXEL_FORMAT_I420); |
356 video_capture_params_.allow_resolution_change = false; | 361 video_capture_params_.allow_resolution_change = false; |
357 } | 362 } |
358 | 363 |
359 void PepperVideoCaptureHost::DetachPlatformVideoCapture() { | 364 void PepperVideoCaptureHost::DetachPlatformVideoCapture() { |
360 if (platform_video_capture_) { | 365 if (platform_video_capture_.get()) { |
361 platform_video_capture_->DetachEventHandler(); | 366 platform_video_capture_->DetachEventHandler(); |
362 platform_video_capture_.reset(); | 367 platform_video_capture_ = NULL; |
363 } | 368 } |
364 } | 369 } |
365 | 370 |
366 bool PepperVideoCaptureHost::SetStatus(PP_VideoCaptureStatus_Dev status, | 371 bool PepperVideoCaptureHost::SetStatus(PP_VideoCaptureStatus_Dev status, |
367 bool forced) { | 372 bool forced) { |
368 if (!forced) { | 373 if (!forced) { |
369 switch (status) { | 374 switch (status) { |
370 case PP_VIDEO_CAPTURE_STATUS_STOPPED: | 375 case PP_VIDEO_CAPTURE_STATUS_STOPPED: |
371 if (status_ != PP_VIDEO_CAPTURE_STATUS_STOPPING) | 376 if (status_ != PP_VIDEO_CAPTURE_STATUS_STOPPING) |
372 return false; | 377 return false; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 } | 409 } |
405 break; | 410 break; |
406 } | 411 } |
407 } | 412 } |
408 | 413 |
409 status_ = status; | 414 status_ = status; |
410 return true; | 415 return true; |
411 } | 416 } |
412 | 417 |
413 PepperVideoCaptureHost::BufferInfo::BufferInfo() | 418 PepperVideoCaptureHost::BufferInfo::BufferInfo() |
414 : in_use(false), data(NULL), buffer() { | 419 : in_use(false), data(NULL), buffer() {} |
415 } | |
416 | 420 |
417 PepperVideoCaptureHost::BufferInfo::~BufferInfo() { | 421 PepperVideoCaptureHost::BufferInfo::~BufferInfo() {} |
418 } | |
419 | 422 |
420 } // namespace content | 423 } // namespace content |
OLD | NEW |