FFmpeg
vf_nlmeans_init.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Clément Bœsch <u pkh me>
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 #ifndef AVFILTER_NLMEANS_INIT_H
22 #define AVFILTER_NLMEANS_INIT_H
23 
24 #include <stddef.h>
25 #include <stdint.h>
26 
27 #include "config.h"
28 #include "libavutil/avassert.h"
29 #include "libavutil/macros.h"
30 #include "vf_nlmeans.h"
31 
32 /**
33  * Compute squared difference of the safe area (the zone where s1 and s2
34  * overlap). It is likely the largest integral zone, so it is interesting to do
35  * as little checks as possible; contrary to the unsafe version of this
36  * function, we do not need any clipping here.
37  *
38  * The line above dst and the column to its left are always readable.
39  */
40 static void compute_safe_ssd_integral_image_c(uint32_t *dst, ptrdiff_t dst_linesize_32,
41  const uint8_t *s1, ptrdiff_t linesize1,
42  const uint8_t *s2, ptrdiff_t linesize2,
43  int w, int h)
44 {
45  const uint32_t *dst_top = dst - dst_linesize_32;
46 
47  /* SIMD-friendly assumptions allowed here */
48  av_assert2(!(w & 0xf) && w >= 16 && h >= 1);
49 
50  for (int y = 0; y < h; y++) {
51  for (int x = 0; x < w; x += 4) {
52  const int d0 = s1[x ] - s2[x ];
53  const int d1 = s1[x + 1] - s2[x + 1];
54  const int d2 = s1[x + 2] - s2[x + 2];
55  const int d3 = s1[x + 3] - s2[x + 3];
56 
57  dst[x ] = dst_top[x ] - dst_top[x - 1] + d0*d0;
58  dst[x + 1] = dst_top[x + 1] - dst_top[x ] + d1*d1;
59  dst[x + 2] = dst_top[x + 2] - dst_top[x + 1] + d2*d2;
60  dst[x + 3] = dst_top[x + 3] - dst_top[x + 2] + d3*d3;
61 
62  dst[x ] += dst[x - 1];
63  dst[x + 1] += dst[x ];
64  dst[x + 2] += dst[x + 1];
65  dst[x + 3] += dst[x + 2];
66  }
67  s1 += linesize1;
68  s2 += linesize2;
69  dst += dst_linesize_32;
70  dst_top += dst_linesize_32;
71  }
72 }
73 
74 static void compute_weights_line_c(const uint32_t *const iia,
75  const uint32_t *const iib,
76  const uint32_t *const iid,
77  const uint32_t *const iie,
78  const uint8_t *const src,
79  float *total_weight,
80  float *sum,
81  const float *const weight_lut,
82  int max_meaningful_diff,
83  int startx, int endx)
84 {
85  for (int x = startx; x < endx; x++) {
86  /*
87  * M is a discrete map where every entry contains the sum of all the entries
88  * in the rectangle from the top-left origin of M to its coordinate. In the
89  * following schema, "i" contains the sum of the whole map:
90  *
91  * M = +----------+-----------------+----+
92  * | | | |
93  * | | | |
94  * | a| b| c|
95  * +----------+-----------------+----+
96  * | | | |
97  * | | | |
98  * | | X | |
99  * | | | |
100  * | d| e| f|
101  * +----------+-----------------+----+
102  * | | | |
103  * | g| h| i|
104  * +----------+-----------------+----+
105  *
106  * The sum of the X box can be calculated with:
107  * X = e-d-b+a
108  *
109  * See https://en.wikipedia.org/wiki/Summed_area_table
110  *
111  * The compute*_ssd functions compute the integral image M where every entry
112  * contains the sum of the squared difference of every corresponding pixels of
113  * two input planes of the same size as M.
114  */
115  const uint32_t a = iia[x];
116  const uint32_t b = iib[x];
117  const uint32_t d = iid[x];
118  const uint32_t e = iie[x];
119  const uint32_t patch_diff_sq = FFMIN(e - d - b + a, max_meaningful_diff);
120  const float weight = weight_lut[patch_diff_sq]; // exp(-patch_diff_sq * s->pdiff_scale)
121 
122  total_weight[x] += weight;
123  sum[x] += weight * src[x];
124  }
125 }
126 
128 {
131 
132 #if ARCH_AARCH64
134 #elif ARCH_X86
135  ff_nlmeans_init_x86(dsp);
136 #endif
137 }
138 
139 #endif /* AVFILTER_NLMEANS_INIT_H */
ff_nlmeans_init_x86
void ff_nlmeans_init_x86(NLMeansDSPContext *dsp)
Definition: vf_nlmeans_init.c:34
ff_nlmeans_init_aarch64
av_cold void ff_nlmeans_init_aarch64(NLMeansDSPContext *dsp)
Definition: vf_nlmeans_init.c:28
av_unused
#define av_unused
Definition: attributes.h:131
w
uint8_t w
Definition: llviddspenc.c:38
b
#define b
Definition: input.c:41
NLMeansDSPContext
Definition: vf_nlmeans.h:25
macros.h
NLMeansDSPContext::compute_safe_ssd_integral_image
void(* compute_safe_ssd_integral_image)(uint32_t *dst, ptrdiff_t dst_linesize_32, const uint8_t *s1, ptrdiff_t linesize1, const uint8_t *s2, ptrdiff_t linesize2, int w, int h)
Definition: vf_nlmeans.h:26
avassert.h
s1
#define s1
Definition: regdef.h:38
compute_safe_ssd_integral_image_c
static void compute_safe_ssd_integral_image_c(uint32_t *dst, ptrdiff_t dst_linesize_32, const uint8_t *s1, ptrdiff_t linesize1, const uint8_t *s2, ptrdiff_t linesize2, int w, int h)
Compute squared difference of the safe area (the zone where s1 and s2 overlap).
Definition: vf_nlmeans_init.h:40
weight
static int weight(int i, int blen, int offset)
Definition: diracdec.c:1562
s2
#define s2
Definition: regdef.h:39
vf_nlmeans.h
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:67
xf
#define xf(width, name, var, range_min, range_max, subs,...)
Definition: cbs_av1.c:590
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
ff_nlmeans_init
static av_unused void ff_nlmeans_init(NLMeansDSPContext *dsp)
Definition: vf_nlmeans_init.h:127
compute_weights_line_c
static void compute_weights_line_c(const uint32_t *const iia, const uint32_t *const iib, const uint32_t *const iid, const uint32_t *const iie, const uint8_t *const src, float *total_weight, float *sum, const float *const weight_lut, int max_meaningful_diff, int startx, int endx)
Definition: vf_nlmeans_init.h:74
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
d
d
Definition: ffmpeg_filter.c:410
NLMeansDSPContext::compute_weights_line
void(* compute_weights_line)(const uint32_t *const iia, const uint32_t *const iib, const uint32_t *const iid, const uint32_t *const iie, const uint8_t *const src, float *total_weight, float *sum, const float *const weight_lut, int max_meaningful_diff, int startx, int endx)
Definition: vf_nlmeans.h:30
h
h
Definition: vp9dsp_template.c:2038