Chromium Code Reviews| Index: content/browser/renderer_host/media/video_capture_controller.cc |
| diff --git a/content/browser/renderer_host/media/video_capture_controller.cc b/content/browser/renderer_host/media/video_capture_controller.cc |
| index a9c11a6291c9c3bf17a5aa3162627746b3eb4c6f..ed3a2f3b4ab98756bfe7bb68b5d50179bb4ee951 100644 |
| --- a/content/browser/renderer_host/media/video_capture_controller.cc |
| +++ b/content/browser/renderer_host/media/video_capture_controller.cc |
| @@ -23,6 +23,7 @@ |
| namespace { |
| +#if defined(OS_IOS) || defined(OS_ANDROID) |
| // TODO(wjia): Support stride. |
| void RotatePackedYV12Frame( |
| const uint8* src, |
| @@ -44,6 +45,7 @@ void RotatePackedYV12Frame( |
| media::RotatePlaneByPixels( |
| src, dest_vplane, width/2, height/2, rotation, flip_vert, flip_horiz); |
| } |
| +#endif // #if defined(OS_IOS) || defined(OS_ANDROID) |
| } // namespace |
| @@ -258,6 +260,130 @@ scoped_refptr<media::VideoFrame> VideoCaptureController::ReserveOutputBuffer() { |
| // Implements VideoCaptureDevice::EventHandler. |
| // OnIncomingCapturedFrame is called the thread running the capture device. |
| // I.e.- DirectShow thread on windows and v4l2_thread on Linux. |
| +#if !defined(OS_IOS) && !defined(OS_ANDROID) |
| +void VideoCaptureController::OnIncomingCapturedFrame( |
| + const uint8* data, |
| + int length, |
| + base::Time timestamp, |
| + int rotation, |
| + bool flip_vert, |
| + bool flip_horiz) { |
| + TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame"); |
| + |
| + scoped_refptr<media::VideoFrame> dst; |
| + { |
| + base::AutoLock lock(buffer_pool_lock_); |
| + if (!buffer_pool_.get()) |
| + return; |
| + dst = buffer_pool_->ReserveI420VideoFrame( |
| + gfx::Size(frame_info_.width, frame_info_.height), rotation); |
| + } |
| + |
| + if (!dst.get()) |
| + return; |
| + |
| + uint8* yplane = dst->data(media::VideoFrame::kYPlane); |
| + uint8* uplane = dst->data(media::VideoFrame::kUPlane); |
| + uint8* vplane = dst->data(media::VideoFrame::kVPlane); |
| + int yplane_stride = frame_info_.width; |
| + int uv_plane_stride = (frame_info_.width + 1) / 2; |
| + int crop_x = 0; |
| + int crop_y = 0; |
| + libyuv::FourCC origin_colorspace = libyuv::FOURCC_ANY; |
| + // Assuming rotation happens first and flips next, we can consolidate both |
| + // vertical and horizontal flips together with rotation into two variables: |
| + // new_rotation = (rotation + 180 * vertical_flip) modulo 360 |
| + // new_vertical_flip = horizontal_flip XOR vertical_flip |
| + int new_rotation_angle = (rotation + 180 * flip_vert) % 360; |
| + libyuv::RotationMode rotation_mode = libyuv::kRotate0; |
| + if (new_rotation_angle == 90) |
| + rotation_mode = libyuv::kRotate90; |
| + else if (new_rotation_angle == 180) |
| + rotation_mode = libyuv::kRotate180; |
| + else if (new_rotation_angle == 270) |
| + rotation_mode = libyuv::kRotate270; |
| + |
| + switch (frame_info_.color) { |
| + case media::VideoCaptureCapability::kColorUnknown: // Color format not set. |
| + break; |
| + case media::VideoCaptureCapability::kI420: |
| + DCHECK(!chopped_width_ && !chopped_height_); |
| + origin_colorspace = libyuv::FOURCC_I420; |
| + break; |
| + case media::VideoCaptureCapability::kYV12: |
| + DCHECK(!chopped_width_ && !chopped_height_); |
| + origin_colorspace = libyuv::FOURCC_YV12; |
| + break; |
| + case media::VideoCaptureCapability::kNV21: |
| + DCHECK(!chopped_width_ && !chopped_height_); |
| + origin_colorspace = libyuv::FOURCC_NV12; |
| + break; |
| + case media::VideoCaptureCapability::kYUY2: |
| + DCHECK(!chopped_width_ && !chopped_height_); |
| + origin_colorspace = libyuv::FOURCC_YUY2; |
| + break; |
| + case media::VideoCaptureCapability::kRGB24: |
| + origin_colorspace = libyuv::FOURCC_RAW; |
| + break; |
| + case media::VideoCaptureCapability::kARGB: |
| + origin_colorspace = libyuv::FOURCC_ARGB; |
| + break; |
| + case media::VideoCaptureCapability::kMJPEG: |
| + origin_colorspace = libyuv::FOURCC_MJPG; |
| + break; |
| + default: |
| + NOTREACHED(); |
| + } |
| +#if defined(OS_WIN) |
| + // kRGB24 on Windows start at the bottom line and has a negative stride. This |
| + // is not supported by libyuv, so the media API is used instead. |
| + // Rotation and flipping is not supported in this case. |
| + if (frame_info_.color == media::VideoCaptureCapability::kRGB24) { |
| + int rgb_stride = -3 * (frame_info_.width + chopped_width_); |
| + const uint8* rgb_src = |
| + data + 3 * (frame_info_.width + chopped_width_) * |
| + (frame_info_.height - 1 + chopped_height_); |
| + media::ConvertRGB24ToYUV(rgb_src, |
| + yplane, |
| + uplane, |
| + vplane, |
| + frame_info_.width, |
| + frame_info_.height, |
| + rgb_stride, |
| + yplane_stride, |
| + uv_plane_stride); |
| + } |
| +#else |
| + if (false) {} |
| +#endif |
| + else { |
|
wjia(left Chromium)
2013/09/06 17:27:36
"if (false)" looks a bit weird. How about the foll
mcasas
2013/09/06 17:46:42
Yes I also thought about adding a flag for this pa
|
| + libyuv::ConvertToI420( |
| + data, |
| + length, |
| + yplane, |
| + yplane_stride, |
| + uplane, |
| + uv_plane_stride, |
| + vplane, |
| + uv_plane_stride, |
| + crop_x, |
| + crop_y, |
| + frame_info_.width, |
| + frame_info_.height * (flip_vert ^ flip_horiz ? -1 : 1), |
| + frame_info_.width, |
| + frame_info_.height, |
| + rotation_mode, |
| + origin_colorspace); |
| + } |
| + BrowserThread::PostTask( |
| + BrowserThread::IO, |
| + FROM_HERE, |
| + base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread, |
| + this, |
| + dst, |
| + timestamp)); |
| +} |
| +#else |
| void VideoCaptureController::OnIncomingCapturedFrame( |
| const uint8* data, |
| int length, |
| @@ -316,21 +442,14 @@ void VideoCaptureController::OnIncomingCapturedFrame( |
| // we can't convert the frame to I420. YUY2 is 2 bytes per pixel. |
| break; |
| } |
| - |
| media::ConvertYUY2ToYUV(data, yplane, uplane, vplane, frame_info_.width, |
| frame_info_.height); |
| break; |
| case media::VideoCaptureCapability::kRGB24: { |
| int ystride = frame_info_.width; |
| int uvstride = frame_info_.width / 2; |
| -#if defined(OS_WIN) // RGB on Windows start at the bottom line. |
| - int rgb_stride = -3 * (frame_info_.width + chopped_width_); |
| - const uint8* rgb_src = data + 3 * (frame_info_.width + chopped_width_) * |
| - (frame_info_.height -1 + chopped_height_); |
| -#else |
| int rgb_stride = 3 * (frame_info_.width + chopped_width_); |
| const uint8* rgb_src = data; |
| -#endif |
| media::ConvertRGB24ToYUV(rgb_src, yplane, uplane, vplane, |
| frame_info_.width, frame_info_.height, |
| rgb_stride, ystride, uvstride); |
| @@ -342,20 +461,6 @@ void VideoCaptureController::OnIncomingCapturedFrame( |
| (frame_info_.width + chopped_width_) * 4, |
| frame_info_.width, frame_info_.width / 2); |
| break; |
| -#if !defined(OS_IOS) && !defined(OS_ANDROID) |
| - case media::VideoCaptureCapability::kMJPEG: { |
| - int yplane_stride = frame_info_.width; |
| - int uv_plane_stride = (frame_info_.width + 1) / 2; |
| - int crop_x = 0; |
| - int crop_y = 0; |
| - libyuv::ConvertToI420(data, length, yplane, yplane_stride, uplane, |
| - uv_plane_stride, vplane, uv_plane_stride, crop_x, |
| - crop_y, frame_info_.width, frame_info_.height, |
| - frame_info_.width, frame_info_.height, |
| - libyuv::kRotate0, libyuv::FOURCC_MJPG); |
| - break; |
| - } |
| -#endif |
| default: |
| NOTREACHED(); |
| } |
| @@ -365,6 +470,7 @@ void VideoCaptureController::OnIncomingCapturedFrame( |
| base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread, |
| this, dst, timestamp)); |
| } |
| +#endif // #if !defined(OS_IOS) && !defined(OS_ANDROID) |
| // OnIncomingCapturedVideoFrame is called the thread running the capture device. |
| void VideoCaptureController::OnIncomingCapturedVideoFrame( |