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

Git pushed a commit to branch master
in repository ffmpeg.

commit da47951bd7b0dc8bfb82f347eb43a30542d0fdf9
Author:     Niklas Haas <[email protected]>
AuthorDate: Thu Feb 19 17:20:25 2026 +0100
Commit:     Niklas Haas <[email protected]>
CommitDate: Thu Feb 19 19:44:46 2026 +0000

    swscale/ops: lift read op metadata to SwsOpList
    
    Instead of awkwardly preserving these from the `SwsOp` itself. This
    interpretation lessens the risk of bugs as a result of changing the plane
    swizzle mask without updating the corresponding components.
    
    After this commit, the plane swizzle mask is automatically taken into
    account; i.e. the src_comps mask is always interpreted as if the read op
    was in-order (unswizzled).
    
    Sponsored-by: Sovereign Tech Fund
    Signed-off-by: Niklas Haas <[email protected]>
---
 libswscale/format.c | 11 +++++------
 libswscale/ops.c    |  8 +++++++-
 libswscale/ops.h    | 22 +++++++++++++---------
 3 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/libswscale/format.c b/libswscale/format.c
index ea7b5b5ebe..e0434a2024 100644
--- a/libswscale/format.c
+++ b/libswscale/format.c
@@ -896,7 +896,7 @@ int ff_sws_decode_pixfmt(SwsOpList *ops, enum AVPixelFormat 
fmt)
     SwsReadWriteOp rw_op;
     SwsSwizzleOp swizzle;
     SwsPackOp unpack;
-    SwsComps comps = {0};
+    SwsComps *comps = &ops->comps_src;
     int shift;
 
     RET(fmt_analyze(fmt, &rw_op, &unpack, &swizzle, &shift,
@@ -908,8 +908,8 @@ int ff_sws_decode_pixfmt(SwsOpList *ops, enum AVPixelFormat 
fmt)
     const int integer = ff_sws_pixel_type_is_int(raw_type);
     const int swapped = (desc->flags & AV_PIX_FMT_FLAG_BE) != 
NATIVE_ENDIAN_FLAG;
     for (int i = 0; i < rw_op.elems; i++) {
-        comps.flags[i] = (integer ? SWS_COMP_EXACT   : 0) |
-                         (swapped ? SWS_COMP_SWAPPED : 0);
+        comps->flags[i] = (integer ? SWS_COMP_EXACT   : 0) |
+                          (swapped ? SWS_COMP_SWAPPED : 0);
     }
 
     /* Generate value range information for simple unpacked formats */
@@ -920,9 +920,9 @@ int ff_sws_decode_pixfmt(SwsOpList *ops, enum AVPixelFormat 
fmt)
         for (int c = 0; c < desc->nb_components; c++) {
             const int bits   = desc->comp[c].depth + shift;
             const int idx    = swizzle.in[is_ya ? 3 * c : c];
-            comps.min[idx]   = Q0;
+            comps->min[idx]  = Q0;
             if (bits < 32) /* FIXME: AVRational is limited to INT_MAX */
-                comps.max[idx] = Q((1ULL << bits) - 1);
+                comps->max[idx] = Q((1ULL << bits) - 1);
         }
     }
 
@@ -931,7 +931,6 @@ int ff_sws_decode_pixfmt(SwsOpList *ops, enum AVPixelFormat 
fmt)
         .op    = SWS_OP_READ,
         .type  = raw_type,
         .rw    = rw_op,
-        .comps = comps,
     }));
 
     if (swapped) {
diff --git a/libswscale/ops.c b/libswscale/ops.c
index 4d9d73437b..900077584a 100644
--- a/libswscale/ops.c
+++ b/libswscale/ops.c
@@ -249,8 +249,14 @@ void ff_sws_op_list_update_comps(SwsOpList *ops)
 
         switch (op->op) {
         case SWS_OP_READ:
-            /* Active components are preserved from the user-provided value,
+            /* Active components are taken from the user-provided values,
              * other components are explicitly stripped */
+            for (int i = 0; i < op->rw.elems; i++) {
+                const int idx = op->rw.packed ? i : ops->order_src.in[i];
+                op->comps.flags[i] = ops->comps_src.flags[idx];
+                op->comps.min[i]   = ops->comps_src.min[idx];
+                op->comps.max[i]   = ops->comps_src.max[idx];
+            }
             for (int i = op->rw.elems; i < 4; i++) {
                 op->comps.flags[i] = prev.flags[i];
                 op->comps.min[i]   = prev.min[i];
diff --git a/libswscale/ops.h b/libswscale/ops.h
index 27f79b2471..9f93c12fa8 100644
--- a/libswscale/ops.h
+++ b/libswscale/ops.h
@@ -197,15 +197,8 @@ typedef struct SwsOp {
     };
 
     /**
-     * Metadata about the operation's input/output components.
-     *
-     * For SWS_OP_READ, this is informative; and lets the optimizer know
-     * additional information about the value range and/or pixel data to 
expect.
-     * The default value of {0} is safe to pass in the case that no additional
-     * information is known.
-     *
-     * For every other operation, this metadata is discarded and regenerated
-     * automatically by `ff_sws_op_list_update_comps()`.
+     * Metadata about the operation's input/output components. Discarded
+     * and regenerated automatically by `ff_sws_op_list_update_comps()`.
      *
      * Note that backends may rely on the presence and accuracy of this
      * metadata for all operations, during ff_sws_ops_compile().
@@ -233,6 +226,17 @@ typedef struct SwsOpList {
     /* Input/output plane pointer swizzle mask */
     SwsSwizzleOp order_src, order_dst;
 
+    /**
+     * Source component metadata associated with pixel values from each
+     * corresponding component (in plane/memory order, i.e. not affected by
+     * `order_src`). Lets the optimizer know additional information about
+     * the value range and/or pixel data to expect.
+     *
+     * The default value of {0} is safe to pass in the case that no additional
+     * information is known.
+     */
+    SwsComps comps_src;
+
     /* Purely informative metadata associated with this operation list */
     SwsFormat src, dst;
 } SwsOpList;

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

Reply via email to