FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/median_template.c
Date: 2025-07-08 13:42:56
Exec Total Coverage
Lines: 71 71 100.0%
Functions: 1 6 16.7%
Branches: 41 46 89.1%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2019 Paul B Mahol
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 * Redistribution and use in source and binary forms, with or without modification,
20 * are permitted provided that the following conditions are met:
21 */
22
23 #include "libavutil/avassert.h"
24 #include "avfilter.h"
25 #include "video.h"
26
27 #undef pixel
28 #if DEPTH == 8
29 #define pixel uint8_t
30 #else
31 #define pixel uint16_t
32 #endif
33
34 #undef htype
35 #define htype uint16_t
36
37 #undef fn
38 #undef fn2
39 #undef fn3
40 #define SHIFT ((DEPTH + 1) / 2)
41 #define BINS (1 << SHIFT)
42 #define MASK (BINS - 1)
43 #define fn3(a,b) a##_##b
44 #define fn2(a,b) fn3(a,b)
45 #define fn(a) fn2(a, DEPTH)
46
47 #define PICK_COARSE_BIN(x, y) (BINS * (x) + ((y) >> SHIFT))
48 #define PICK_FINE_BIN(x, y, z) (BINS * ((x) * ((y) >> SHIFT) + (z)) + ((y) & MASK))
49
50 36 static void fn(filter_plane)(AVFilterContext *ctx, const uint8_t *ssrc, int src_linesize,
51 uint8_t *ddst, int dst_linesize, int width, int height,
52 int slice_h_start, int slice_h_end, int jobnr)
53 {
54 36 MedianContext *s = ctx->priv;
55 36 htype *ccoarse = s->coarse[jobnr];
56 36 htype *cfine = s->fine[jobnr];
57 36 const int radius = s->radius;
58 36 const int radiusV = s->radiusV;
59 36 const int t = s->t;
60 36 const pixel *src = (const pixel *)ssrc;
61 36 pixel *dst = (pixel *)ddst;
62 const pixel *srcp;
63 const pixel *p;
64
65 36 src_linesize /= sizeof(pixel);
66 36 dst_linesize /= sizeof(pixel);
67
68 36 memset(cfine, 0, s->fine_size * sizeof(*cfine));
69 36 memset(ccoarse, 0, s->coarse_size * sizeof(*ccoarse));
70
71 36 srcp = src + FFMAX(0, slice_h_start - radiusV) * src_linesize;
72
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
36 if (jobnr == 0) {
73
2/2
✓ Branch 0 taken 4224 times.
✓ Branch 1 taken 18 times.
8484 for (int i = 0; i < width; i++) {
74 8448 cfine[PICK_FINE_BIN(width, srcp[i], i)] += radiusV + 1;
75 8448 ccoarse[PICK_COARSE_BIN(i, srcp[i])] += radiusV + 1;
76 }
77 }
78
79 36 srcp = src + FFMAX(0, slice_h_start - radiusV - (jobnr != 0)) * src_linesize;
80
2/2
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 18 times.
216 for (int i = 0; i < radiusV + (jobnr != 0) * (1 + radiusV); i++) {
81
2/2
✓ Branch 0 taken 21120 times.
✓ Branch 1 taken 90 times.
42420 for (int j = 0; j < width; j++) {
82 42240 cfine[PICK_FINE_BIN(width, srcp[j], j)]++;
83 42240 ccoarse[PICK_COARSE_BIN(j, srcp[j])]++;
84 }
85 180 srcp += src_linesize;
86 }
87
88 36 srcp = src;
89
90
2/2
✓ Branch 0 taken 3456 times.
✓ Branch 1 taken 18 times.
6948 for (int i = slice_h_start; i < slice_h_end; i++) {
91 6912 htype coarse[BINS] = { 0 };
92 6912 htype fine[BINS][BINS] = { { 0 } };
93 6912 htype luc[BINS] = { 0 };
94
95 6912 p = srcp + src_linesize * FFMAX(0, i - radiusV - 1);
96
2/2
✓ Branch 0 taken 912384 times.
✓ Branch 1 taken 3456 times.
1831680 for (int j = 0; j < width; j++) {
97 1824768 cfine[PICK_FINE_BIN(width, p[j], j)]--;
98 1824768 ccoarse[PICK_COARSE_BIN(j, p[j])]--;
99 }
100
101 6912 p = srcp + src_linesize * FFMIN(height - 1, i + radiusV);
102
2/2
✓ Branch 0 taken 912384 times.
✓ Branch 1 taken 3456 times.
1831680 for (int j = 0; j < width; j++) {
103 1824768 cfine[PICK_FINE_BIN(width, p[j], j)]++;
104 1824768 ccoarse[PICK_COARSE_BIN(j, p[j])]++;
105 }
106
107 6912 s->hmuladd(coarse, &ccoarse[0], radius, BINS);
108
2/2
✓ Branch 0 taken 17280 times.
✓ Branch 1 taken 3456 times.
41472 for (int j = 0; j < radius; j++)
109 34560 s->hadd(coarse, &ccoarse[BINS * j], BINS);
110
2/2
✓ Branch 0 taken 55296 times.
✓ Branch 1 taken 3456 times.
117504 for (int k = 0; k < BINS; k++)
111 110592 s->hmuladd(&fine[k][0], &cfine[BINS * width * k], 2 * radius + 1, BINS);
112
113
2/2
✓ Branch 0 taken 912384 times.
✓ Branch 1 taken 3456 times.
1831680 for (int j = 0; j < width; j++) {
114 1824768 int sum = 0, k, b;
115 htype *segment;
116
117
2/2
✓ Branch 0 taken 17280 times.
✓ Branch 1 taken 895104 times.
1824768 s->hadd(coarse, &ccoarse[BINS * FFMIN(j + radius, width - 1)], BINS);
118
119
1/2
✓ Branch 0 taken 7625764 times.
✗ Branch 1 not taken.
15251528 for (k = 0; k < BINS; k++) {
120 15251528 sum += coarse[k];
121
2/2
✓ Branch 0 taken 912384 times.
✓ Branch 1 taken 6713380 times.
15251528 if (sum > t) {
122 1824768 sum -= coarse[k];
123 1824768 break;
124 }
125 }
126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 912384 times.
1824768 av_assert0(k < BINS);
127
128
2/2
✓ Branch 0 taken 143311 times.
✓ Branch 1 taken 769073 times.
1824768 if (luc[k] <= j - radius) {
129 286622 memset(&fine[k], 0, BINS * sizeof(htype));
130
4/4
✓ Branch 0 taken 1687536 times.
✓ Branch 1 taken 24030 times.
✓ Branch 2 taken 1568255 times.
✓ Branch 3 taken 143311 times.
3423132 for (luc[k] = j - radius; luc[k] < FFMIN(j + radius + 1, width); luc[k]++)
131 3136510 s->hadd(fine[k], &cfine[BINS * (width * k + luc[k])], BINS);
132
2/2
✓ Branch 0 taken 2683 times.
✓ Branch 1 taken 140628 times.
286622 if (luc[k] < j + radius + 1) {
133 5366 s->hmuladd(&fine[k][0], &cfine[BINS * (width * k + width - 1)], j + radius + 1 - width, BINS);
134 5366 luc[k] = j + radius + 1;
135 }
136 } else {
137
2/2
✓ Branch 0 taken 1071524 times.
✓ Branch 1 taken 769073 times.
3681194 for (; luc[k] < j + radius + 1; luc[k]++) {
138 2143048 s->hsub(fine[k], &cfine[BINS * (width * k + FFMAX(luc[k] - 2 * radius - 1, 0))], BINS);
139
2/2
✓ Branch 0 taken 15906 times.
✓ Branch 1 taken 1055618 times.
2143048 s->hadd(fine[k], &cfine[BINS * (width * k + FFMIN(luc[k], width - 1))], BINS);
140 }
141 }
142
143 1824768 s->hsub(coarse, &ccoarse[BINS * FFMAX(j - radius, 0)], BINS);
144
145 1824768 segment = fine[k];
146
1/2
✓ Branch 0 taken 7529482 times.
✗ Branch 1 not taken.
15058964 for (b = 0; b < BINS; b++) {
147 15058964 sum += segment[b];
148
2/2
✓ Branch 0 taken 912384 times.
✓ Branch 1 taken 6617098 times.
15058964 if (sum > t) {
149 1824768 dst[j] = BINS * k + b;
150 1824768 break;
151 }
152 }
153
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 912384 times.
1824768 av_assert0(b < BINS);
154 }
155
156 6912 dst += dst_linesize;
157 }
158 36 }
159