| 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/browser/renderer_host/media/video_capture_controller.h" | 5 #include "content/browser/renderer_host/media/video_capture_controller.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 | 94 |
| 95 void VideoCaptureController::StartCapture( | 95 void VideoCaptureController::StartCapture( |
| 96 const VideoCaptureControllerID& id, | 96 const VideoCaptureControllerID& id, |
| 97 VideoCaptureControllerEventHandler* event_handler, | 97 VideoCaptureControllerEventHandler* event_handler, |
| 98 base::ProcessHandle render_process, | 98 base::ProcessHandle render_process, |
| 99 const media::VideoCaptureParams& params) { | 99 const media::VideoCaptureParams& params) { |
| 100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 101 DVLOG(1) << "VideoCaptureController::StartCapture, id " << id.device_id | 101 DVLOG(1) << "VideoCaptureController::StartCapture, id " << id.device_id |
| 102 << ", (" << params.width | 102 << ", (" << params.width |
| 103 << ", " << params.height | 103 << ", " << params.height |
| 104 << ", " << params.frame_per_second | 104 << ", " << params.frame_rate |
| 105 << ", " << params.session_id | 105 << ", " << params.session_id |
| 106 << ")"; | 106 << ")"; |
| 107 | 107 |
| 108 // Signal error in case device is already in error state. | 108 // Signal error in case device is already in error state. |
| 109 if (state_ == VIDEO_CAPTURE_STATE_ERROR) { | 109 if (state_ == VIDEO_CAPTURE_STATE_ERROR) { |
| 110 event_handler->OnError(id); | 110 event_handler->OnError(id); |
| 111 return; | 111 return; |
| 112 } | 112 } |
| 113 | 113 |
| 114 // Do nothing if this client has called StartCapture before. | 114 // Do nothing if this client has called StartCapture before. |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 // Implements VideoCaptureDevice::EventHandler. | 257 // Implements VideoCaptureDevice::EventHandler. |
| 258 // OnIncomingCapturedFrame is called the thread running the capture device. | 258 // OnIncomingCapturedFrame is called the thread running the capture device. |
| 259 // I.e.- DirectShow thread on windows and v4l2_thread on Linux. | 259 // I.e.- DirectShow thread on windows and v4l2_thread on Linux. |
| 260 void VideoCaptureController::OnIncomingCapturedFrame( | 260 void VideoCaptureController::OnIncomingCapturedFrame( |
| 261 const uint8* data, | 261 const uint8* data, |
| 262 int length, | 262 int length, |
| 263 base::Time timestamp, | 263 base::Time timestamp, |
| 264 int rotation, | 264 int rotation, |
| 265 bool flip_vert, | 265 bool flip_vert, |
| 266 bool flip_horiz) { | 266 bool flip_horiz) { |
| 267 DCHECK(frame_info_.color == media::VideoCaptureCapability::kI420 || | 267 DCHECK(frame_info_.color == media::kI420 || |
| 268 frame_info_.color == media::VideoCaptureCapability::kYV12 || | 268 frame_info_.color == media::kYV12 || |
| 269 (rotation == 0 && !flip_vert && !flip_horiz)); | 269 (rotation == 0 && !flip_vert && !flip_horiz)); |
| 270 | 270 |
| 271 scoped_refptr<media::VideoFrame> dst; | 271 scoped_refptr<media::VideoFrame> dst; |
| 272 { | 272 { |
| 273 base::AutoLock lock(buffer_pool_lock_); | 273 base::AutoLock lock(buffer_pool_lock_); |
| 274 if (!buffer_pool_.get()) | 274 if (!buffer_pool_.get()) |
| 275 return; | 275 return; |
| 276 dst = buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width, | 276 dst = buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width, |
| 277 frame_info_.height), | 277 frame_info_.height), |
| 278 rotation); | 278 rotation); |
| 279 } | 279 } |
| 280 | 280 |
| 281 if (!dst.get()) | 281 if (!dst.get()) |
| 282 return; | 282 return; |
| 283 | 283 |
| 284 uint8* yplane = dst->data(media::VideoFrame::kYPlane); | 284 uint8* yplane = dst->data(media::VideoFrame::kYPlane); |
| 285 uint8* uplane = dst->data(media::VideoFrame::kUPlane); | 285 uint8* uplane = dst->data(media::VideoFrame::kUPlane); |
| 286 uint8* vplane = dst->data(media::VideoFrame::kVPlane); | 286 uint8* vplane = dst->data(media::VideoFrame::kVPlane); |
| 287 | 287 |
| 288 // Do color conversion from the camera format to I420. | 288 // Do color conversion from the camera format to I420. |
| 289 switch (frame_info_.color) { | 289 switch (frame_info_.color) { |
| 290 case media::VideoCaptureCapability::kColorUnknown: // Color format not set. | 290 case media::kColorUnknown: // Color format not set. |
| 291 break; | 291 break; |
| 292 case media::VideoCaptureCapability::kI420: | 292 case media::kI420: |
| 293 DCHECK(!chopped_width_ && !chopped_height_); | 293 DCHECK(!chopped_width_ && !chopped_height_); |
| 294 RotatePackedYV12Frame( | 294 RotatePackedYV12Frame( |
| 295 data, yplane, uplane, vplane, frame_info_.width, frame_info_.height, | 295 data, yplane, uplane, vplane, frame_info_.width, frame_info_.height, |
| 296 rotation, flip_vert, flip_horiz); | 296 rotation, flip_vert, flip_horiz); |
| 297 break; | 297 break; |
| 298 case media::VideoCaptureCapability::kYV12: | 298 case media::kYV12: |
| 299 DCHECK(!chopped_width_ && !chopped_height_); | 299 DCHECK(!chopped_width_ && !chopped_height_); |
| 300 RotatePackedYV12Frame( | 300 RotatePackedYV12Frame( |
| 301 data, yplane, vplane, uplane, frame_info_.width, frame_info_.height, | 301 data, yplane, vplane, uplane, frame_info_.width, frame_info_.height, |
| 302 rotation, flip_vert, flip_horiz); | 302 rotation, flip_vert, flip_horiz); |
| 303 break; | 303 break; |
| 304 case media::VideoCaptureCapability::kNV21: | 304 case media::kNV21: |
| 305 DCHECK(!chopped_width_ && !chopped_height_); | 305 DCHECK(!chopped_width_ && !chopped_height_); |
| 306 media::ConvertNV21ToYUV(data, yplane, uplane, vplane, frame_info_.width, | 306 media::ConvertNV21ToYUV(data, yplane, uplane, vplane, frame_info_.width, |
| 307 frame_info_.height); | 307 frame_info_.height); |
| 308 break; | 308 break; |
| 309 case media::VideoCaptureCapability::kYUY2: | 309 case media::kYUY2: |
| 310 DCHECK(!chopped_width_ && !chopped_height_); | 310 DCHECK(!chopped_width_ && !chopped_height_); |
| 311 if (frame_info_.width * frame_info_.height * 2 != length) { | 311 if (frame_info_.width * frame_info_.height * 2 != length) { |
| 312 // If |length| of |data| does not match the expected width and height | 312 // If |length| of |data| does not match the expected width and height |
| 313 // we can't convert the frame to I420. YUY2 is 2 bytes per pixel. | 313 // we can't convert the frame to I420. YUY2 is 2 bytes per pixel. |
| 314 break; | 314 break; |
| 315 } | 315 } |
| 316 | 316 |
| 317 media::ConvertYUY2ToYUV(data, yplane, uplane, vplane, frame_info_.width, | 317 media::ConvertYUY2ToYUV(data, yplane, uplane, vplane, frame_info_.width, |
| 318 frame_info_.height); | 318 frame_info_.height); |
| 319 break; | 319 break; |
| 320 case media::VideoCaptureCapability::kRGB24: { | 320 case media::kRGB24: { |
| 321 int ystride = frame_info_.width; | 321 int ystride = frame_info_.width; |
| 322 int uvstride = frame_info_.width / 2; | 322 int uvstride = frame_info_.width / 2; |
| 323 #if defined(OS_WIN) // RGB on Windows start at the bottom line. | 323 #if defined(OS_WIN) // RGB on Windows start at the bottom line. |
| 324 int rgb_stride = -3 * (frame_info_.width + chopped_width_); | 324 int rgb_stride = -3 * (frame_info_.width + chopped_width_); |
| 325 const uint8* rgb_src = data + 3 * (frame_info_.width + chopped_width_) * | 325 const uint8* rgb_src = data + 3 * (frame_info_.width + chopped_width_) * |
| 326 (frame_info_.height -1 + chopped_height_); | 326 (frame_info_.height -1 + chopped_height_); |
| 327 #else | 327 #else |
| 328 int rgb_stride = 3 * (frame_info_.width + chopped_width_); | 328 int rgb_stride = 3 * (frame_info_.width + chopped_width_); |
| 329 const uint8* rgb_src = data; | 329 const uint8* rgb_src = data; |
| 330 #endif | 330 #endif |
| 331 media::ConvertRGB24ToYUV(rgb_src, yplane, uplane, vplane, | 331 media::ConvertRGB24ToYUV(rgb_src, yplane, uplane, vplane, |
| 332 frame_info_.width, frame_info_.height, | 332 frame_info_.width, frame_info_.height, |
| 333 rgb_stride, ystride, uvstride); | 333 rgb_stride, ystride, uvstride); |
| 334 break; | 334 break; |
| 335 } | 335 } |
| 336 case media::VideoCaptureCapability::kARGB: | 336 case media::kARGB: |
| 337 media::ConvertRGB32ToYUV(data, yplane, uplane, vplane, frame_info_.width, | 337 media::ConvertRGB32ToYUV(data, yplane, uplane, vplane, frame_info_.width, |
| 338 frame_info_.height, | 338 frame_info_.height, |
| 339 (frame_info_.width + chopped_width_) * 4, | 339 (frame_info_.width + chopped_width_) * 4, |
| 340 frame_info_.width, frame_info_.width / 2); | 340 frame_info_.width, frame_info_.width / 2); |
| 341 break; | 341 break; |
| 342 #if !defined(OS_IOS) && !defined(OS_ANDROID) | 342 #if !defined(OS_IOS) && !defined(OS_ANDROID) |
| 343 case media::VideoCaptureCapability::kMJPEG: { | 343 case media::kMJPEG: { |
| 344 int yplane_stride = frame_info_.width; | 344 int yplane_stride = frame_info_.width; |
| 345 int uv_plane_stride = (frame_info_.width + 1) / 2; | 345 int uv_plane_stride = (frame_info_.width + 1) / 2; |
| 346 int crop_x = 0; | 346 int crop_x = 0; |
| 347 int crop_y = 0; | 347 int crop_y = 0; |
| 348 libyuv::ConvertToI420(data, length, yplane, yplane_stride, uplane, | 348 libyuv::ConvertToI420(data, length, yplane, yplane_stride, uplane, |
| 349 uv_plane_stride, vplane, uv_plane_stride, crop_x, | 349 uv_plane_stride, vplane, uv_plane_stride, crop_x, |
| 350 crop_y, frame_info_.width, frame_info_.height, | 350 crop_y, frame_info_.width, frame_info_.height, |
| 351 frame_info_.width, frame_info_.height, | 351 frame_info_.width, frame_info_.height, |
| 352 libyuv::kRotate0, libyuv::FOURCC_MJPG); | 352 libyuv::kRotate0, libyuv::FOURCC_MJPG); |
| 353 break; | 353 break; |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 723 controller_clients_.push_back((*client_it)); | 723 controller_clients_.push_back((*client_it)); |
| 724 pending_clients_.erase(client_it++); | 724 pending_clients_.erase(client_it++); |
| 725 } | 725 } |
| 726 // Request the manager to start the actual capture. | 726 // Request the manager to start the actual capture. |
| 727 video_capture_manager_->Start(current_params_, this); | 727 video_capture_manager_->Start(current_params_, this); |
| 728 state_ = VIDEO_CAPTURE_STATE_STARTED; | 728 state_ = VIDEO_CAPTURE_STATE_STARTED; |
| 729 device_in_use_ = true; | 729 device_in_use_ = true; |
| 730 } | 730 } |
| 731 | 731 |
| 732 } // namespace content | 732 } // namespace content |
| OLD | NEW |