[FFmpeg-devel] [PATCH] swscale/swscale_unscaled: add unscaled conversion for AYUV/VUYA/UYVA

James Almer jamrial at gmail.com
Tue Oct 29 21:15:55 EET 2024


Signed-off-by: James Almer <jamrial at gmail.com>
---
 libswscale/rgb2rgb.c          |  4 ++++
 libswscale/rgb2rgb.h          |  4 ++++
 libswscale/rgb2rgb_template.c |  8 ++++++++
 libswscale/swscale_unscaled.c | 21 +++++++++++++++++++++
 4 files changed, 37 insertions(+)

diff --git a/libswscale/rgb2rgb.c b/libswscale/rgb2rgb.c
index 2750a29cea..199afe989b 100644
--- a/libswscale/rgb2rgb.c
+++ b/libswscale/rgb2rgb.c
@@ -56,6 +56,10 @@ void (*shuffle_bytes_2103)(const uint8_t *src, uint8_t *dst, int src_size);
 void (*shuffle_bytes_1230)(const uint8_t *src, uint8_t *dst, int src_size);
 void (*shuffle_bytes_3012)(const uint8_t *src, uint8_t *dst, int src_size);
 void (*shuffle_bytes_3210)(const uint8_t *src, uint8_t *dst, int src_size);
