The branch, master has been updated
       via  9b8b78a8153f9ca94b7eb9cba87442954787912a (commit)
       via  ae3c5ac2c1c8f073bcb32980983ddb17098ded91 (commit)
       via  c96ccd78fcc9fdfe7efe340879576eaf50881375 (commit)
       via  2968f30a15e0b8dcd3872436bcff51bddbd9a933 (commit)
       via  34ad857d2b1021a3ca2bd33860a72cdcf63affa3 (commit)
      from  11a89bfe7bedc88980a178c565cc4d237e1ba0d8 (commit)


- Log -----------------------------------------------------------------
commit 9b8b78a8153f9ca94b7eb9cba87442954787912a
Author:     Niklas Haas <g...@haasn.dev>
AuthorDate: Sat Aug 16 18:18:53 2025 +0200
Commit:     Niklas Haas <ffm...@haasn.dev>
CommitDate: Mon Aug 18 18:50:00 2025 +0000

    avfilter/vf_colordetect: detect fully opaque alpha planes
    
    It can be useful to know if the alpha plane consists of fully opaque
    pixels or not, in which case it can e.g. safely be stripped.
    
    This only requires a very minor modification to the AVX2 routines, adding
    an extra AND on the read alpha value with the reference alpha value, and a
    single extra cheap test per line.
    
    detect_alpha_8_full_c:                                2849.1 ( 1.00x)
    detect_alpha_8_full_avx2:                              260.3 (10.95x)
    detect_alpha_8_full_avx512icl:                         130.2 (21.87x)
    detect_alpha_8_limited_c:                             8349.2 ( 1.00x)
    detect_alpha_8_limited_avx2:                           756.6 (11.04x)
    detect_alpha_8_limited_avx512icl:                      364.2 (22.93x)
    detect_alpha_16_full_c:                               1652.8 ( 1.00x)
    detect_alpha_16_full_avx2:                             236.5 ( 6.99x)
    detect_alpha_16_full_avx512icl:                        134.6 (12.28x)
    detect_alpha_16_limited_c:                            5263.1 ( 1.00x)
    detect_alpha_16_limited_avx2:                          797.4 ( 6.60x)
    detect_alpha_16_limited_avx512icl:                     400.3 (13.15x)

diff --git a/doc/filters.texi b/doc/filters.texi
index 908c98a3cf..fbd1d1959b 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -9880,7 +9880,7 @@ which indicates that this is a full range YUV source.
 @item alpha_mode
 Detect if the source contains color values above the alpha channel, which
 indicates that the alpha channel is independent (straight), rather than
-premultiplied.
+premultiplied. Also detects if the alpha plane is fully opaque or not.
 @item all
 Enable detection of all of the above properties. This is the default.
 @end table
diff --git a/libavfilter/vf_colordetect.c b/libavfilter/vf_colordetect.c
index fadb5c38f8..a7fc98e2f1 100644
--- a/libavfilter/vf_colordetect.c
+++ b/libavfilter/vf_colordetect.c
@@ -180,10 +180,9 @@ static int detect_alpha(AVFilterContext *ctx, void *arg,
         ret = s->dsp.detect_alpha(in->data[i] + y_start * stride, stride,
                                   alpha, alpha_stride, w, h_slice, alpha_max,
                                   mpeg_range, offset);
-        if (ret) {
-            atomic_store(&s->detected_alpha, ret);
+        ret |= atomic_fetch_or_explicit(&s->detected_alpha, ret, 
memory_order_relaxed);
+        if (ret == FF_ALPHA_STRAIGHT)
             break;
-        }
     }
 
     return 0;
@@ -197,7 +196,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 
     if (s->mode & COLOR_DETECT_COLOR_RANGE && s->detected_range == 
AVCOL_RANGE_UNSPECIFIED)
         ff_filter_execute(ctx, detect_range, in, NULL, nb_threads);
-    if (s->mode & COLOR_DETECT_ALPHA_MODE && s->detected_alpha == 
FF_ALPHA_UNDETERMINED)
+
+    if (s->mode & COLOR_DETECT_ALPHA_MODE && s->detected_alpha != 
FF_ALPHA_NONE &&
+        s->detected_alpha != FF_ALPHA_STRAIGHT)
         ff_filter_execute(ctx, detect_alpha, in, NULL, nb_threads);
 
     return ff_filter_frame(inlink->dst->outputs[0], in);
