Chromium Code Reviews| Index: content/browser/renderer_host/media/video_capture_device_client.cc |
| diff --git a/content/browser/renderer_host/media/video_capture_device_client.cc b/content/browser/renderer_host/media/video_capture_device_client.cc |
| index e9900a5810f57cd2567a369ea3e00bf547e0f5ac..5ed4046fd1bd44551ec2abb41e34c93ff949fe75 100644 |
| --- a/content/browser/renderer_host/media/video_capture_device_client.cc |
| +++ b/content/browser/renderer_host/media/video_capture_device_client.cc |
| @@ -73,21 +73,12 @@ void VideoCaptureDeviceClient::OnIncomingCapturedData( |
| if (!frame_format.IsValid()) |
| return; |
| - // Chopped pixels in width/height in case video capture device has odd |
| - // numbers for width/height. |
| - int chopped_width = 0; |
| - int chopped_height = 0; |
| - int new_unrotated_width = frame_format.frame_size.width(); |
| - int new_unrotated_height = frame_format.frame_size.height(); |
| - |
| - if (new_unrotated_width & 1) { |
| - --new_unrotated_width; |
| - chopped_width = 1; |
| - } |
| - if (new_unrotated_height & 1) { |
| - --new_unrotated_height; |
| - chopped_height = 1; |
| - } |
| + // |chopped_{width,height} and |new_unrotated_{width,height}| are the lowest |
| + // bit decomposition of {width, height}, grabbing the odd and even parts. |
| + const int chopped_width = frame_format.frame_size.width() & 1; |
| + const int chopped_height = frame_format.frame_size.height() & 1; |
| + const int new_unrotated_width = frame_format.frame_size.width() & ~1; |
| + const int new_unrotated_height = frame_format.frame_size.height() & ~1; |
| int destination_width = new_unrotated_width; |
| int destination_height = new_unrotated_height; |
| @@ -95,6 +86,17 @@ void VideoCaptureDeviceClient::OnIncomingCapturedData( |
| destination_width = new_unrotated_height; |
| destination_height = new_unrotated_width; |
| } |
| + |
| + DLOG_IF(WARNING, (rotation % 90)) |
|
perkj_chrome
2015/03/19 20:38:17
nit: dcheck this
mcasas
2015/03/19 22:57:00
Done.
|
| + << " Rotation must be a multiple of 90 and is " << rotation; |
| + libyuv::RotationMode rotation_mode = libyuv::kRotate0; |
| + if (rotation == 90) |
| + rotation_mode = libyuv::kRotate90; |
| + else if (rotation == 180) |
| + rotation_mode = libyuv::kRotate180; |
| + else if (rotation == 270) |
| + rotation_mode = libyuv::kRotate270; |
| + |
| const gfx::Size dimensions(destination_width, destination_height); |
| if (!VideoFrame::IsValidConfig(VideoFrame::I420, |
| dimensions, |
| @@ -121,14 +123,6 @@ void VideoCaptureDeviceClient::OnIncomingCapturedData( |
| int crop_y = 0; |
| libyuv::FourCC origin_colorspace = libyuv::FOURCC_ANY; |
| - libyuv::RotationMode rotation_mode = libyuv::kRotate0; |
| - if (rotation == 90) |
| - rotation_mode = libyuv::kRotate90; |
| - else if (rotation == 180) |
| - rotation_mode = libyuv::kRotate180; |
| - else if (rotation == 270) |
| - rotation_mode = libyuv::kRotate270; |
| - |
| bool flip = false; |
| switch (frame_format.pixel_format) { |
| case media::PIXEL_FORMAT_UNKNOWN: // Color format not set. |
| @@ -229,6 +223,71 @@ void VideoCaptureDeviceClient::OnIncomingCapturedData( |
| timestamp)); |
| } |
| +void |
| +VideoCaptureDeviceClient::OnIncomingCapturedYuvData( |
| + const uint8* y_data, |
| + const uint8* u_data, |
| + const uint8* v_data, |
| + int y_length, |
| + int u_length, |
| + int v_length, |
| + const VideoCaptureFormat& frame_format, |
| + int clockwise_rotation, |
| + const base::TimeTicks& timestamp) { |
| + TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedYuvData"); |
| + DCHECK_EQ(frame_format.pixel_format, media::PIXEL_FORMAT_I420); |
| + DCHECK_EQ(clockwise_rotation, 0) << "Rotation not supported"; |
| + DCHECK_GE(static_cast<size_t>(y_length + u_length + v_length), |
| + frame_format.ImageAllocationSize()); |
| + |
| + scoped_refptr<Buffer> buffer = ReserveOutputBuffer(VideoFrame::I420, |
| + frame_format.frame_size); |
| + if (!buffer.get()) |
| + return; |
| + |
| + // Blit (copy) here from y,u,v into buffer.data()). Needed so we can return |
| + // the parameter buffer synchronously to the driver. |
| + const size_t y_stride = y_length / frame_format.frame_size.height(); |
| + const size_t u_stride = u_length / frame_format.frame_size.height() / 2; |
|
magjed_chromium
2015/03/19 18:13:29
You need parenthesis around height() / 2, now it's
perkj_chrome
2015/03/19 20:38:17
Why dont you have y_stride u_stride etc as input p
mcasas
2015/03/19 22:57:00
Done.
mcasas
2015/03/19 22:57:00
Done.
|
| + const size_t v_stride = v_length / frame_format.frame_size.height() / 2; |
| + const size_t y_plane_size = VideoFrame::PlaneAllocationSize(VideoFrame::I420, |
| + VideoFrame::kYPlane, frame_format.frame_size); |
| + const size_t u_plane_size = VideoFrame::PlaneAllocationSize(VideoFrame::I420, |
| + VideoFrame::kUPlane, frame_format.frame_size); |
| + uint8* const dst_y = reinterpret_cast<uint8*>(buffer->data()); |
| + uint8* const dst_u = dst_y + y_plane_size; |
| + uint8* const dst_v = dst_u + u_plane_size; |
| + |
| + if (libyuv::I420Copy(y_data, y_stride, |
|
perkj_chrome
2015/03/19 20:38:17
So actually holding the buffer in the driver did n
mcasas
2015/03/19 22:57:00
After much discussion with posciak@ we decided not
|
| + u_data, u_stride, |
| + v_data, v_stride, |
| + dst_y, y_stride, |
| + dst_u, u_stride, |
| + dst_v, v_stride, |
| + frame_format.frame_size.width(), |
| + frame_format.frame_size.height())) { |
| + DLOG(WARNING) << "Failed to copy buffer"; |
| + return; |
| + } |
| + |
| + scoped_refptr<VideoFrame> video_frame = VideoFrame::WrapExternalYuvData( |
| + VideoFrame::I420, frame_format.frame_size, |
| + gfx::Rect(frame_format.frame_size), frame_format.frame_size, y_stride, |
| + u_stride, v_stride, dst_y, dst_u, dst_v, base::TimeDelta(), |
| + base::Closure()); |
| + DCHECK(video_frame.get()); |
| + |
| + BrowserThread::PostTask( |
| + BrowserThread::IO, |
| + FROM_HERE, |
| + base::Bind( |
| + &VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread, |
| + controller_, |
| + buffer, |
| + video_frame, |
| + timestamp)); |
| +}; |
| + |
| scoped_refptr<media::VideoCaptureDevice::Client::Buffer> |
| VideoCaptureDeviceClient::ReserveOutputBuffer(VideoFrame::Format format, |
| const gfx::Size& dimensions) { |