| 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/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 | 97 |
| 98 void VideoCaptureController::StartCapture( | 98 void VideoCaptureController::StartCapture( |
| 99 const VideoCaptureControllerID& id, | 99 const VideoCaptureControllerID& id, |
| 100 VideoCaptureControllerEventHandler* event_handler, | 100 VideoCaptureControllerEventHandler* event_handler, |
| 101 base::ProcessHandle render_process, | 101 base::ProcessHandle render_process, |
| 102 const media::VideoCaptureParams& params) { | 102 const media::VideoCaptureParams& params) { |
| 103 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 103 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 104 DVLOG(1) << "VideoCaptureController::StartCapture, id " << id.device_id | 104 DVLOG(1) << "VideoCaptureController::StartCapture, id " << id.device_id |
| 105 << ", (" << params.width | 105 << ", (" << params.width |
| 106 << ", " << params.height | 106 << ", " << params.height |
| 107 << ", " << params.frame_per_second | 107 << ", " << params.frame_rate |
| 108 << ", " << params.session_id | 108 << ", " << params.session_id |
| 109 << ")"; | 109 << ")"; |
| 110 | 110 |
| 111 // Signal error in case device is already in error state. | 111 // Signal error in case device is already in error state. |
| 112 if (state_ == VIDEO_CAPTURE_STATE_ERROR) { | 112 if (state_ == VIDEO_CAPTURE_STATE_ERROR) { |
| 113 event_handler->OnError(id); | 113 event_handler->OnError(id); |
| 114 return; | 114 return; |
| 115 } | 115 } |
| 116 | 116 |
| 117 // Do nothing if this client has called StartCapture before. | 117 // Do nothing if this client has called StartCapture before. |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 int new_rotation_angle = (rotation + 180 * flip_vert) % 360; | 297 int new_rotation_angle = (rotation + 180 * flip_vert) % 360; |
| 298 libyuv::RotationMode rotation_mode = libyuv::kRotate0; | 298 libyuv::RotationMode rotation_mode = libyuv::kRotate0; |
| 299 if (new_rotation_angle == 90) | 299 if (new_rotation_angle == 90) |
| 300 rotation_mode = libyuv::kRotate90; | 300 rotation_mode = libyuv::kRotate90; |
| 301 else if (new_rotation_angle == 180) | 301 else if (new_rotation_angle == 180) |
| 302 rotation_mode = libyuv::kRotate180; | 302 rotation_mode = libyuv::kRotate180; |
| 303 else if (new_rotation_angle == 270) | 303 else if (new_rotation_angle == 270) |
| 304 rotation_mode = libyuv::kRotate270; | 304 rotation_mode = libyuv::kRotate270; |
| 305 | 305 |
| 306 switch (frame_info_.color) { | 306 switch (frame_info_.color) { |
| 307 case media::VideoCaptureCapability::kColorUnknown: // Color format not set. | 307 case media::PIXEL_FORMAT_UNKNOWN: // Color format not set. |
| 308 break; | 308 break; |
| 309 case media::VideoCaptureCapability::kI420: | 309 case media::PIXEL_FORMAT_I420: |
| 310 DCHECK(!chopped_width_ && !chopped_height_); | 310 DCHECK(!chopped_width_ && !chopped_height_); |
| 311 origin_colorspace = libyuv::FOURCC_I420; | 311 origin_colorspace = libyuv::FOURCC_I420; |
| 312 break; | 312 break; |
| 313 case media::VideoCaptureCapability::kYV12: | 313 case media::PIXEL_FORMAT_YV12: |
| 314 DCHECK(!chopped_width_ && !chopped_height_); | 314 DCHECK(!chopped_width_ && !chopped_height_); |
| 315 origin_colorspace = libyuv::FOURCC_YV12; | 315 origin_colorspace = libyuv::FOURCC_YV12; |
| 316 break; | 316 break; |
| 317 case media::VideoCaptureCapability::kNV21: | 317 case media::PIXEL_FORMAT_NV21: |
| 318 DCHECK(!chopped_width_ && !chopped_height_); | 318 DCHECK(!chopped_width_ && !chopped_height_); |
| 319 origin_colorspace = libyuv::FOURCC_NV12; | 319 origin_colorspace = libyuv::FOURCC_NV12; |
| 320 break; | 320 break; |
| 321 case media::VideoCaptureCapability::kYUY2: | 321 case media::PIXEL_FORMAT_YUY2: |
| 322 DCHECK(!chopped_width_ && !chopped_height_); | 322 DCHECK(!chopped_width_ && !chopped_height_); |
| 323 origin_colorspace = libyuv::FOURCC_YUY2; | 323 origin_colorspace = libyuv::FOURCC_YUY2; |
| 324 break; | 324 break; |
| 325 case media::VideoCaptureCapability::kRGB24: | 325 case media::PIXEL_FORMAT_RGB24: |
| 326 origin_colorspace = libyuv::FOURCC_RAW; | 326 origin_colorspace = libyuv::FOURCC_RAW; |
| 327 break; | 327 break; |
| 328 case media::VideoCaptureCapability::kARGB: | 328 case media::PIXEL_FORMAT_ARGB: |
| 329 origin_colorspace = libyuv::FOURCC_ARGB; | 329 origin_colorspace = libyuv::FOURCC_ARGB; |
| 330 break; | 330 break; |
| 331 case media::VideoCaptureCapability::kMJPEG: | 331 case media::PIXEL_FORMAT_MJPEG: |
| 332 origin_colorspace = libyuv::FOURCC_MJPG; | 332 origin_colorspace = libyuv::FOURCC_MJPG; |
| 333 break; | 333 break; |
| 334 default: | 334 default: |
| 335 NOTREACHED(); | 335 NOTREACHED(); |
| 336 } | 336 } |
| 337 | 337 |
| 338 int need_convert_rgb24_on_win = false; | 338 int need_convert_rgb24_on_win = false; |
| 339 #if defined(OS_WIN) | 339 #if defined(OS_WIN) |
| 340 // kRGB24 on Windows start at the bottom line and has a negative stride. This | 340 // kRGB24 on Windows start at the bottom line and has a negative stride. This |
| 341 // is not supported by libyuv, so the media API is used instead. | 341 // is not supported by libyuv, so the media API is used instead. |
| 342 if (frame_info_.color == media::VideoCaptureCapability::kRGB24) { | 342 if (frame_info_.color == media::PIXEL_FORMAT_RGB24) { |
| 343 // Rotation and flipping is not supported in kRGB24 and OS_WIN case. | 343 // Rotation and flipping is not supported in kRGB24 and OS_WIN case. |
| 344 DCHECK(!rotation && !flip_vert && !flip_horiz); | 344 DCHECK(!rotation && !flip_vert && !flip_horiz); |
| 345 need_convert_rgb24_on_win = true; | 345 need_convert_rgb24_on_win = true; |
| 346 } | 346 } |
| 347 #endif | 347 #endif |
| 348 if (need_convert_rgb24_on_win) { | 348 if (need_convert_rgb24_on_win) { |
| 349 int rgb_stride = -3 * (frame_info_.width + chopped_width_); | 349 int rgb_stride = -3 * (frame_info_.width + chopped_width_); |
| 350 const uint8* rgb_src = | 350 const uint8* rgb_src = |
| 351 data + 3 * (frame_info_.width + chopped_width_) * | 351 data + 3 * (frame_info_.width + chopped_width_) * |
| 352 (frame_info_.height - 1 + chopped_height_); | 352 (frame_info_.height - 1 + chopped_height_); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 timestamp)); | 387 timestamp)); |
| 388 } | 388 } |
| 389 #else | 389 #else |
| 390 void VideoCaptureController::OnIncomingCapturedFrame( | 390 void VideoCaptureController::OnIncomingCapturedFrame( |
| 391 const uint8* data, | 391 const uint8* data, |
| 392 int length, | 392 int length, |
| 393 base::Time timestamp, | 393 base::Time timestamp, |
| 394 int rotation, | 394 int rotation, |
| 395 bool flip_vert, | 395 bool flip_vert, |
| 396 bool flip_horiz) { | 396 bool flip_horiz) { |
| 397 DCHECK(frame_info_.color == media::VideoCaptureCapability::kI420 || | 397 DCHECK(frame_info_.color == media::PIXEL_FORMAT_I420 || |
| 398 frame_info_.color == media::VideoCaptureCapability::kYV12 || | 398 frame_info_.color == media::PIXEL_FORMAT_YV12 || |
| 399 (rotation == 0 && !flip_vert && !flip_horiz)); | 399 (rotation == 0 && !flip_vert && !flip_horiz)); |
| 400 | 400 |
| 401 TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame"); | 401 TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame"); |
| 402 | 402 |
| 403 scoped_refptr<media::VideoFrame> dst; | 403 scoped_refptr<media::VideoFrame> dst; |
| 404 { | 404 { |
| 405 base::AutoLock lock(buffer_pool_lock_); | 405 base::AutoLock lock(buffer_pool_lock_); |
| 406 if (!buffer_pool_.get()) | 406 if (!buffer_pool_.get()) |
| 407 return; | 407 return; |
| 408 dst = buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width, | 408 dst = buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width, |
| 409 frame_info_.height), | 409 frame_info_.height), |
| 410 rotation); | 410 rotation); |
| 411 } | 411 } |
| 412 | 412 |
| 413 if (!dst.get()) | 413 if (!dst.get()) |
| 414 return; | 414 return; |
| 415 | 415 |
| 416 uint8* yplane = dst->data(media::VideoFrame::kYPlane); | 416 uint8* yplane = dst->data(media::VideoFrame::kYPlane); |
| 417 uint8* uplane = dst->data(media::VideoFrame::kUPlane); | 417 uint8* uplane = dst->data(media::VideoFrame::kUPlane); |
| 418 uint8* vplane = dst->data(media::VideoFrame::kVPlane); | 418 uint8* vplane = dst->data(media::VideoFrame::kVPlane); |
| 419 | 419 |
| 420 // Do color conversion from the camera format to I420. | 420 // Do color conversion from the camera format to I420. |
| 421 switch (frame_info_.color) { | 421 switch (frame_info_.color) { |
| 422 case media::VideoCaptureCapability::kColorUnknown: // Color format not set. | 422 case media::PIXEL_FORMAT_UNKNOWN: // Color format not set. |
| 423 break; | 423 break; |
| 424 case media::VideoCaptureCapability::kI420: | 424 case media::PIXEL_FORMAT_I420: |
| 425 DCHECK(!chopped_width_ && !chopped_height_); | 425 DCHECK(!chopped_width_ && !chopped_height_); |
| 426 RotatePackedYV12Frame( | 426 RotatePackedYV12Frame( |
| 427 data, yplane, uplane, vplane, frame_info_.width, frame_info_.height, | 427 data, yplane, uplane, vplane, frame_info_.width, frame_info_.height, |
| 428 rotation, flip_vert, flip_horiz); | 428 rotation, flip_vert, flip_horiz); |
| 429 break; | 429 break; |
| 430 case media::VideoCaptureCapability::kYV12: | 430 case media::PIXEL_FORMAT_YV12: |
| 431 DCHECK(!chopped_width_ && !chopped_height_); | 431 DCHECK(!chopped_width_ && !chopped_height_); |
| 432 RotatePackedYV12Frame( | 432 RotatePackedYV12Frame( |
| 433 data, yplane, vplane, uplane, frame_info_.width, frame_info_.height, | 433 data, yplane, vplane, uplane, frame_info_.width, frame_info_.height, |
| 434 rotation, flip_vert, flip_horiz); | 434 rotation, flip_vert, flip_horiz); |
| 435 break; | 435 break; |
| 436 case media::VideoCaptureCapability::kNV21: | 436 case media::PIXEL_FORMAT_NV21: |
| 437 DCHECK(!chopped_width_ && !chopped_height_); | 437 DCHECK(!chopped_width_ && !chopped_height_); |
| 438 media::ConvertNV21ToYUV(data, yplane, uplane, vplane, frame_info_.width, | 438 media::ConvertNV21ToYUV(data, yplane, uplane, vplane, frame_info_.width, |
| 439 frame_info_.height); | 439 frame_info_.height); |
| 440 break; | 440 break; |
| 441 case media::VideoCaptureCapability::kYUY2: | 441 case media::PIXEL_FORMAT_YUY2: |
| 442 DCHECK(!chopped_width_ && !chopped_height_); | 442 DCHECK(!chopped_width_ && !chopped_height_); |
| 443 if (frame_info_.width * frame_info_.height * 2 != length) { | 443 if (frame_info_.width * frame_info_.height * 2 != length) { |
| 444 // If |length| of |data| does not match the expected width and height | 444 // If |length| of |data| does not match the expected width and height |
| 445 // we can't convert the frame to I420. YUY2 is 2 bytes per pixel. | 445 // we can't convert the frame to I420. YUY2 is 2 bytes per pixel. |
| 446 break; | 446 break; |
| 447 } | 447 } |
| 448 |
| 448 media::ConvertYUY2ToYUV(data, yplane, uplane, vplane, frame_info_.width, | 449 media::ConvertYUY2ToYUV(data, yplane, uplane, vplane, frame_info_.width, |
| 449 frame_info_.height); | 450 frame_info_.height); |
| 450 break; | 451 break; |
| 451 case media::VideoCaptureCapability::kRGB24: { | 452 case media::PIXEL_FORMAT_RGB24: { |
| 452 int ystride = frame_info_.width; | 453 int ystride = frame_info_.width; |
| 453 int uvstride = frame_info_.width / 2; | 454 int uvstride = frame_info_.width / 2; |
| 454 int rgb_stride = 3 * (frame_info_.width + chopped_width_); | 455 int rgb_stride = 3 * (frame_info_.width + chopped_width_); |
| 455 const uint8* rgb_src = data; | 456 const uint8* rgb_src = data; |
| 456 media::ConvertRGB24ToYUV(rgb_src, yplane, uplane, vplane, | 457 media::ConvertRGB24ToYUV(rgb_src, yplane, uplane, vplane, |
| 457 frame_info_.width, frame_info_.height, | 458 frame_info_.width, frame_info_.height, |
| 458 rgb_stride, ystride, uvstride); | 459 rgb_stride, ystride, uvstride); |
| 459 break; | 460 break; |
| 460 } | 461 } |
| 461 case media::VideoCaptureCapability::kARGB: | 462 case media::PIXEL_FORMAT_ARGB: |
| 462 media::ConvertRGB32ToYUV(data, yplane, uplane, vplane, frame_info_.width, | 463 media::ConvertRGB32ToYUV(data, yplane, uplane, vplane, frame_info_.width, |
| 463 frame_info_.height, | 464 frame_info_.height, |
| 464 (frame_info_.width + chopped_width_) * 4, | 465 (frame_info_.width + chopped_width_) * 4, |
| 465 frame_info_.width, frame_info_.width / 2); | 466 frame_info_.width, frame_info_.width / 2); |
| 466 break; | 467 break; |
| 467 default: | 468 default: |
| 468 NOTREACHED(); | 469 NOTREACHED(); |
| 469 } | 470 } |
| 470 | 471 |
| 471 BrowserThread::PostTask(BrowserThread::IO, | 472 BrowserThread::PostTask(BrowserThread::IO, |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 838 controller_clients_.push_back((*client_it)); | 839 controller_clients_.push_back((*client_it)); |
| 839 pending_clients_.erase(client_it++); | 840 pending_clients_.erase(client_it++); |
| 840 } | 841 } |
| 841 // Request the manager to start the actual capture. | 842 // Request the manager to start the actual capture. |
| 842 video_capture_manager_->Start(current_params_, this); | 843 video_capture_manager_->Start(current_params_, this); |
| 843 state_ = VIDEO_CAPTURE_STATE_STARTED; | 844 state_ = VIDEO_CAPTURE_STATE_STARTED; |
| 844 device_in_use_ = true; | 845 device_in_use_ = true; |
| 845 } | 846 } |
| 846 | 847 |
| 847 } // namespace content | 848 } // namespace content |
| OLD | NEW |