From a686d34fea6e963f878518ffe3a08512362ed79b Mon Sep 17 00:00:00 2001 From: James Almer Date: Tue, 29 Oct 2024 16:14:04 -0300 Subject: [PATCH] swscale/swscale_unscaled: add unscaled conversion for AYUV/VUYA/UYVA Signed-off-by: James Almer --- 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))))