This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit 2feb8482527612d618ae8d62e4201d5536ea63fb
Author:     Niklas Haas <[email protected]>
AuthorDate: Fri Dec 5 18:45:22 2025 +0100
Commit:     Niklas Haas <[email protected]>
CommitDate: Tue Dec 9 09:47:48 2025 +0000

    swscale/format: derive fmt_swizzle() from AVPixFmtDescriptor when possible
    
    Unfortunately, this is exceptionally difficult to handle in the general 
case,
    when packed/bitstream formats come into play - the actual interpretation of
    the offset, shift etc. are so difficult to deal with in a general case that
    I think it's simpler to continue falling back to a static table of variants
    for these exceptions. They are fortunately small in number.
---
 libswscale/format.c | 108 ++++++++++++++++++++++++++++------------------------
 1 file changed, 59 insertions(+), 49 deletions(-)

diff --git a/libswscale/format.c b/libswscale/format.c
index a1afa64f4d..7be3685c6c 100644
--- a/libswscale/format.c
+++ b/libswscale/format.c
@@ -629,41 +629,86 @@ static SwsPixelType fmt_pixel_type(enum AVPixelFormat fmt)
     return SWS_PIXEL_NONE;
 }
 
+/* A regular format is defined as any format that contains only a single
+ * component per elementary data type (i.e. no sub-byte pack/unpack needed),
+ * and whose components map 1:1 onto elementary data units */
+static int is_regular_fmt(enum AVPixelFormat fmt)
+{
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
+    if (desc->flags & (AV_PIX_FMT_FLAG_PAL | AV_PIX_FMT_FLAG_BAYER))
+        return 0; /* no 1:1 correspondence between components and data units */
+    if (desc->flags & (AV_PIX_FMT_FLAG_BITSTREAM))
+        return 0; /* bitstream formats are packed by definition */
+    if ((desc->flags & AV_PIX_FMT_FLAG_PLANAR) || desc->nb_components == 1)
+        return 1; /* planar formats are regular by definition */
+
+    const int step = desc->comp[0].step;
+    int total_bits = 0;
+
+    for (int i = 0; i < desc->nb_components; i++) {
+        if (desc->comp[i].shift || desc->comp[i].step != step)
+            return 0; /* irregular/packed format */
+        total_bits += desc->comp[i].depth;
+    }
+
+    /* Exclude formats with missing components like RGB0, 0RGB, etc. */
+    return total_bits == step * 8;
+}
+
+struct comp {
+    int index;
+    int plane;
+    int offset;
+};
+
+/* Compare by (plane, offset) */
+static int cmp_comp(const void *a, const void *b) {
+    const struct comp *ca = a;
+    const struct comp *cb = b;
+    if (ca->plane != cb->plane)
+        return ca->plane - cb->plane;
+    return ca->offset - cb->offset;
+}
+
 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 }};
