| 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..7f847bbe7df661765b35cd2d8dafc530f6d820e0 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,133 @@ 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();
|
| + }
|
| +
|
| + int need_convert_rgb24_on_win = false;
|
| +#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.
|
| + if (frame_info_.color == media::VideoCaptureCapability::kRGB24) {
|
| + // Rotation and flipping is not supported in kRGB24 and OS_WIN case.
|
| + DCHECK(!rotation && !flip_vert && !flip_horiz);
|
| + need_convert_rgb24_on_win = true;
|
| + }
|
| +#endif
|
| + if (need_convert_rgb24_on_win) {
|
| + 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 {
|
| + 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 +445,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 +464,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 +473,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(
|
|
|