@@ -218,9 +219,10 @@ static av_cold void uninit(AVFilterContext *ctx)
 
     if (s->mode & COLOR_DETECT_ALPHA_MODE) {
         av_log(ctx, AV_LOG_INFO, "  Alpha mode: %s\n",
-               s->detected_alpha == FF_ALPHA_NONE     ? "none" :
-               s->detected_alpha == FF_ALPHA_STRAIGHT ? "straight / 
independent"
-                                                      : "undertermined");
+               s->detected_alpha == FF_ALPHA_NONE        ? "none" :
+               s->detected_alpha == FF_ALPHA_STRAIGHT    ? "straight" :
+               s->detected_alpha == FF_ALPHA_TRANSPARENT ? "undetermined"
+                                                         : "opaque");
     }
 }
 
diff --git a/libavfilter/vf_colordetect.h b/libavfilter/vf_colordetect.h
index 22fdbf6189..0c0dc889dc 100644
--- a/libavfilter/vf_colordetect.h
+++ b/libavfilter/vf_colordetect.h
@@ -27,9 +27,10 @@
 #include <libavutil/pixfmt.h>
 
 enum FFAlphaDetect {
-    FF_ALPHA_NONE = -1,
+    FF_ALPHA_NONE         = -1,
     FF_ALPHA_UNDETERMINED = 0,
-    FF_ALPHA_STRAIGHT,
+    FF_ALPHA_TRANSPARENT  = 1 << 0, ///< alpha < alpha_max
+    FF_ALPHA_STRAIGHT     = (1 << 1) | FF_ALPHA_TRANSPARENT, ///< alpha < pixel
     /* No way to positively identify premultiplied alpha */
 };
 
@@ -113,16 +114,19 @@ ff_detect_alpha_full_c(const uint8_t *color, ptrdiff_t 
color_stride,
                        ptrdiff_t width, ptrdiff_t height,
                        int alpha_max, int mpeg_range, int offset)
 {
+    uint8_t transparent = 0;
     while (height--) {
-        uint8_t cond = 0;
-        for (int x = 0; x < width; x++)
-            cond |= color[x] > alpha[x];
-        if (cond)
+        uint8_t straight = 0;
+        for (int x = 0; x < width; x++) {
+            straight  |= color[x] > alpha[x];
+            transparent |= alpha[x] != alpha_max;
+        }
+        if (straight)
             return FF_ALPHA_STRAIGHT;
         color += color_stride;
         alpha += alpha_stride;
     }
-    return 0;
+    return transparent ? FF_ALPHA_TRANSPARENT : 0;
 }
 
 static inline int
@@ -131,16 +135,19 @@ ff_detect_alpha_limited_c(const uint8_t *color, ptrdiff_t 
color_stride,
                           ptrdiff_t width, ptrdiff_t height,
                           int alpha_max, int mpeg_range, int offset)
 {
+    uint8_t transparent = 0;
     while (height--) {
-        uint8_t cond = 0;
-        for (int x = 0; x < width; x++)
-            cond |= alpha_max * color[x] - offset > mpeg_range * alpha[x];
-        if (cond)
+        uint8_t straight = 0;
+        for (int x = 0; x < width; x++) {
+            straight  |= alpha_max * color[x] - offset > mpeg_range * alpha[x];
+            transparent |= alpha[x] != alpha_max;
+        }
+        if (straight)
             return FF_ALPHA_STRAIGHT;
         color += color_stride;
         alpha += alpha_stride;
     }
-    return 0;
+    return transparent ? FF_ALPHA_TRANSPARENT : 0;
 }
 
 static inline int
@@ -149,18 +156,21 @@ ff_detect_alpha16_full_c(const uint8_t *color, ptrdiff_t 
color_stride,
                          ptrdiff_t width, ptrdiff_t height,
                          int alpha_max, int mpeg_range, int offset)
 {
+    uint8_t transparent = 0;
     while (height--) {
         const uint16_t *color16 = (const uint16_t *) color;
         const uint16_t *alpha16 = (const uint16_t *) alpha;
-        uint8_t cond = 0;
-        for (int x = 0; x < width; x++)
-            cond |= color16[x] > alpha16[x];
-        if (cond)
+        uint8_t straight = 0;
+        for (int x = 0; x < width; x++) {
+            straight  |= color16[x] > alpha16[x];
+            transparent |= alpha16[x] != alpha_max;
+        }
+        if (straight)
             return FF_ALPHA_STRAIGHT;
         color += color_stride;
         alpha += alpha_stride;
     }
-    return 0;
+    return transparent ? FF_ALPHA_TRANSPARENT : 0;
 }
 
 static inline int