+void (*shuffle_bytes_3102)(const uint8_t *src, uint8_t *dst, int src_size);
+void (*shuffle_bytes_2013)(const uint8_t *src, uint8_t *dst, int src_size);
+void (*shuffle_bytes_2130)(const uint8_t *src, uint8_t *dst, int src_size);
+void (*shuffle_bytes_1203)(const uint8_t *src, uint8_t *dst, int src_size);
 
 
 void (*yv12toyuy2)(const uint8_t *ysrc, const uint8_t *usrc,
diff --git a/libswscale/rgb2rgb.h b/libswscale/rgb2rgb.h
index e4af7c7b6e..c988e65256 100644
--- a/libswscale/rgb2rgb.h
+++ b/libswscale/rgb2rgb.h
@@ -52,6 +52,10 @@ extern void (*shuffle_bytes_2103)(const uint8_t *src, uint8_t *dst, int src_size
 extern void (*shuffle_bytes_1230)(const uint8_t *src, uint8_t *dst, int src_size);
 extern void (*shuffle_bytes_3012)(const uint8_t *src, uint8_t *dst, int src_size);
 extern void (*shuffle_bytes_3210)(const uint8_t *src, uint8_t *dst, int src_size);
+extern void (*shuffle_bytes_3102)(const uint8_t *src, uint8_t *dst, int src_size);
+extern void (*shuffle_bytes_2013)(const uint8_t *src, uint8_t *dst, int src_size);
+extern void (*shuffle_bytes_2130)(const uint8_t *src, uint8_t *dst, int src_size);
+extern void (*shuffle_bytes_1203)(const uint8_t *src, uint8_t *dst, int src_size);
 
 void rgb64tobgr48_nobswap(const uint8_t *src, uint8_t *dst, int src_size);
 void   rgb64tobgr48_bswap(const uint8_t *src, uint8_t *dst, int src_size);
diff --git a/libswscale/rgb2rgb_template.c b/libswscale/rgb2rgb_template.c
index 84b9da0911..47a1bb8368 100644
--- a/libswscale/rgb2rgb_template.c
+++ b/libswscale/rgb2rgb_template.c
@@ -359,6 +359,10 @@ static void shuffle_bytes_##name (const uint8_t *src,                   \
 DEFINE_SHUFFLE_BYTES(1230_c, 1, 2, 3, 0)
 DEFINE_SHUFFLE_BYTES(3012_c, 3, 0, 1, 2)
 DEFINE_SHUFFLE_BYTES(3210_c, 3, 2, 1, 0)
+DEFINE_SHUFFLE_BYTES(3102_c, 3, 1, 0, 2)
+DEFINE_SHUFFLE_BYTES(2013_c, 2, 0, 1, 3)
+DEFINE_SHUFFLE_BYTES(2130_c, 2, 1, 3, 0)
+DEFINE_SHUFFLE_BYTES(1203_c, 1, 2, 0, 3)
 
 static inline void rgb24tobgr24_c(const uint8_t *src, uint8_t *dst, int src_size)
 {
@@ -970,6 +974,10 @@ static av_cold void rgb2rgb_init_c(void)
     shuffle_bytes_1230 = shuffle_bytes_1230_c;
     shuffle_bytes_3012 = shuffle_bytes_3012_c;
     shuffle_bytes_3210 = shuffle_bytes_3210_c;
+    shuffle_bytes_3102 = shuffle_bytes_3102_c;
+    shuffle_bytes_2013 = shuffle_bytes_2013_c;
+    shuffle_bytes_2130 = shuffle_bytes_2130_c;
+    shuffle_bytes_1203 = shuffle_bytes_1203_c;
     rgb32tobgr16       = rgb32tobgr16_c;
     rgb32tobgr15       = rgb32tobgr15_c;
     yv12toyuy2         = yv12toyuy2_c;
diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c
index a1930b9132..a53f6bc0c3 100644
--- a/libswscale/swscale_unscaled.c
+++ b/libswscale/swscale_unscaled.c
@@ -1497,6 +1497,13 @@ static int bayer_to_yv12_wrapper(SwsInternal *c, const uint8_t *const src[],
         || (x) == AV_PIX_FMT_BGR48BE   \
         )
 
+#define isAYUV(x) (                 \
+           (x) == AV_PIX_FMT_AYUV   \
+        || (x) == AV_PIX_FMT_VUYA   \
+        || (x) == AV_PIX_FMT_VUYX   \
+        || (x) == AV_PIX_FMT_UYVA   \
+        )
+
 /* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */
 typedef void (* rgbConvFn) (const uint8_t *, uint8_t *, int);
 static rgbConvFn findRgbConvFn(SwsInternal *c)
@@ -1569,6 +1576,16 @@ static rgbConvFn findRgbConvFn(SwsInternal *c)
               || CONV_IS(BGRA64LE, BGR48BE)
               || CONV_IS(RGBA64BE, RGB48LE)
               || CONV_IS(BGRA64BE, BGR48LE)) conv = rgb64to48_bswap;
+    } else if (isAYUV(srcFormat) && isAYUV(dstFormat)) {
+        /* VUYX only for dst, to avoid copying undefined bytes */
+        if (     CONV_IS(AYUV, VUYA)
+              || CONV_IS(AYUV, VUYX)
+              || CONV_IS(VUYA, AYUV)) conv = shuffle_bytes_3210;
+        else if (CONV_IS(AYUV, UYVA)) conv = shuffle_bytes_2130;
+        else if (CONV_IS(VUYA, UYVA)) conv = shuffle_bytes_1203;
+        else if (CONV_IS(UYVA, AYUV)) conv = shuffle_bytes_3102;
+        else if (CONV_IS(UYVA, VUYA)
+              || CONV_IS(UYVA, VUYX)) conv = shuffle_bytes_2013;
     } else
     /* BGR -> BGR */
     if ((isBGRinInt(srcFormat) && isBGRinInt(dstFormat)) ||
@@ -2086,6 +2103,10 @@ void ff_get_unscaled_swscale(SwsInternal *c)
         !(flags & SWS_ACCURATE_RND) && !(dstW&1))
         c->convert_unscaled = bgr24ToYv12Wrapper;
 
+    /* AYUV/VUYA/UYVA -> AYUV/VUYA/UYVA */
+    if (isAYUV(srcFormat) && isAYUV(dstFormat) && findRgbConvFn(c))
+        c->convert_unscaled = rgbToRgbWrapper;
+
     /* RGB/BGR -> RGB/BGR (no dither needed forms) */
     if (isAnyRGB(srcFormat) && isAnyRGB(dstFormat) && findRgbConvFn(c)
         && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT))))
-- 
2.47.0



More information about the ffmpeg-devel mailing list