PR #21104 opened by Niklas Haas (haasn)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21104
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21104.patch


>From 7bda21249c263dec6f615a1058d181b6169890f7 Mon Sep 17 00:00:00 2001
From: Niklas Haas <[email protected]>
Date: Thu, 4 Dec 2025 19:32:16 +0100
Subject: [PATCH 1/2] swscale/format: handle YA format swizzles more robustly

This code was previously broken; since YAF32BE/LE were not included as
part of the format enumeration. However, since we *always* know the correct
swizzle for YA formats, we can just special-case this by the number of
components instead.
---
 libswscale/format.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/libswscale/format.c b/libswscale/format.c
index 2ae6d50523..5ac0418266 100644
--- a/libswscale/format.c
+++ b/libswscale/format.c
@@ -630,6 +630,10 @@ static SwsPixelType fmt_pixel_type(enum AVPixelFormat fmt)
 
 static SwsSwizzleOp fmt_swizzle(enum AVPixelFormat fmt)
 {
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
+    if (desc->nb_components == 2) /* YA formats */
+        return (SwsSwizzleOp) {{ .x = 0, 3, 1, 2 }};
+
     switch (fmt) {
     case AV_PIX_FMT_ARGB:
     case AV_PIX_FMT_0RGB:
@@ -663,10 +667,6 @@ static SwsSwizzleOp fmt_swizzle(enum AVPixelFormat fmt)
     case AV_PIX_FMT_X2BGR10LE:
     case AV_PIX_FMT_X2BGR10BE:
         return (SwsSwizzleOp) {{ .x = 3, 2, 1, 0 }};
-    case AV_PIX_FMT_YA8:
-    case AV_PIX_FMT_YA16BE:
-    case AV_PIX_FMT_YA16LE:
-        return (SwsSwizzleOp) {{ .x = 0, 3, 1, 2 }};
     case AV_PIX_FMT_XV30BE:
     case AV_PIX_FMT_XV30LE:
         return (SwsSwizzleOp) {{ .x = 3, 2, 0, 1 }};
-- 
2.49.1


>From 13648bed352d008d3d65dec58331702f17e41c7e Mon Sep 17 00:00:00 2001
From: Niklas Haas <[email protected]>
Date: Thu, 4 Dec 2025 19:25:51 +0100
Subject: [PATCH 2/2] swscale/tests: add new test for generated operation lists

This is similar to swscale/tests/swscale.c, but significantly cheaper - it
merely prints the generated (optimized) operation list for every format
conversion.

Mostly useful for my own purposes as a regression test when making changes
to the ops optimizer. Note the distinction between this and tests/swscale.c,
the latter of which tests the result of applying an operation list for
equality, rather than the operation list itself.
---
 libswscale/Makefile        |  1 +
 libswscale/tests/sws_ops.c | 99 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 100 insertions(+)
 create mode 100644 libswscale/tests/sws_ops.c

diff --git a/libswscale/Makefile b/libswscale/Makefile
index a096ed331e..bde1144897 100644
--- a/libswscale/Makefile
+++ b/libswscale/Makefile
@@ -43,3 +43,4 @@ TESTPROGS = colorspace                                        
          \
             floatimg_cmp                                                \
             pixdesc_query                                               \
             swscale                                                     \
+            sws_ops                                                     \
diff --git a/libswscale/tests/sws_ops.c b/libswscale/tests/sws_ops.c
new file mode 100644
index 0000000000..536d0d3599
--- /dev/null
+++ b/libswscale/tests/sws_ops.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2025      Nikles Haas
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/pixdesc.h"
+#include "libswscale/ops.h"
+#include "libswscale/format.h"
+
+static int run_test(SwsContext *const ctx,
+                    const AVPixFmtDescriptor *const src_desc,
+                    const AVPixFmtDescriptor *const dst_desc)
+{
+    bool dummy;
+
+    SwsFormat src = {
+        .format = av_pix_fmt_desc_get_id(src_desc),
+        .desc   = src_desc,
+    };
+
+    SwsFormat dst = {
+        .format = av_pix_fmt_desc_get_id(dst_desc),
+        .desc   = dst_desc,
+    };
+
+    ff_infer_colors(&src.color, &dst.color);
+
+    SwsOpList *ops = ff_sws_op_list_alloc();
+    if (!ops)
+        return AVERROR(ENOMEM);
+
+    if (ff_sws_decode_pixfmt(ops, src.format) < 0)
+        goto fail;
+    if (ff_sws_decode_colors(ctx, SWS_PIXEL_F32, ops, src, &dummy) < 0)
+        goto fail;
+    if (ff_sws_encode_colors(ctx, SWS_PIXEL_F32, ops, dst, &dummy) < 0)
+        goto fail;
+    if (ff_sws_encode_pixfmt(ops, dst.format) < 0)
+        goto fail;
+
+    av_log(NULL, AV_LOG_INFO, "%s -> %s:\n",
+           av_get_pix_fmt_name(src.format), av_get_pix_fmt_name(dst.format));
+
+    ff_sws_op_list_optimize(ops);
+    ff_sws_op_list_print(NULL, AV_LOG_INFO, ops);
+
+fail:
+    /* silently skip unsupported formats */
+    ff_sws_op_list_free(&ops);
+    return 0;
+}
+
+static void log_cb(void *avcl, int level, const char *fmt, va_list vl)
+{
+    if (level == AV_LOG_INFO)
+        vfprintf(stdout, fmt, vl);
+    else
+        av_log_default_callback(avcl, level, fmt, vl);
+}
+
+int main(int argc, char **argv)
+{
+    SwsContext *ctx = sws_alloc_context();
+    int ret = 1;
+
+    av_log_set_callback(log_cb);
+
+    for (const AVPixFmtDescriptor *src = av_pix_fmt_desc_next(NULL);
+         src; src = av_pix_fmt_desc_next(src))
+    {
+        for (const AVPixFmtDescriptor *dst = av_pix_fmt_desc_next(NULL);
+            dst; dst = av_pix_fmt_desc_next(dst))
+        {
+            int ret = run_test(ctx, src, dst);
+            if (ret < 0)
+                goto fail;
+        }
+    }
+
+    ret = 0;
+fail:
+    sws_free_context(&ctx);
+    return ret;
+}
-- 
2.49.1

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to