@@ -169,17 +179,19 @@ ff_detect_alpha16_limited_c(const uint8_t *color, 
ptrdiff_t color_stride,
                             ptrdiff_t width, ptrdiff_t height,
                             int alpha_max, int mpeg_range, int offset)
 {
+    uint8_t transparent = 0;
     while (height--) {
         const uint16_t *color16 = (const uint16_t *) color;
         const uint16_t *alpha16 = (const uint16_t *) alpha;
         for (int x = 0; x < width; x++) {
             if ((int64_t) alpha_max * color16[x] - offset > (int64_t) 
mpeg_range * alpha16[x])
                 return FF_ALPHA_STRAIGHT;
+            transparent |= alpha16[x] != alpha_max;
         }
         color += color_stride;
         alpha += alpha_stride;
     }
-    return 0;
+    return transparent ? FF_ALPHA_TRANSPARENT : 0;
 }
 
 #endif /* AVFILTER_COLORDETECT_H */
diff --git a/libavfilter/x86/vf_colordetect.asm 
b/libavfilter/x86/vf_colordetect.asm
index 53ff17cf5c..7a96b6933c 100644
--- a/libavfilter/x86/vf_colordetect.asm
+++ b/libavfilter/x86/vf_colordetect.asm
@@ -69,8 +69,19 @@ cglobal detect_range%1, 4, 7, 5, data, stride, width, 
height, mpeg_min, mpeg_max
     RET
 %endmacro
 
+%define FF_ALPHA_STRAIGHT 0x3
+
 %macro detect_alpha_fn 3 ; suffix, hsuffix, range
-cglobal detect_alpha%1_%3, 6, 7, 6, color, color_stride, alpha, alpha_stride, 
width, height, x
+%if ARCH_X86_64
+cglobal detect_alpha%1_%3, 6, 8, 7, color, color_stride, alpha, alpha_stride, 
width, height, ret, x
+%else
+cglobal detect_alpha%1_%3, 1, 6, 7, color, ret, alpha, x, width, height
+%define color_strideq r1m
+%define alpha_strideq r3m
+    mov alphad,  r2m
+    mov widthd,  r4m
+    mov heightd, r5m
+%endif
     pxor m0, m0
     add colorq, widthq
     add alphaq, widthq
@@ -79,17 +90,23 @@ cglobal detect_alpha%1_%3, 6, 7, 6, color, color_stride, 
alpha, alpha_stride, wi
     vpbroadcast%2 m3, r6m ; alpha_max
     vpbroadcast%2 m4, r7m ; mpeg_range
     vpbroadcast%2 m5, r8m ; offset
+%else
+    vpbroadcast%1 m3, r6m ; alpha_max
 %endif
+    mova m6, m3
+    xor retd, retd
 .lineloop:
     mov xq, widthq
     .loop:
     %ifidn %3, full
         movu m1, [colorq + xq]
         movu m2, [alphaq + xq]
+        pand m6, m2
         pmaxu%1 m1, m2
     %else
         pmovzx%1%2 m1, [colorq + xq]
         pmovzx%1%2 m2, [alphaq + xq]
+        pand m6, m2
         pmull%2 m1, m3
         pmull%2 m2, m4
     %ifidn %1, b
@@ -121,15 +138,28 @@ cglobal detect_alpha%1_%3, 6, 7, 6, color, color_stride, 
alpha, alpha_stride, wi
 %endif
     jnz .found
 
+%if cpuflag(avx512)
+    vpandnq m1, m6, m3 ; m1 = ~m6 & m3
+    vptestmq k1, m1, m1
+    kortestb k1, k1
+    setnz xb
+%else
+    ptest m6, m3
+    setnc xb ; CF = !(~m6 & m3)
+%endif
+    or retb, xb
+
     add colorq, color_strideq
     add alphaq, alpha_strideq
     dec heightq
     jg .lineloop
-    xor eax, eax
+%ifnidn retd, eax
+    mov eax, retd
+%endif
     RET
 
 .found:
-    mov eax, 1
+    mov eax, FF_ALPHA_STRAIGHT
     RET
 %endmacro
 
diff --git a/tests/checkasm/vf_colordetect.c b/tests/checkasm/vf_colordetect.c
index 7498d6141a..9a16de7392 100644
--- a/tests/checkasm/vf_colordetect.c
+++ b/tests/checkasm/vf_colordetect.c
@@ -87,7 +87,7 @@ static void check_alpha_detect(int depth, enum AVColorRange 
range)
     LOCAL_ALIGNED_32(uint8_t, luma,  [HEIGHT * STRIDE]);
     LOCAL_ALIGNED_32(uint8_t, alpha, [HEIGHT * STRIDE]);
     memset(luma,  0x80, HEIGHT * STRIDE);
