aboutsummaryrefslogtreecommitdiff
path: root/source/scale.cc
diff options
context:
space:
mode:
authorFrank Barchard <fbarchard@google.com>2020-09-28 12:41:52 -0700
committerCommit Bot <commit-bot@chromium.org>2020-09-28 20:13:21 +0000
commit7a52fde1c4eb00790bd647b50842797daa5222e6 (patch)
tree6f7c07526562863a0ff2d0b2d76421d762f7868b /source/scale.cc
parentd6833cda383bace2c98190fe0df504609c9ae074 (diff)
downloadlibyuv-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.cc65
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,