GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavfilter/median_template.c Lines: 0 70 0.0 %
Date: 2020-10-23 17:01:47 Branches: 0 46 0.0 %

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 "formats.h"
26
#include "internal.h"
27
#include "video.h"
28
29
#undef pixel
30
#if DEPTH == 8
31
#define pixel uint8_t
32
#else
33
#define pixel uint16_t
34
#endif
35
36
#undef htype
37
#define htype uint16_t
38
39
#undef fn
40
#undef fn2
41
#undef fn3
42
#define SHIFT   ((DEPTH + 1) / 2)
43
#define BINS    (1 << SHIFT)
44
#define MASK    (BINS - 1)
45
#define fn3(a,b)   a##_##b
46
#define fn2(a,b)   fn3(a,b)
47
#define fn(a)      fn2(a, DEPTH)
48
49
#define PICK_COARSE_BIN(x, y) (BINS * (x) + ((y) >> SHIFT))
50
#define PICK_FINE_BIN(x, y, z) (BINS * ((x) * ((y) >> SHIFT) + (z)) + ((y) & MASK))
51
52
static void fn(filter_plane)(AVFilterContext *ctx, const uint8_t *ssrc, int src_linesize,
53
                             uint8_t *ddst, int dst_linesize, int width, int height,
54
                             int slice_h_start, int slice_h_end, int jobnr)
55
{
56
    MedianContext *s = ctx->priv;
57
    htype *ccoarse = s->coarse[jobnr];
58
    htype *cfine = s->fine[jobnr];
59
    const int radius = s->radius;
60
    const int radiusV = s->radiusV;
61
    const int t = s->t;
62
    const pixel *src = (const pixel *)ssrc;
63
    pixel *dst = (pixel *)ddst;
64
    const pixel *srcp;
65
    const pixel *p;
66
67
    src_linesize /= sizeof(pixel);
68
    dst_linesize /= sizeof(pixel);
69
70
    memset(cfine, 0, s->fine_size * sizeof(*cfine));
71
    memset(ccoarse, 0, s->coarse_size * sizeof(*ccoarse));
72
73
    srcp = src + FFMAX(0, slice_h_start - radiusV) * src_linesize;
74
    if (jobnr == 0) {
75
        for (int i = 0; i < width; i++) {
76
            cfine[PICK_FINE_BIN(width, srcp[i], i)] += radiusV + 1;
77
            ccoarse[PICK_COARSE_BIN(i, srcp[i])] += radiusV + 1;
78
        }
79
    }
80
81
    srcp = src + FFMAX(0, slice_h_start - radiusV - (jobnr != 0)) * src_linesize;
82
    for (int i = 0; i < radiusV + (jobnr != 0) * (1 + radiusV); i++) {
83
        for (int j = 0; j < width; j++) {
84
            cfine[PICK_FINE_BIN(width, srcp[j], j)]++;
85
            ccoarse[PICK_COARSE_BIN(j, srcp[j])]++;
86
        }
87
        srcp += src_linesize;
88
    }
89
90
    srcp = src;
91
92
    for (int i = slice_h_start; i < slice_h_end; i++) {
93
        htype coarse[BINS] = { 0 };
94
        htype fine[BINS][BINS] = { { 0 } };
95
        htype luc[BINS] = { 0 };
96
97
        p = srcp + src_linesize * FFMAX(0, i - radiusV - 1);
98
        for (int j = 0; j < width; j++) {
99
            cfine[PICK_FINE_BIN(width, p[j], j)]--;
100
            ccoarse[PICK_COARSE_BIN(j, p[j])]--;
101
        }
102
103
        p = srcp + src_linesize * FFMIN(height - 1, i + radiusV);
104
        for (int j = 0; j < width; j++) {
105
            cfine[PICK_FINE_BIN(width, p[j], j)]++;
106
            ccoarse[PICK_COARSE_BIN(j, p[j])]++;
107
        }
108
109
        s->hmuladd(coarse, &ccoarse[0], radius, BINS);
110
        for (int j = 0; j < radius; j++)
111
            s->hadd(coarse, &ccoarse[BINS * j], BINS);
112
        for (int k = 0; k < BINS; k++)
113
            s->hmuladd(&fine[k][0], &cfine[BINS * width * k], 2 * radius + 1, BINS);
114
115
        for (int j = 0; j < width; j++) {
116
            int sum = 0, k, b;
117
            htype *segment;
118
119
            s->hadd(coarse, &ccoarse[BINS * FFMIN(j + radius, width - 1)], BINS);
120
121
            for (k = 0; k < BINS; k++) {
122
                sum += coarse[k];
123
                if (sum > t) {
124
                    sum -= coarse[k];
125
                    break;
126
                }
127
            }
128
            av_assert0(k < BINS);
129
130
            if (luc[k] <= j - radius) {
131
                memset(&fine[k], 0, BINS * sizeof(htype));
132
                for (luc[k] = j - radius; luc[k] < FFMIN(j + radius + 1, width); luc[k]++)
133
                    s->hadd(fine[k], &cfine[BINS * (width * k + luc[k])], BINS);
134
                if (luc[k] < j + radius + 1) {
135
                    s->hmuladd(&fine[k][0], &cfine[BINS * (width * k + width - 1)], j + radius + 1 - width, BINS);
136
                    luc[k] = j + radius + 1;
137
                }
138
            } else {
139
                for (; luc[k] < j + radius + 1; luc[k]++) {
140
                    s->hsub(fine[k], &cfine[BINS * (width * k + FFMAX(luc[k] - 2 * radius - 1, 0))], BINS);
141
                    s->hadd(fine[k], &cfine[BINS * (width * k + FFMIN(luc[k], width - 1))], BINS);
142
                }
143
            }
144
145
            s->hsub(coarse, &ccoarse[BINS * FFMAX(j - radius, 0)], BINS);
146
147
            segment = fine[k];
148
            for (b = 0; b < BINS; b++) {
149
                sum += segment[b];
150
                if (sum > t) {
151
                    dst[j] = BINS * k + b;
152
                    break;
153
                }
154
            }
155
            av_assert0(b < BINS);
156
        }
157
158
        dst += dst_linesize;
159
    }
160
}