-    memset(alpha, 0xFF, HEIGHT * STRIDE);
+    memset(alpha, 0xF0, HEIGHT * STRIDE);
 
     /* Try and force overflow */
     if (depth > 8 && range == AVCOL_RANGE_MPEG) {

commit ae3c5ac2c1c8f073bcb32980983ddb17098ded91
Author:     Niklas Haas <g...@haasn.dev>
AuthorDate: Fri Aug 15 23:15:06 2025 +0200
Commit:     Niklas Haas <ffm...@haasn.dev>
CommitDate: Mon Aug 18 18:50:00 2025 +0000

    avfilter/vf_colordetect: remove extra safety margin on premul check
    
    This safety margin was motivated by the fact that vf_premultiply sometimes
    produces such illegally high values, but this has since been fixed by
    603334a04362e7, so there's no more reason to have this safety margin, at
    least for our own code. (Of course, other sources may also produce such
    broken files, but we shouldn't work around that - garbage in, garbage out.)
    
    See-Also: 603334a04362e7a466cbdf9a25892ded167e3ce0

diff --git a/libavfilter/vf_colordetect.c b/libavfilter/vf_colordetect.c
index 68b0e5b0fa..fadb5c38f8 100644
--- a/libavfilter/vf_colordetect.c
+++ b/libavfilter/vf_colordetect.c
@@ -168,12 +168,11 @@ static int detect_alpha(AVFilterContext *ctx, void *arg,
      *   = alpha_max * x - offset > mpeg_range * a in the below formula.
      *
      * We subtract an additional offset of (1 << (depth - 1)) to account for
-     * rounding errors in the value of `x`, and an extra safety margin of
-     * mpeg_range because vf_premultiply.c et al. add an offset of (a >> 1) & 
1.
+     * rounding errors in the value of `x`.
      */
     const int alpha_max = (1 << s->depth) - 1;
     const int mpeg_range = s->mpeg_max - s->mpeg_min;
-    const int offset = alpha_max * s->mpeg_min + mpeg_range + (1 << (s->depth 
- 1));
+    const int offset = alpha_max * s->mpeg_min + (1 << (s->depth - 1));
 
     int ret = 0;
     for (int i = 0; i < nb_planes; i++) {
diff --git a/tests/checkasm/vf_colordetect.c b/tests/checkasm/vf_colordetect.c
index 9c5f68f855..7498d6141a 100644
--- a/tests/checkasm/vf_colordetect.c
+++ b/tests/checkasm/vf_colordetect.c
@@ -75,7 +75,7 @@ static void check_alpha_detect(int depth, enum AVColorRange 
range)
     const int mpeg_max = 235 << (depth - 8);
     const int alpha_max = (1 << depth) - 1;
     const int mpeg_range = mpeg_max - mpeg_min;
-    const int offset = alpha_max * mpeg_min + mpeg_range + (1 << (depth - 1));
+    const int offset = alpha_max * mpeg_min + (1 << (depth - 1));
     int res_ref, res_new;
 
     FFColorDetectDSPContext dsp = {0};

commit c96ccd78fcc9fdfe7efe340879576eaf50881375
Author:     Niklas Haas <g...@haasn.dev>
AuthorDate: Fri Aug 15 23:13:16 2025 +0200
Commit:     Niklas Haas <ffm...@haasn.dev>
CommitDate: Mon Aug 18 18:50:00 2025 +0000

    avfilter/vf_colordetect: rename p, q, k variables for clarity
    
    Purely cosmetic.
    
    Motivated in part because I want to depend on the assumption that P
    represents the maximum alpha channel value.

diff --git a/libavfilter/vf_colordetect.c b/libavfilter/vf_colordetect.c
index bc29cfb1b0..68b0e5b0fa 100644
--- a/libavfilter/vf_colordetect.c
+++ b/libavfilter/vf_colordetect.c
@@ -165,21 +165,22 @@ static int detect_alpha(AVFilterContext *ctx, void *arg,
      *
      * This simplifies to:
      *   (x - mpeg_min) * pixel_max > (mpeg_max - mpeg_min) * a
-     *   = P * x - K > Q * a in the below formula.
+     *   = alpha_max * x - offset > mpeg_range * a in the below formula.
      *
      * We subtract an additional offset of (1 << (depth - 1)) to account for
      * rounding errors in the value of `x`, and an extra safety margin of
-     * Q because vf_premultiply.c et al. add an offset of (a >> 1) & 1.
+     * mpeg_range because vf_premultiply.c et al. add an offset of (a >> 1) & 
1.
      */
-    const int p = (1 << s->depth) - 1;
-    const int q = s->mpeg_max - s->mpeg_min;
-    const int k = p * s->mpeg_min + q + (1 << (s->depth - 1));
+    const int alpha_max = (1 << s->depth) - 1;
+    const int mpeg_range = s->mpeg_max - s->mpeg_min;
+    const int offset = alpha_max * s->mpeg_min + mpeg_range + (1 << (s->depth 
- 1));
 
     int ret = 0;
     for (int i = 0; i < nb_planes; i++) {
         const ptrdiff_t stride = in->linesize[i];
         ret = s->dsp.detect_alpha(in->data[i] + y_start * stride, stride,
-                                  alpha, alpha_stride, w, h_slice, p, q, k);
+                                  alpha, alpha_stride, w, h_slice, alpha_max,
+                                  mpeg_range, offset);
         if (ret) {
             atomic_store(&s->detected_alpha, ret);
             break;
diff --git a/libavfilter/vf_colordetect.h b/libavfilter/vf_colordetect.h
index 6626f88d26..22fdbf6189 100644
--- a/libavfilter/vf_colordetect.h
+++ b/libavfilter/vf_colordetect.h
@@ -43,7 +43,7 @@ typedef struct FFColorDetectDSPContext {
     int (*detect_alpha)(const uint8_t *color, ptrdiff_t color_stride,
                         const uint8_t *alpha, ptrdiff_t alpha_stride,
                         ptrdiff_t width, ptrdiff_t height,
-                        int p, int q, int k);
+                        int alpha_max, int mpeg_range, int offset);
 } FFColorDetectDSPContext;
 
 void ff_color_detect_dsp_init(FFColorDetectDSPContext *dsp, int depth,
@@ -111,7 +111,7 @@ static inline int
 ff_detect_alpha_full_c(const uint8_t *color, ptrdiff_t color_stride,
                        const uint8_t *alpha, ptrdiff_t alpha_stride,
                        ptrdiff_t width, ptrdiff_t height,
-                       int p, int q, int k)
+                       int alpha_max, int mpeg_range, int offset)
 {
     while (height--) {
         uint8_t cond = 0;
@@ -129,12 +129,12 @@ static inline int
 ff_detect_alpha_limited_c(const uint8_t *color, ptrdiff_t color_stride,
                           const uint8_t *alpha, ptrdiff_t alpha_stride,
                           ptrdiff_t width, ptrdiff_t height,
-                          int p, int q, int k)
+                          int alpha_max, int mpeg_range, int offset)
 {
     while (height--) {
         uint8_t cond = 0;
         for (int x = 0; x < width; x++)
-            cond |= p * color[x] - k > q * alpha[x];
+            cond |= alpha_max * color[x] - offset > mpeg_range * alpha[x];
         if (cond)
             return FF_ALPHA_STRAIGHT;
         color += color_stride;
@@ -147,7 +147,7 @@ static inline int
 ff_detect_alpha16_full_c(const uint8_t *color, ptrdiff_t color_stride,
                          const uint8_t *alpha, ptrdiff_t alpha_stride,
                          ptrdiff_t width, ptrdiff_t height,
-                         int p, int q, int k)
+                         int alpha_max, int mpeg_range, int offset)
 {
     while (height--) {
         const uint16_t *color16 = (const uint16_t *) color;
@@ -167,13 +167,13 @@ static inline int
 ff_detect_alpha16_limited_c(const uint8_t *color, ptrdiff_t color_stride,
                             const uint8_t *alpha, ptrdiff_t alpha_stride,
                             ptrdiff_t width, ptrdiff_t height,
-                            int p, int q, int k)
+                            int alpha_max, int mpeg_range, int offset)
 {
     while (height--) {
         const uint16_t *color16 = (const uint16_t *) color;
         const uint16_t *alpha16 = (const uint16_t *) alpha;
         for (int x = 0; x < width; x++) {
-            if ((int64_t) p * color16[x] - k > (int64_t) q * alpha16[x])
+            if ((int64_t) alpha_max * color16[x] - offset > (int64_t) 
mpeg_range * alpha16[x])
                 return FF_ALPHA_STRAIGHT;
         }
         color += color_stride;
diff --git a/libavfilter/x86/vf_colordetect.asm 
b/libavfilter/x86/vf_colordetect.asm
index 44562bc57a..53ff17cf5c 100644
--- a/libavfilter/x86/vf_colordetect.asm
+++ b/libavfilter/x86/vf_colordetect.asm
@@ -76,9 +76,9 @@ cglobal detect_alpha%1_%3, 6, 7, 6, color, color_stride, 
alpha, alpha_stride, wi
     add alphaq, widthq
     neg widthq
 %ifidn %3, limited
-    vpbroadcast%2 m3, r6m ; p
-    vpbroadcast%2 m4, r7m ; q
-    vpbroadcast%2 m5, r8m ; k
+    vpbroadcast%2 m3, r6m ; alpha_max
+    vpbroadcast%2 m4, r7m ; mpeg_range
+    vpbroadcast%2 m5, r8m ; offset
 %endif
 .lineloop:
     mov xq, widthq
diff --git a/tests/checkasm/vf_colordetect.c b/tests/checkasm/vf_colordetect.c
index 785fc08892..9c5f68f855 100644
--- a/tests/checkasm/vf_colordetect.c
+++ b/tests/checkasm/vf_colordetect.c
@@ -73,9 +73,9 @@ static void check_alpha_detect(int depth, enum AVColorRange 
range)
 {
     const int mpeg_min =  16 << (depth - 8);
     const int mpeg_max = 235 << (depth - 8);
-    const int p = (1 << depth) - 1;
-    const int q = mpeg_max - mpeg_min;
-    const int k = p * mpeg_min + q + (1 << (depth - 1));
+    const int alpha_max = (1 << depth) - 1;
+    const int mpeg_range = mpeg_max - mpeg_min;
+    const int offset = alpha_max * mpeg_min + mpeg_range + (1 << (depth - 1));
     int res_ref, res_new;
 
     FFColorDetectDSPContext dsp = {0};
@@ -115,20 +115,20 @@ static void check_alpha_detect(int depth, enum 
AVColorRange range)
     if (check_func(dsp.detect_alpha, "detect_alpha_%d_%s", depth, range == 
AVCOL_RANGE_JPEG ? "full" : "limited")) {
         /* Test increasing height, to ensure we hit the placed 0 eventually */
         for (int h = 1; h <= HEIGHT; h++) {
-            res_ref = call_ref(luma, STRIDE, alpha, STRIDE, w, h, p, q, k);
-            res_new = call_new(luma, STRIDE, alpha, STRIDE, w, h, p, q, k);
+            res_ref = call_ref(luma, STRIDE, alpha, STRIDE, w, h, alpha_max, 
mpeg_range, offset);
+            res_new = call_new(luma, STRIDE, alpha, STRIDE, w, h, alpha_max, 
mpeg_range, offset);
             if (res_ref != res_new)
                 fail();
         }
 
         /* Test base case without any out-of-range values */
         memset(alpha, 0xFF, HEIGHT * STRIDE);
-        res_ref = call_ref(luma, STRIDE, alpha, STRIDE, w, HEIGHT, p, q, k);
-        res_new = call_new(luma, STRIDE, alpha, STRIDE, w, HEIGHT, p, q, k);
+        res_ref = call_ref(luma, STRIDE, alpha, STRIDE, w, HEIGHT, alpha_max, 
mpeg_range, offset);
+        res_new = call_new(luma, STRIDE, alpha, STRIDE, w, HEIGHT, alpha_max, 
mpeg_range, offset);
         if (res_ref != res_new)
             fail();
 
-        bench_new(luma, STRIDE, alpha, STRIDE, w, HEIGHT, p, q, k);
+        bench_new(luma, STRIDE, alpha, STRIDE, w, HEIGHT, alpha_max, 
mpeg_range, offset);
     }
 }
 

commit 2968f30a15e0b8dcd3872436bcff51bddbd9a933
Author:     Niklas Haas <g...@haasn.dev>
AuthorDate: Fri Aug 15 23:07:28 2025 +0200
Commit:     Niklas Haas <ffm...@haasn.dev>
CommitDate: Mon Aug 18 18:50:00 2025 +0000

    tests/checkasm/vf_colordetect: also test opaque alpha base case
    
    Preemptively adding a check for a following commit.

diff --git a/tests/checkasm/vf_colordetect.c b/tests/checkasm/vf_colordetect.c
index 4979931cd3..785fc08892 100644
--- a/tests/checkasm/vf_colordetect.c
+++ b/tests/checkasm/vf_colordetect.c
@@ -76,6 +76,7 @@ static void check_alpha_detect(int depth, enum AVColorRange 
range)
     const int p = (1 << depth) - 1;
     const int q = mpeg_max - mpeg_min;
     const int k = p * mpeg_min + q + (1 << (depth - 1));
+    int res_ref, res_new;
 
     FFColorDetectDSPContext dsp = {0};
     ff_color_detect_dsp_init(&dsp, depth, range);
@@ -114,14 +115,19 @@ static void check_alpha_detect(int depth, enum 
AVColorRange range)
     if (check_func(dsp.detect_alpha, "detect_alpha_%d_%s", depth, range == 
AVCOL_RANGE_JPEG ? "full" : "limited")) {
         /* Test increasing height, to ensure we hit the placed 0 eventually */
         for (int h = 1; h <= HEIGHT; h++) {
-            int res_ref = call_ref(luma, STRIDE, alpha, STRIDE, w, h, p, q, k);
-            int res_new = call_new(luma, STRIDE, alpha, STRIDE, w, h, p, q, k);
+            res_ref = call_ref(luma, STRIDE, alpha, STRIDE, w, h, p, q, k);
+            res_new = call_new(luma, STRIDE, alpha, STRIDE, w, h, p, q, k);
             if (res_ref != res_new)
                 fail();
         }
 
-        /* Test performance of base case without any out-of-range values */
+        /* Test base case without any out-of-range values */
         memset(alpha, 0xFF, HEIGHT * STRIDE);
+        res_ref = call_ref(luma, STRIDE, alpha, STRIDE, w, HEIGHT, p, q, k);
+        res_new = call_new(luma, STRIDE, alpha, STRIDE, w, HEIGHT, p, q, k);
+        if (res_ref != res_new)
+            fail();
+
         bench_new(luma, STRIDE, alpha, STRIDE, w, HEIGHT, p, q, k);
     }
 }

commit 34ad857d2b1021a3ca2bd33860a72cdcf63affa3
Author:     Niklas Haas <g...@haasn.dev>
AuthorDate: Fri Aug 15 22:55:30 2025 +0200
Commit:     Niklas Haas <ffm...@haasn.dev>
CommitDate: Mon Aug 18 18:50:00 2025 +0000

    avfilter/vf_colordetect: slightly change detect_alpha() signature
    
    Basically cosmetic.
    
    I want to expand this to detect more than a single property about the alpha
    channel at the same time; so we first need a way for this function to
    return a more complex result.
    
    Move the enum AlphaMode to the header and formally generalize the return
    signature a bit to allow returning more than just one value.

diff --git a/libavfilter/vf_colordetect.c b/libavfilter/vf_colordetect.c
index 11e23ccbff..bc29cfb1b0 100644
--- a/libavfilter/vf_colordetect.c
+++ b/libavfilter/vf_colordetect.c
@@ -39,13 +39,6 @@
 
 #include "vf_colordetect.h"
 
-enum AlphaMode {
-    ALPHA_NONE = -1,
-    ALPHA_UNDETERMINED = 0,
-    ALPHA_STRAIGHT,
-    /* No way to positively identify premultiplied alpha */
-};
-
 enum ColorDetectMode {
     COLOR_DETECT_COLOR_RANGE = 1 << 0,
     COLOR_DETECT_ALPHA_MODE  = 1 << 1,
@@ -64,7 +57,7 @@ typedef struct ColorDetectContext {
     int mpeg_max;
 
     atomic_int detected_range; // enum AVColorRange
-    atomic_int detected_alpha; // enum AlphaMode
+    atomic_int detected_alpha; // enum FFAlphaDetect
 } ColorDetectContext;
 
 #define OFFSET(x) offsetof(ColorDetectContext, x)
@@ -124,9 +117,9 @@ static int config_input(AVFilterLink *inlink)
 
     if (desc->flags & AV_PIX_FMT_FLAG_ALPHA) {
         s->idx_a = desc->comp[desc->nb_components - 1].plane;
-        atomic_init(&s->detected_alpha, ALPHA_UNDETERMINED);
+        atomic_init(&s->detected_alpha, FF_ALPHA_UNDETERMINED);
     } else {
-        atomic_init(&s->detected_alpha, ALPHA_NONE);
+        atomic_init(&s->detected_alpha, FF_ALPHA_NONE);
     }
 
     ff_color_detect_dsp_init(&s->dsp, depth, inlink->color_range);
@@ -182,12 +175,14 @@ static int detect_alpha(AVFilterContext *ctx, void *arg,
     const int q = s->mpeg_max - s->mpeg_min;
     const int k = p * s->mpeg_min + q + (1 << (s->depth - 1));
 
+    int ret = 0;
     for (int i = 0; i < nb_planes; i++) {
         const ptrdiff_t stride = in->linesize[i];
-        if (s->dsp.detect_alpha(in->data[i] + y_start * stride, stride,
-                                alpha, alpha_stride, w, h_slice, p, q, k)) {
-            atomic_store(&s->detected_alpha, ALPHA_STRAIGHT);
-            return 0;
+        ret = s->dsp.detect_alpha(in->data[i] + y_start * stride, stride,
+                                  alpha, alpha_stride, w, h_slice, p, q, k);
+        if (ret) {
+            atomic_store(&s->detected_alpha, ret);
+            break;
         }
     }
 
@@ -202,7 +197,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 
     if (s->mode & COLOR_DETECT_COLOR_RANGE && s->detected_range == 
AVCOL_RANGE_UNSPECIFIED)
         ff_filter_execute(ctx, detect_range, in, NULL, nb_threads);
-    if (s->mode & COLOR_DETECT_ALPHA_MODE && s->detected_alpha == 
ALPHA_UNDETERMINED)
+    if (s->mode & COLOR_DETECT_ALPHA_MODE && s->detected_alpha == 
FF_ALPHA_UNDETERMINED)
         ff_filter_execute(ctx, detect_alpha, in, NULL, nb_threads);
 
     return ff_filter_frame(inlink->dst->outputs[0], in);
@@ -223,9 +218,9 @@ static av_cold void uninit(AVFilterContext *ctx)
 
     if (s->mode & COLOR_DETECT_ALPHA_MODE) {
         av_log(ctx, AV_LOG_INFO, "  Alpha mode: %s\n",
-               s->detected_alpha == ALPHA_NONE     ? "none" :
-               s->detected_alpha == ALPHA_STRAIGHT ? "straight / independent"
-                                                   : "undetermined");
+               s->detected_alpha == FF_ALPHA_NONE     ? "none" :
+               s->detected_alpha == FF_ALPHA_STRAIGHT ? "straight / 
independent"
+                                                      : "undertermined");
     }
 }
 
diff --git a/libavfilter/vf_colordetect.h b/libavfilter/vf_colordetect.h
index 24279643d3..6626f88d26 100644
--- a/libavfilter/vf_colordetect.h
+++ b/libavfilter/vf_colordetect.h
@@ -26,13 +26,20 @@
 #include <libavutil/macros.h>
 #include <libavutil/pixfmt.h>
 
+enum FFAlphaDetect {
+    FF_ALPHA_NONE = -1,
+    FF_ALPHA_UNDETERMINED = 0,
+    FF_ALPHA_STRAIGHT,
+    /* No way to positively identify premultiplied alpha */
+};
+
 typedef struct FFColorDetectDSPContext {
     /* Returns 1 if an out-of-range value was detected, 0 otherwise */
     int (*detect_range)(const uint8_t *data, ptrdiff_t stride,
                         ptrdiff_t width, ptrdiff_t height,
                         int mpeg_min, int mpeg_max);
 
-    /* Returns 1 if the color value exceeds the alpha value, 0 otherwise */
+    /* Returns an FFAlphaDetect enum value */
     int (*detect_alpha)(const uint8_t *color, ptrdiff_t color_stride,
                         const uint8_t *alpha, ptrdiff_t alpha_stride,
                         ptrdiff_t width, ptrdiff_t height,
@@ -111,7 +118,7 @@ ff_detect_alpha_full_c(const uint8_t *color, ptrdiff_t 
color_stride,
         for (int x = 0; x < width; x++)
             cond |= color[x] > alpha[x];
         if (cond)
-            return 1;
+            return FF_ALPHA_STRAIGHT;
         color += color_stride;
         alpha += alpha_stride;
     }
@@ -129,7 +136,7 @@ ff_detect_alpha_limited_c(const uint8_t *color, ptrdiff_t 
color_stride,
         for (int x = 0; x < width; x++)
             cond |= p * color[x] - k > q * alpha[x];
         if (cond)
-            return 1;
+            return FF_ALPHA_STRAIGHT;
         color += color_stride;
         alpha += alpha_stride;
     }
@@ -149,7 +156,7 @@ ff_detect_alpha16_full_c(const uint8_t *color, ptrdiff_t 
color_stride,
         for (int x = 0; x < width; x++)
             cond |= color16[x] > alpha16[x];
         if (cond)
-            return 1;
+            return FF_ALPHA_STRAIGHT;
         color += color_stride;
         alpha += alpha_stride;
     }
@@ -167,7 +174,7 @@ ff_detect_alpha16_limited_c(const uint8_t *color, ptrdiff_t 
color_stride,
         const uint16_t *alpha16 = (const uint16_t *) alpha;
         for (int x = 0; x < width; x++) {
             if ((int64_t) p * color16[x] - k > (int64_t) q * alpha16[x])
-                return 1;
+                return FF_ALPHA_STRAIGHT;
         }
         color += color_stride;
         alpha += alpha_stride;

-----------------------------------------------------------------------

Summary of changes:
 doc/filters.texi                   |  2 +-
 libavfilter/vf_colordetect.c       | 47 ++++++++++++------------
 libavfilter/vf_colordetect.h       | 73 ++++++++++++++++++++++++--------------
 libavfilter/x86/vf_colordetect.asm | 42 ++++++++++++++++++----
 tests/checkasm/vf_colordetect.c    | 22 +++++++-----
 5 files changed, 119 insertions(+), 67 deletions(-)


hooks/post-receive
-- 

_______________________________________________
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog

To unsubscribe, visit link above, or email
ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to