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 |