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 PostErrorReply(); |
| 122 } |
| 123 |
| 124 void PepperVideoCaptureHost::PostErrorReply() { |
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 PostErrorReply(); |
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, video_capture_params_); |
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 video_capture_params_.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 |