Chromium Code Reviews| Index: webrtc/common_video/video_frame_buffer.cc |
| diff --git a/webrtc/common_video/video_frame_buffer.cc b/webrtc/common_video/video_frame_buffer.cc |
| index 700dcaf02b7af098798eb51e344f065b232a8700..19b2bc25441b4d724265f73a9bf09e67933d9e2a 100644 |
| --- a/webrtc/common_video/video_frame_buffer.cc |
| +++ b/webrtc/common_video/video_frame_buffer.cc |
| @@ -13,6 +13,7 @@ |
| #include "webrtc/base/checks.h" |
| #include "webrtc/base/keep_ref_until_done.h" |
| #include "libyuv/convert.h" |
| +#include "libyuv/scale.h" |
| // Aligning pointer to 64 bytes for improved performance, e.g. use SIMD. |
| static const int kBufferAlignment = 64; |
| @@ -207,6 +208,56 @@ rtc::scoped_refptr<I420Buffer> I420Buffer::Copy( |
| return copy; |
| } |
| +rtc::scoped_refptr<I420Buffer> I420Buffer::CropAndScale( |
| + const rtc::scoped_refptr<VideoFrameBuffer>& buffer, |
| + int offset_x, |
| + int offset_y, |
| + int crop_width, |
| + int crop_height, |
| + int dst_width, |
| + int dst_height) { |
| + RTC_CHECK_LE(crop_width, buffer->width()); |
| + RTC_CHECK_LE(crop_height, buffer->height()); |
| + RTC_CHECK_LE(crop_width + offset_x, buffer->width()); |
| + RTC_CHECK_LE(crop_height + offset_y, buffer->height()); |
| + |
| + rtc::scoped_refptr<I420Buffer> scaled = |
| + new rtc::RefCountedObject<I420Buffer>(dst_width, dst_height); |
| + |
| + // Make sure offset is even so that u/v plane becomes aligned. |
| + // TODO(nisse): Duplicated in ShallowCrop. |
|
perkj_webrtc
2016/05/16 06:48:47
remove this todo. I am fine with this duplication.
|
| + const int uv_offset_x = offset_x / 2; |
| + const int uv_offset_y = offset_y / 2; |
| + offset_x = uv_offset_x * 2; |
| + offset_y = uv_offset_y * 2; |
| + |
| + const uint8_t* y_plane = buffer->DataY() + |
| + buffer->StrideY() * offset_y + offset_x; |
| + const uint8_t* u_plane = buffer->DataU() + |
| + buffer->StrideU() * uv_offset_y + uv_offset_x; |
| + const uint8_t* v_plane = buffer->DataV() + |
| + buffer->StrideV() * uv_offset_y + uv_offset_x; |
| + if (libyuv::I420Scale(y_plane, buffer->StrideY(), |
| + u_plane, buffer->StrideU(), |
| + v_plane, buffer->StrideV(), |
| + crop_width, crop_height, |
| + scaled->MutableDataY(), scaled->StrideY(), |
| + scaled->MutableDataU(), scaled->StrideU(), |
| + scaled->MutableDataV(), scaled->StrideV(), |
| + dst_width, dst_height, libyuv::kFilterBox) < 0) { |
| + return nullptr; |
| + } |
| + return scaled; |
| +} |
| + |
| +rtc::scoped_refptr<I420Buffer> I420Buffer::Scale( |
| + const rtc::scoped_refptr<VideoFrameBuffer>& buffer, |
| + int dst_width, |
| + int dst_height) { |
| + return CropAndScale(buffer, 0, 0, buffer->width(), buffer->height(), |
| + dst_width, dst_height); |
| +} |
| + |
| NativeHandleBuffer::NativeHandleBuffer(void* native_handle, |
| int width, |
| int height) |
| @@ -324,22 +375,21 @@ rtc::scoped_refptr<VideoFrameBuffer> WrappedI420Buffer::NativeToI420Buffer() { |
| return nullptr; |
| } |
| -rtc::scoped_refptr<VideoFrameBuffer> ShallowCenterCrop( |
| +rtc::scoped_refptr<WrappedI420Buffer> WrappedI420Buffer::ShallowCrop( |
| const rtc::scoped_refptr<VideoFrameBuffer>& buffer, |
| + int offset_x, |
| + int offset_y, |
| int cropped_width, |
| int cropped_height) { |
| RTC_CHECK(buffer->native_handle() == nullptr); |
| RTC_CHECK_LE(cropped_width, buffer->width()); |
| RTC_CHECK_LE(cropped_height, buffer->height()); |
| - if (buffer->width() == cropped_width && buffer->height() == cropped_height) |
| - return buffer; |
| - // Center crop to |cropped_width| x |cropped_height|. |
| // Make sure offset is even so that u/v plane becomes aligned. |
| - const int uv_offset_x = (buffer->width() - cropped_width) / 4; |
| - const int uv_offset_y = (buffer->height() - cropped_height) / 4; |
| - const int offset_x = uv_offset_x * 2; |
| - const int offset_y = uv_offset_y * 2; |
| + const int uv_offset_x = offset_x / 2; |
| + const int uv_offset_y = offset_y / 2; |
| + offset_x = uv_offset_x * 2; |
| + offset_y = uv_offset_y * 2; |
| const uint8_t* y_plane = buffer->DataY() + |
| buffer->StrideY() * offset_y + offset_x; |
| @@ -355,4 +405,18 @@ rtc::scoped_refptr<VideoFrameBuffer> ShallowCenterCrop( |
| rtc::KeepRefUntilDone(buffer)); |
| } |
| +// TODO(nisse): Used only by |
| +// AndroidVideoCapturer::FrameFactory::CreateAliasedFrame. Delete when |
| +// the CreateAliasedFrame method is removed. |
| +rtc::scoped_refptr<VideoFrameBuffer> ShallowCenterCrop( |
| + const rtc::scoped_refptr<VideoFrameBuffer>& buffer, |
| + int cropped_width, |
| + int cropped_height) { |
| + return WrappedI420Buffer::ShallowCrop( |
| + buffer, |
| + (buffer->width() - cropped_width) / 2, |
| + (buffer->height() - cropped_height) / 2, |
| + cropped_width, cropped_height); |
| +} |
| + |
| } // namespace webrtc |