diff options
author | Frank Barchard <fbarchard@google.com> | 2020-09-28 12:41:52 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-09-28 20:13:21 +0000 |
commit | 7a52fde1c4eb00790bd647b50842797daa5222e6 (patch) | |
tree | 6f7c07526562863a0ff2d0b2d76421d762f7868b /source/scale.cc | |
parent | d6833cda383bace2c98190fe0df504609c9ae074 (diff) | |
download | libyuv-7a52fde1c4eb00790bd647b50842797daa5222e6.tar.gz |
NV12Scale function using split/merge on UV channal
Bug: libyuv:718, libyuv:838, b/168918847
Change-Id: I78b27baac50f0ce955e00cb6aaf7dfe5a0cb1e3d
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/2432067
Commit-Queue: Frank Barchard <fbarchard@chromium.org>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Diffstat (limited to 'source/scale.cc')
-rw-r--r-- | source/scale.cc | 65 |
1 files changed, 64 insertions, 1 deletions
diff --git a/source/scale.cc b/source/scale.cc index b17920a6..d26bfec7 100644 --- a/source/scale.cc +++ b/source/scale.cc @@ -1670,7 +1670,7 @@ void ScalePlane_16(const uint16_t* src, } if (dst_width == src_width && filtering != kFilterBox) { int dy = FixedDiv(src_height, dst_height); - // Arbitrary scale vertically, but unscaled vertically. + // Arbitrary scale vertically, but unscaled horizontally. ScalePlaneVertical_16(src_height, dst_width, dst_height, src_stride, dst_stride, src, dst, 0, 0, dy, 1, filtering); return; @@ -1869,6 +1869,69 @@ int I444Scale_16(const uint16_t* src_y, return 0; } +// Scale an NV12 image. +// This function in turn calls a scaling function for each plane. + +// TODO(https://bugs.chromium.org/p/libyuv/issues/detail?id=838): Remove +// this once libyuv implements NV12Scale and use the libyuv::NV12Scale(). +// This is copy-pasted from +// webrtc/common_video/libyuv/include/webrtc_libyuv.h +int NV12Scale(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_uv, + int src_stride_uv, + int src_width, + int src_height, + uint8_t* dst_y, + int dst_stride_y, + uint8_t* dst_uv, + int dst_stride_uv, + int dst_width, + int dst_height, + enum FilterMode filtering) { + const int src_chroma_width = (src_width + 1) / 2; + const int src_chroma_height = (src_height + 1) / 2; + + if (src_width == dst_width && src_height == dst_height) { + // No scaling. + libyuv::CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, src_width, + src_height); + libyuv::CopyPlane(src_uv, src_stride_uv, dst_uv, dst_stride_uv, + src_chroma_width * 2, src_chroma_height); + return 0; + } + + // Scaling. + // Allocate temporary memory for spitting UV planes and scaling them. + const int dst_chroma_width = (dst_width + 1) / 2; + const int dst_chroma_height = (dst_height + 1) / 2; + + align_buffer_64(tmp_buffer, + src_chroma_width * src_chroma_height * 2 + + dst_chroma_width * dst_chroma_height * 2); + + uint8_t* const src_u = tmp_buffer; + uint8_t* const src_v = src_u + src_chroma_width * src_chroma_height; + uint8_t* const dst_u = src_v + src_chroma_width * src_chroma_height; + uint8_t* const dst_v = dst_u + dst_chroma_width * dst_chroma_height; + + // Split source UV plane into separate U and V plane using the temporary data. + libyuv::SplitUVPlane(src_uv, src_stride_uv, src_u, src_chroma_width, src_v, + src_chroma_width, src_chroma_width, src_chroma_height); + + // Scale the planes. + libyuv::I420Scale( + src_y, src_stride_y, src_u, src_chroma_width, src_v, src_chroma_width, + src_width, src_height, dst_y, dst_stride_y, dst_u, dst_chroma_width, + dst_v, dst_chroma_width, dst_width, dst_height, filtering); + + // Merge the UV planes into the destination. + libyuv::MergeUVPlane(dst_u, dst_chroma_width, dst_v, dst_chroma_width, dst_uv, + dst_stride_uv, dst_chroma_width, dst_chroma_height); + free_aligned_buffer_64(tmp_buffer); + return 0; +} + // Deprecated api LIBYUV_API int Scale(const uint8_t* src_y, |