aboutsummaryrefslogtreecommitdiff
path: root/source/planar_functions.cc
diff options
context:
space:
mode:
authorFrank Barchard <fbarchard@google.com>2022-08-16 10:22:05 -0700
committerFrank Barchard <fbarchard@chromium.org>2022-08-16 22:07:38 +0000
commit65e7c9d5706a77d1949da59bfcb0817c252ef8d6 (patch)
tree3cb55897ef7833792f07952fbf76b43606197c00 /source/planar_functions.cc
parent1c5a8bb17ac4092da557e55cf519bf4df105d8f1 (diff)
downloadlibyuv-65e7c9d5706a77d1949da59bfcb0817c252ef8d6.tar.gz
MM21ToYUY2 and ABGRToJ420 conversion
MM21 to YUY2 use zip1 for performance Cortex A510 Was MM21ToYUY2 (612 ms) Now MM21ToYUY2 (573 ms) Prefetches help Cortex A53 Was MM21ToYUY2 (4998 ms) Now MM21ToYUY2 (1900 ms) Pixel 4 Cortex A76 Was MM21ToYUY2 (215 ms) Now MM21ToYUY2 (173 ms) ABGRToJ420 - NEON, SSSE3 and AVX2 row functions - J400, J420 and J422 formats. - Added AVX2 for UV on ARGBToJ420. Was SSSE3 Same code/performance as ARGBToJ420 but with constants re-ordered. Pixel 4 ABGRToJ420_Opt (623 ms) ABGRToJ422_Opt (702 ms) ABGRToJ400_Opt (238 ms) Skylake Xeon With LIBYUV_BIT_EXACT which uses C for UV ABGRToJ420_Opt (988 ms) ABGRToJ422_Opt (1872 ms) ABGRToJ400_Opt (186 ms) Skylake Xeon using AVX2 ABGRToJ420_Opt (251 ms) ABGRToJ422_Opt (245 ms) ABGRToJ400_Opt (184 ms) Skylake Xeon using SSSE3 ABGRToJ420_Opt (328 ms) ABGRToJ422_Opt (362 ms) ABGRToJ400_Opt (185 ms) Bug: b/238137982 Change-Id: I559c3fe3fb80fa2ce5be3d8218736f9cbc627666 Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/3832111 Reviewed-by: Justin Green <greenjustin@google.com> Reviewed-by: Wan-Teh Chang <wtc@google.com> Reviewed-by: Frank Barchard <fbarchard@chromium.org>
Diffstat (limited to 'source/planar_functions.cc')
-rw-r--r--source/planar_functions.cc62
1 files changed, 61 insertions, 1 deletions
diff --git a/source/planar_functions.cc b/source/planar_functions.cc
index 169d4a8f..fae8630e 100644
--- a/source/planar_functions.cc
+++ b/source/planar_functions.cc
@@ -915,7 +915,7 @@ int NV21ToNV12(const uint8_t* src_y,
// tile width is 16 and assumed.
// tile_height is 16 or 32 for MM21.
// src_stride_y is bytes per row of source ignoring tiling. e.g. 640
-// TODO: More detile row functions.
+// TODO(fbarchard): More detile row functions.
LIBYUV_API
void DetilePlane(const uint8_t* src_y,
@@ -1033,6 +1033,66 @@ void DetileSplitUVPlane(const uint8_t* src_uv,
}
}
+LIBYUV_API
+void DetileToYUY2(const uint8_t* src_y,
+ int src_stride_y,
+ const uint8_t* src_uv,
+ int src_stride_uv,
+ uint8_t* dst_yuy2,
+ int dst_stride_yuy2,
+ int width,
+ int height,
+ int tile_height) {
+ const ptrdiff_t src_y_tile_stride = 16 * tile_height;
+ const ptrdiff_t src_uv_tile_stride = src_y_tile_stride / 2;
+ int y;
+ void (*DetileToYUY2)(const uint8_t* src_y, ptrdiff_t src_y_tile_stride,
+ const uint8_t* src_uv, ptrdiff_t src_uv_tile_stride,
+ uint8_t* dst_yuy2, int width) = DetileToYUY2_C;
+ assert(src_stride_y >= 0);
+ assert(src_stride_y > 0);
+ assert(src_stride_uv >= 0);
+ assert(src_stride_uv > 0);
+ assert(tile_height > 0);
+
+ if (width <= 0 || height == 0 || tile_height <= 0) {
+ return;
+ }
+ // Negative height means invert the image.
+ if (height < 0) {
+ height = -height;
+ dst_yuy2 = dst_yuy2 + (height - 1) * dst_stride_yuy2;
+ dst_stride_yuy2 = -dst_stride_yuy2;
+ }
+
+#if defined(HAS_DETILETOYUY2_NEON)
+ if (TestCpuFlag(kCpuHasNEON)) {
+ DetileToYUY2 = DetileToYUY2_Any_NEON;
+ if (IS_ALIGNED(width, 16)) {
+ DetileToYUY2 = DetileToYUY2_NEON;
+ }
+ }
+#endif
+
+ // Detile plane
+ for (y = 0; y < height; ++y) {
+ DetileToYUY2(src_y, src_y_tile_stride, src_uv, src_uv_tile_stride,
+ dst_yuy2, width);
+ dst_yuy2 += dst_stride_yuy2;
+ src_y += 16;
+
+ if (y & 0x1) {
+ src_uv += 16;
+ }
+
+ // Advance to next row of tiles.
+ if ((y & (tile_height - 1)) == (tile_height - 1)) {
+ src_y = src_y - src_y_tile_stride + src_stride_y * tile_height;
+ src_uv = src_uv - src_uv_tile_stride + src_stride_uv * (tile_height / 2);
+ }
+ }
+}
+
// Support function for NV12 etc RGB channels.
// Width and height are plane sizes (typically half pixel width).
LIBYUV_API