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