FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/x86/vf_colordetect_init.c
Date: 2026-09-15 09:36:26
Exec Total Coverage
Lines: 19 33 57.6%
Functions: 9 17 52.9%
Branches: 56 126 44.4%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2025 Niklas Haas
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "libavutil/attributes.h"
22 #include "libavutil/x86/cpu.h"
23 #include "libavfilter/vf_colordetectdsp.h"
24
25 #define DETECT_RANGE_FUNC(FUNC_NAME, ASM_FUNC_NAME, C_FUNC_NAME, SHIFT, MMSIZE) \
26 int ASM_FUNC_NAME(const uint8_t *src, ptrdiff_t stride, \
27 ptrdiff_t width, ptrdiff_t height, int min, int max); \
28 \
29 static int FUNC_NAME(const uint8_t *src, ptrdiff_t stride, \
30 ptrdiff_t width, ptrdiff_t height, int min, int max) \
31 { \
32 ptrdiff_t total = width << SHIFT; \
33 ptrdiff_t bytes = total & ~(MMSIZE - 1); \
34 int ret; \
35 if (!bytes) \
36 return C_FUNC_NAME(src, stride, width, height, min, max); \
37 \
38 ret = ASM_FUNC_NAME(src, stride, bytes, height, min, max); \
39 if (ret || bytes == total) \
40 return ret; \
41 \
42 return ret | ASM_FUNC_NAME(src + total - MMSIZE, stride, MMSIZE, \
43 height, min, max); \
44 }
45
46 #define DETECT_ALPHA_FUNC(FUNC_NAME, ASM_FUNC_NAME, C_FUNC_NAME, SHIFT, MMSIZE) \
47 int ASM_FUNC_NAME(const uint8_t *color, ptrdiff_t color_stride, \
48 const uint8_t *alpha, ptrdiff_t alpha_stride, \
49 ptrdiff_t width, ptrdiff_t height, int p, int q, int k); \
50 \
51 static int FUNC_NAME(const uint8_t *color, ptrdiff_t color_stride, \
52 const uint8_t *alpha, ptrdiff_t alpha_stride, \
53 ptrdiff_t width, ptrdiff_t height, int p, int q, int k) \
54 { \
55 ptrdiff_t total = width << SHIFT; \
56 ptrdiff_t bytes = total & ~(MMSIZE - 1); \
57 int ret; \
58 if (!bytes) \
59 return C_FUNC_NAME(color, color_stride, alpha, alpha_stride, \
60 width, height, p, q, k); \
61 \
62 ret = ASM_FUNC_NAME(color, color_stride, alpha, alpha_stride, \
63 bytes, height, p, q, k); \
64 if (ret == FF_ALPHA_STRAIGHT || bytes == total) \
65 return ret; \
66 \
67 return ret | ASM_FUNC_NAME(color + total - MMSIZE, color_stride, \
68 alpha + total - MMSIZE, alpha_stride, \
69 MMSIZE, height, p, q, k); \
70 }
71
72 #if HAVE_AVX512ICL_EXTERNAL
73 DETECT_RANGE_FUNC(detect_range_avx512icl, ff_detect_rangeb_avx512icl, ff_detect_range_c, 0, 64)
74 DETECT_RANGE_FUNC(detect_range16_avx512icl, ff_detect_rangew_avx512icl, ff_detect_range16_c, 1, 64)
75 DETECT_ALPHA_FUNC(detect_alpha_full_avx512icl, ff_detect_alphab_full_avx512icl, ff_detect_alpha_full_c, 0, 64)
76 DETECT_ALPHA_FUNC(detect_alpha16_full_avx512icl, ff_detect_alphaw_full_avx512icl, ff_detect_alpha16_full_c, 1, 64)
77 DETECT_ALPHA_FUNC(detect_alpha_full_off_avx512icl, ff_detect_alphab_full_off_avx512icl, ff_detect_alpha_full_c, 0, 64)
78 DETECT_ALPHA_FUNC(detect_alpha16_full_off_avx512icl, ff_detect_alphaw_full_off_avx512icl, ff_detect_alpha16_full_c, 1, 64)
79 DETECT_ALPHA_FUNC(detect_alpha_limited_avx512icl, ff_detect_alphab_limited_avx512icl, ff_detect_alpha_limited_c, 0, 64)
80 DETECT_ALPHA_FUNC(detect_alpha16_limited_avx512icl, ff_detect_alphaw_limited_avx512icl, ff_detect_alpha16_limited_c, 1, 64)
81 #endif
82 #if HAVE_AVX2_EXTERNAL
83
5/6
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 13 times.
17 DETECT_RANGE_FUNC(detect_range_avx2, ff_detect_rangeb_avx2, ff_detect_range_c, 0, 32)
84
5/6
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 13 times.
17 DETECT_RANGE_FUNC(detect_range16_avx2, ff_detect_rangew_avx2, ff_detect_range16_c, 1, 32)
85
5/6
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 12 times.
18 DETECT_ALPHA_FUNC(detect_alpha_full_avx2, ff_detect_alphab_full_avx2, ff_detect_alpha_full_c, 0, 32)
86
5/6
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 12 times.
18 DETECT_ALPHA_FUNC(detect_alpha16_full_avx2, ff_detect_alphaw_full_avx2, ff_detect_alpha16_full_c, 1, 32)
87
5/6
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 12 times.
18 DETECT_ALPHA_FUNC(detect_alpha_full_off_avx2, ff_detect_alphab_full_off_avx2, ff_detect_alpha_full_c, 0, 32)
88
5/6
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 12 times.
18 DETECT_ALPHA_FUNC(detect_alpha16_full_off_avx2, ff_detect_alphaw_full_off_avx2, ff_detect_alpha16_full_c, 1, 32)
89
5/6
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 16 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1 times.
18 DETECT_ALPHA_FUNC(detect_alpha_limited_avx2, ff_detect_alphab_limited_avx2, ff_detect_alpha_limited_c, 0, 32)
90
5/6
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 16 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1 times.
18 DETECT_ALPHA_FUNC(detect_alpha16_limited_avx2, ff_detect_alphaw_limited_avx2, ff_detect_alpha16_limited_c, 1, 32)
91 #endif
92
93 112 av_cold void ff_color_detect_dsp_init_x86(FFColorDetectDSPContext *dsp, int depth,
94 int offset, enum AVColorRange color_range)
95 {
96 112 int cpu_flags = av_get_cpu_flags();
97 #if HAVE_AVX2_EXTERNAL
98
3/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 104 times.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
112 if (EXTERNAL_AVX2_FAST(cpu_flags)) {
99
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 dsp->detect_range = depth > 8 ? detect_range16_avx2 : detect_range_avx2;
100
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (color_range != AVCOL_RANGE_JPEG) {
101
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 dsp->detect_alpha = depth > 8 ? detect_alpha16_limited_avx2 : detect_alpha_limited_avx2;
102
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 } else if (offset) {
103
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 dsp->detect_alpha = depth > 8 ? detect_alpha16_full_off_avx2 : detect_alpha_full_off_avx2;
104 } else {
105
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 dsp->detect_alpha = depth > 8 ? detect_alpha16_full_avx2 : detect_alpha_full_avx2;
106 }
107 }
108 #endif
109 #if HAVE_AVX512ICL_EXTERNAL
110
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 if (EXTERNAL_AVX512ICL(cpu_flags)) {
111 dsp->detect_range = depth > 8 ? detect_range16_avx512icl : detect_range_avx512icl;
112 if (color_range != AVCOL_RANGE_JPEG) {
113 dsp->detect_alpha = depth > 8 ? detect_alpha16_limited_avx512icl : detect_alpha_limited_avx512icl;
114 } else if (offset) {
115 dsp->detect_alpha = depth > 8 ? detect_alpha16_full_off_avx512icl : detect_alpha_full_off_avx512icl;
116 } else {
117 dsp->detect_alpha = depth > 8 ? detect_alpha16_full_avx512icl : detect_alpha_full_avx512icl;
118 }
119 }
120 #endif
121 112 }
122