+    if (desc->nb_components == 2) {
+        /* YA formats */
+        return SWS_SWIZZLE(0, 3, 1, 2);
+    } else if (is_regular_fmt(fmt)) {
+        /* Sort by increasing component order */
+        struct comp sorted[4] = { {0}, {1}, {2}, {3} };
+        for (int i = 0; i < desc->nb_components; i++) {
+            sorted[i].plane  = desc->comp[i].plane;
+            sorted[i].offset = desc->comp[i].offset;
+        }
+
+        qsort(sorted, desc->nb_components, sizeof(struct comp), cmp_comp);
+
+        SwsSwizzleOp swiz = SWS_SWIZZLE(0, 1, 2, 3);
+        for (int i = 0; i < desc->nb_components; i++)
+            swiz.in[i] = sorted[i].index;
+        return swiz;
+    }
 
     switch (fmt) {
-    case AV_PIX_FMT_ARGB:
     case AV_PIX_FMT_0RGB:
-    case AV_PIX_FMT_AYUV64LE:
-    case AV_PIX_FMT_AYUV64BE:
-    case AV_PIX_FMT_AYUV:
     case AV_PIX_FMT_X2RGB10LE:
     case AV_PIX_FMT_X2RGB10BE:
         return (SwsSwizzleOp) {{ .x = 3, 0, 1, 2 }};
-    case AV_PIX_FMT_BGR24:
     case AV_PIX_FMT_BGR8:
     case AV_PIX_FMT_BGR4:
     case AV_PIX_FMT_BGR4_BYTE:
-    case AV_PIX_FMT_BGRA:
     case AV_PIX_FMT_BGR565BE:
     case AV_PIX_FMT_BGR565LE:
     case AV_PIX_FMT_BGR555BE:
     case AV_PIX_FMT_BGR555LE:
     case AV_PIX_FMT_BGR444BE:
     case AV_PIX_FMT_BGR444LE:
-    case AV_PIX_FMT_BGR48BE:
-    case AV_PIX_FMT_BGR48LE:
-    case AV_PIX_FMT_BGRA64BE:
-    case AV_PIX_FMT_BGRA64LE:
     case AV_PIX_FMT_BGR0:
-    case AV_PIX_FMT_VUYA:
     case AV_PIX_FMT_VUYX:
         return (SwsSwizzleOp) {{ .x = 2, 1, 0, 3 }};
-    case AV_PIX_FMT_ABGR:
     case AV_PIX_FMT_0BGR:
     case AV_PIX_FMT_X2BGR10LE:
     case AV_PIX_FMT_X2BGR10BE:
@@ -671,7 +716,6 @@ static SwsSwizzleOp fmt_swizzle(enum AVPixelFormat fmt)
     case AV_PIX_FMT_XV30BE:
     case AV_PIX_FMT_XV30LE:
         return (SwsSwizzleOp) {{ .x = 3, 2, 0, 1 }};
-    case AV_PIX_FMT_VYU444:
     case AV_PIX_FMT_V30XBE:
     case AV_PIX_FMT_V30XLE:
         return (SwsSwizzleOp) {{ .x = 2, 0, 1, 3 }};
@@ -679,41 +723,7 @@ static SwsSwizzleOp fmt_swizzle(enum AVPixelFormat fmt)
     case AV_PIX_FMT_XV36LE:
     case AV_PIX_FMT_XV48BE:
     case AV_PIX_FMT_XV48LE:
-    case AV_PIX_FMT_UYVA:
         return (SwsSwizzleOp) {{ .x = 1, 0, 2, 3 }};
-    case AV_PIX_FMT_GBRP:
-    case AV_PIX_FMT_GBRP9BE:
-    case AV_PIX_FMT_GBRP9LE:
-    case AV_PIX_FMT_GBRP10BE:
-    case AV_PIX_FMT_GBRP10LE:
-    case AV_PIX_FMT_GBRP12BE:
-    case AV_PIX_FMT_GBRP12LE:
-    case AV_PIX_FMT_GBRP14BE:
-    case AV_PIX_FMT_GBRP14LE:
-    case AV_PIX_FMT_GBRP16BE:
-    case AV_PIX_FMT_GBRP16LE:
-    case AV_PIX_FMT_GBRPF16BE:
-    case AV_PIX_FMT_GBRPF16LE:
-    case AV_PIX_FMT_GBRAP:
-    case AV_PIX_FMT_GBRAP10LE:
-    case AV_PIX_FMT_GBRAP10BE:
-    case AV_PIX_FMT_GBRAP12LE:
-    case AV_PIX_FMT_GBRAP12BE:
-    case AV_PIX_FMT_GBRAP14LE:
-    case AV_PIX_FMT_GBRAP14BE:
-    case AV_PIX_FMT_GBRAP16LE:
-    case AV_PIX_FMT_GBRAP16BE:
-    case AV_PIX_FMT_GBRPF32BE:
-    case AV_PIX_FMT_GBRPF32LE:
-    case AV_PIX_FMT_GBRAPF16BE:
-    case AV_PIX_FMT_GBRAPF16LE:
-    case AV_PIX_FMT_GBRAPF32BE:
-    case AV_PIX_FMT_GBRAPF32LE:
-    case AV_PIX_FMT_GBRP10MSBBE:
-    case AV_PIX_FMT_GBRP10MSBLE:
-    case AV_PIX_FMT_GBRP12MSBBE:
-    case AV_PIX_FMT_GBRP12MSBLE:
-        return (SwsSwizzleOp) {{ .x = 1, 2, 0, 3 }};
     default:
         return (SwsSwizzleOp) {{ .x = 0, 1, 2, 3 }};
     }

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

Reply via email to