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