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]
