| 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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 | 111 |
| 112 void PepperVideoCaptureHost::OnPaused(media::VideoCapture* capture) { | 112 void PepperVideoCaptureHost::OnPaused(media::VideoCapture* capture) { |
| 113 if (SetStatus(PP_VIDEO_CAPTURE_STATUS_PAUSED, false)) | 113 if (SetStatus(PP_VIDEO_CAPTURE_STATUS_PAUSED, false)) |
| 114 SendStatus(); | 114 SendStatus(); |
| 115 } | 115 } |
| 116 | 116 |
| 117 void PepperVideoCaptureHost::OnError(media::VideoCapture* capture, | 117 void PepperVideoCaptureHost::OnError(media::VideoCapture* capture, |
| 118 int error_code) { | 118 int error_code) { |
| 119 // Today, the media layer only sends "1" as an error. | 119 // Today, the media layer only sends "1" as an error. |
| 120 DCHECK(error_code == 1); | 120 DCHECK(error_code == 1); |
| 121 Error(); |
| 122 } |
| 123 |
| 124 void PepperVideoCaptureHost::Error() { |
| 121 // It either comes because some error was detected while starting (e.g. 2 | 125 // It either comes because some error was detected while starting (e.g. 2 |
| 122 // conflicting "master" resolution), or because the browser failed to start | 126 // conflicting "master" resolution), or because the browser failed to start |
| 123 // the capture. | 127 // the capture. |
| 124 SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPED, true); | 128 SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPED, true); |
| 125 host()->SendUnsolicitedReply(pp_resource(), | 129 host()->SendUnsolicitedReply(pp_resource(), |
| 126 PpapiPluginMsg_VideoCapture_OnError(PP_ERROR_FAILED)); | 130 PpapiPluginMsg_VideoCapture_OnError(PP_ERROR_FAILED)); |
| 127 } | 131 } |
| 128 | 132 |
| 129 void PepperVideoCaptureHost::OnRemoved(media::VideoCapture* capture) { | 133 void PepperVideoCaptureHost::OnRemoved(media::VideoCapture* capture) { |
| 130 } | 134 } |
| 131 | 135 |
| 132 void PepperVideoCaptureHost::OnFrameReady( | 136 void PepperVideoCaptureHost::OnFrameReady( |
| 133 media::VideoCapture* capture, | 137 media::VideoCapture* capture, |
| 134 const scoped_refptr<media::VideoFrame>& frame) { | 138 const scoped_refptr<media::VideoFrame>& frame) { |
| 135 DCHECK(frame.get()); | 139 DCHECK(frame.get()); |
| 140 |
| 141 if (alloc_size_ != frame->coded_size()) { |
| 142 AllocBuffers(frame->coded_size(), capture->CaptureFrameRate()); |
| 143 alloc_size_ = frame->coded_size(); |
| 144 } |
| 145 |
| 136 for (uint32_t i = 0; i < buffers_.size(); ++i) { | 146 for (uint32_t i = 0; i < buffers_.size(); ++i) { |
| 137 if (!buffers_[i].in_use) { | 147 if (!buffers_[i].in_use) { |
| 138 DCHECK_EQ(frame->format(), media::VideoFrame::I420); | 148 DCHECK_EQ(frame->format(), media::VideoFrame::I420); |
| 139 if (buffers_[i].buffer->size() < | 149 if (buffers_[i].buffer->size() < |
| 140 media::VideoFrame::AllocationSize(frame->format(), | 150 media::VideoFrame::AllocationSize(frame->format(), |
| 141 frame->coded_size())) { | 151 frame->coded_size())) { |
| 142 // TODO(ihf): handle size mismatches gracefully here. | 152 // TODO(ihf): handle size mismatches gracefully here. |
| 143 return; | 153 return; |
| 144 } | 154 } |
| 145 uint8* dst = reinterpret_cast<uint8*>(buffers_[i].data); | 155 uint8* dst = reinterpret_cast<uint8*>(buffers_[i].data); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 158 } | 168 } |
| 159 } | 169 } |
| 160 buffers_[i].in_use = true; | 170 buffers_[i].in_use = true; |
| 161 host()->SendUnsolicitedReply(pp_resource(), | 171 host()->SendUnsolicitedReply(pp_resource(), |
| 162 PpapiPluginMsg_VideoCapture_OnBufferReady(i)); | 172 PpapiPluginMsg_VideoCapture_OnBufferReady(i)); |
| 163 return; | 173 return; |
| 164 } | 174 } |
| 165 } | 175 } |
| 166 } | 176 } |
| 167 | 177 |
| 168 void PepperVideoCaptureHost::OnDeviceInfoReceived( | 178 void PepperVideoCaptureHost::AllocBuffers( |
| 169 media::VideoCapture* capture, | 179 const gfx::Size& resolution, |
| 170 const media::VideoCaptureParams& device_info) { | 180 int frame_rate) { |
| 171 PP_VideoCaptureDeviceInfo_Dev info = { | 181 PP_VideoCaptureDeviceInfo_Dev info = { |
| 172 static_cast<uint32_t>(device_info.width), | 182 static_cast<uint32_t>(resolution.width()), |
| 173 static_cast<uint32_t>(device_info.height), | 183 static_cast<uint32_t>(resolution.height()), |
| 174 static_cast<uint32_t>(device_info.frame_rate) | 184 static_cast<uint32_t>(frame_rate) |
| 175 }; | 185 }; |
| 176 ReleaseBuffers(); | 186 ReleaseBuffers(); |
| 177 | 187 |
| 178 const size_t size = media::VideoFrame::AllocationSize( | 188 const size_t size = media::VideoFrame::AllocationSize( |
| 179 media::VideoFrame::I420, gfx::Size(info.width, info.height)); | 189 media::VideoFrame::I420, gfx::Size(info.width, info.height)); |
| 180 | 190 |
| 181 ppapi::proxy::ResourceMessageReplyParams params(pp_resource(), 0); | 191 ppapi::proxy::ResourceMessageReplyParams params(pp_resource(), 0); |
| 182 | 192 |
| 183 // Allocate buffers. We keep a reference to them, that is released in | 193 // Allocate buffers. We keep a reference to them, that is released in |
| 184 // ReleaseBuffers. In the mean time, we prepare the resource and handle here | 194 // ReleaseBuffers. In the mean time, we prepare the resource and handle here |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 dispatcher->ShareHandleWithRemote(platform_file, false), | 249 dispatcher->ShareHandleWithRemote(platform_file, false), |
| 240 size)); | 250 size)); |
| 241 } | 251 } |
| 242 } | 252 } |
| 243 | 253 |
| 244 if (buffers_.empty()) { | 254 if (buffers_.empty()) { |
| 245 // We couldn't allocate/map buffers at all. Send an error and stop the | 255 // We couldn't allocate/map buffers at all. Send an error and stop the |
| 246 // capture. | 256 // capture. |
| 247 SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPING, true); | 257 SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPING, true); |
| 248 platform_video_capture_->StopCapture(this); | 258 platform_video_capture_->StopCapture(this); |
| 249 OnError(capture, PP_ERROR_NOMEMORY); | 259 Error(); |
| 250 return; | 260 return; |
| 251 } | 261 } |
| 252 | 262 |
| 253 host()->Send(new PpapiPluginMsg_ResourceReply( | 263 host()->Send(new PpapiPluginMsg_ResourceReply( |
| 254 params, PpapiPluginMsg_VideoCapture_OnDeviceInfo( | 264 params, PpapiPluginMsg_VideoCapture_OnDeviceInfo( |
| 255 info, buffer_host_resources, size))); | 265 info, buffer_host_resources, size))); |
| 256 } | 266 } |
| 257 | 267 |
| 258 int32_t PepperVideoCaptureHost::OnOpen( | 268 int32_t PepperVideoCaptureHost::OnOpen( |
| 259 ppapi::host::HostMessageContext* context, | 269 ppapi::host::HostMessageContext* context, |
| (...skipping 25 matching lines...) Expand all Loading... |
| 285 int32_t PepperVideoCaptureHost::OnStartCapture( | 295 int32_t PepperVideoCaptureHost::OnStartCapture( |
| 286 ppapi::host::HostMessageContext* context) { | 296 ppapi::host::HostMessageContext* context) { |
| 287 if (!SetStatus(PP_VIDEO_CAPTURE_STATUS_STARTING, false) || | 297 if (!SetStatus(PP_VIDEO_CAPTURE_STATUS_STARTING, false) || |
| 288 !platform_video_capture_.get()) | 298 !platform_video_capture_.get()) |
| 289 return PP_ERROR_FAILED; | 299 return PP_ERROR_FAILED; |
| 290 | 300 |
| 291 DCHECK(buffers_.empty()); | 301 DCHECK(buffers_.empty()); |
| 292 | 302 |
| 293 // It's safe to call this regardless it's capturing or not, because | 303 // It's safe to call this regardless it's capturing or not, because |
| 294 // PepperPlatformVideoCapture maintains the state. | 304 // PepperPlatformVideoCapture maintains the state. |
| 295 platform_video_capture_->StartCapture(this, capability_); | 305 platform_video_capture_->StartCapture(this, param_request_); |
| 296 return PP_OK; | 306 return PP_OK; |
| 297 } | 307 } |
| 298 | 308 |
| 299 int32_t PepperVideoCaptureHost::OnReuseBuffer( | 309 int32_t PepperVideoCaptureHost::OnReuseBuffer( |
| 300 ppapi::host::HostMessageContext* context, | 310 ppapi::host::HostMessageContext* context, |
| 301 uint32_t buffer) { | 311 uint32_t buffer) { |
| 302 if (buffer >= buffers_.size() || !buffers_[buffer].in_use) | 312 if (buffer >= buffers_.size() || !buffers_[buffer].in_use) |
| 303 return PP_ERROR_BADARGUMENT; | 313 return PP_ERROR_BADARGUMENT; |
| 304 buffers_[buffer].in_use = false; | 314 buffers_[buffer].in_use = false; |
| 305 return PP_OK; | 315 return PP_OK; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 host()->SendUnsolicitedReply(pp_resource(), | 361 host()->SendUnsolicitedReply(pp_resource(), |
| 352 PpapiPluginMsg_VideoCapture_OnStatus(status_)); | 362 PpapiPluginMsg_VideoCapture_OnStatus(status_)); |
| 353 } | 363 } |
| 354 | 364 |
| 355 void PepperVideoCaptureHost::SetRequestedInfo( | 365 void PepperVideoCaptureHost::SetRequestedInfo( |
| 356 const PP_VideoCaptureDeviceInfo_Dev& device_info, | 366 const PP_VideoCaptureDeviceInfo_Dev& device_info, |
| 357 uint32_t buffer_count) { | 367 uint32_t buffer_count) { |
| 358 // Clamp the buffer count to between 1 and |kMaxBuffers|. | 368 // Clamp the buffer count to between 1 and |kMaxBuffers|. |
| 359 buffer_count_hint_ = std::min(std::max(buffer_count, 1U), kMaxBuffers); | 369 buffer_count_hint_ = std::min(std::max(buffer_count, 1U), kMaxBuffers); |
| 360 | 370 |
| 361 capability_.width = device_info.width; | 371 param_request_.requested_format = |
| 362 capability_.height = device_info.height; | 372 media::VideoCaptureFormat(device_info.width, |
| 363 capability_.frame_rate = device_info.frames_per_second; | 373 device_info.height, |
| 364 capability_.expected_capture_delay = 0; // Ignored. | 374 device_info.frames_per_second, |
| 365 capability_.color = media::PIXEL_FORMAT_I420; | 375 media::ConstantResolutionVideoCaptureDevice); |
| 366 capability_.interlaced = false; // Ignored. | |
| 367 } | 376 } |
| 368 | 377 |
| 369 void PepperVideoCaptureHost::DetachPlatformVideoCapture() { | 378 void PepperVideoCaptureHost::DetachPlatformVideoCapture() { |
| 370 if (platform_video_capture_.get()) { | 379 if (platform_video_capture_.get()) { |
| 371 platform_video_capture_->DetachEventHandler(); | 380 platform_video_capture_->DetachEventHandler(); |
| 372 platform_video_capture_ = NULL; | 381 platform_video_capture_ = NULL; |
| 373 } | 382 } |
| 374 } | 383 } |
| 375 | 384 |
| 376 bool PepperVideoCaptureHost::SetStatus(PP_VideoCaptureStatus_Dev status, | 385 bool PepperVideoCaptureHost::SetStatus(PP_VideoCaptureStatus_Dev status, |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 PepperVideoCaptureHost::BufferInfo::BufferInfo() | 432 PepperVideoCaptureHost::BufferInfo::BufferInfo() |
| 424 : in_use(false), | 433 : in_use(false), |
| 425 data(NULL), | 434 data(NULL), |
| 426 buffer() { | 435 buffer() { |
| 427 } | 436 } |
| 428 | 437 |
| 429 PepperVideoCaptureHost::BufferInfo::~BufferInfo() { | 438 PepperVideoCaptureHost::BufferInfo::~BufferInfo() { |
| 430 } | 439 } |
| 431 | 440 |
| 432 } // namespace content | 441 } // namespace content |
| OLD | NEW |