FFmpeg
aap_template.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #undef ZERO
20 #undef ONE
21 #undef ftype
22 #undef SAMPLE_FORMAT
23 #if DEPTH == 32
24 #define SAMPLE_FORMAT float
25 #define ftype float
26 #define ONE 1.f
27 #define ZERO 0.f
28 #else
29 #define SAMPLE_FORMAT double
30 #define ftype double
31 #define ONE 1.0
32 #define ZERO 0.0
33 #endif
34 
35 #define fn3(a,b) a##_##b
36 #define fn2(a,b) fn3(a,b)
37 #define fn(a) fn2(a, SAMPLE_FORMAT)
38 
39 #if DEPTH == 64
40 static double scalarproduct_double(const double *v1, const double *v2, int len)
41 {
42  double p = 0.0;
43 
44  for (int i = 0; i < len; i++)
45  p += v1[i] * v2[i];
46 
47  return p;
48 }
49 #endif
50 
52  ftype *coeffs, ftype *tmp, int *offset)
53 {
54  const int order = s->order;
55  ftype output;
56 
57  delay[*offset] = sample;
58 
59  memcpy(tmp, coeffs + order - *offset, order * sizeof(ftype));
60 #if DEPTH == 32
61  output = s->fdsp->scalarproduct_float(delay, tmp, s->kernel_size);
62 #else
63  output = scalarproduct_double(delay, tmp, s->kernel_size);
64 #endif
65 
66  if (--(*offset) < 0)
67  *offset = order - 1;
68 
69  return output;
70 }
71 
72 static int fn(lup_decompose)(ftype **MA, const int N, const ftype tol, int *P)
73 {
74  for (int i = 0; i <= N; i++)
75  P[i] = i;
76 
77  for (int i = 0; i < N; i++) {
78  ftype maxA = ZERO;
79  int imax = i;
80 
81  for (int k = i; k < N; k++) {
82  ftype absA = fabs(MA[k][i]);
83  if (absA > maxA) {
84  maxA = absA;
85  imax = k;
86  }
87  }
88 
89  if (maxA < tol)
90  return 0;
91 
92  if (imax != i) {
93  FFSWAP(int, P[i], P[imax]);
94  FFSWAP(ftype *, MA[i], MA[imax]);
95  P[N]++;
96  }
97 
98  for (int j = i + 1; j < N; j++) {
99  MA[j][i] /= MA[i][i];
100 
101  for (int k = i + 1; k < N; k++)
102  MA[j][k] -= MA[j][i] * MA[i][k];
103  }
104  }
105 
106  return 1;
107 }
108 
109 static void fn(lup_invert)(ftype *const *MA, const int *P, const int N, ftype **IA)
110 {
111  for (int j = 0; j < N; j++) {
112  for (int i = 0; i < N; i++) {
113  IA[i][j] = P[i] == j ? ONE : ZERO;
114 
115  for (int k = 0; k < i; k++)
116  IA[i][j] -= MA[i][k] * IA[k][j];
117  }
118 
119  for (int i = N - 1; i >= 0; i--) {
120  for (int k = i + 1; k < N; k++)
121  IA[i][j] -= MA[i][k] * IA[k][j];
122 
123  IA[i][j] /= MA[i][i];
124  }
125  }
126 }
127 
128 static ftype fn(process_sample)(AudioAPContext *s, ftype input, ftype desired, int ch)
129 {
130  ftype *dcoeffs = (ftype *)s->dcoeffs->extended_data[ch];
131  ftype *coeffs = (ftype *)s->coeffs->extended_data[ch];
132  ftype *delay = (ftype *)s->delay->extended_data[ch];
133  ftype **itmpmp = (ftype **)&s->itmpmp[s->projection * ch];
134  ftype **tmpmp = (ftype **)&s->tmpmp[s->projection * ch];
135  ftype *tmpm = (ftype *)s->tmpm->extended_data[ch];
136  ftype *tmp = (ftype *)s->tmp->extended_data[ch];
137  ftype *e = (ftype *)s->e->extended_data[ch];
138  ftype *x = (ftype *)s->x->extended_data[ch];
139  ftype *w = (ftype *)s->w->extended_data[ch];
140  int *p = (int *)s->p->extended_data[ch];
141  int *offset = (int *)s->offset->extended_data[ch];
142  const int projection = s->projection;
143  const ftype delta = s->delta;
144  const int order = s->order;
145  const int length = projection + order;
146  const ftype mu = s->mu;
147  const ftype tol = 0.00001f;
148  ftype output;
149 
150  x[offset[2] + length] = x[offset[2]] = input;
151  delay[offset[0] + order] = input;
152 
153  output = fn(fir_sample)(s, input, delay, coeffs, tmp, offset);
154  e[offset[1]] = e[offset[1] + projection] = desired - output;
155 
156  for (int i = 0; i < projection; i++) {
157  const int iprojection = i * projection;
158 
159  for (int j = i; j < projection; j++) {
160  ftype sum = ZERO;
161  for (int k = 0; k < order; k++)
162  sum += x[offset[2] + i + k] * x[offset[2] + j + k];
163  tmpm[iprojection + j] = sum;
164  if (i != j)
165  tmpm[j * projection + i] = sum;
166  }
167 
168  tmpm[iprojection + i] += delta;
169  }
170 
171  fn(lup_decompose)(tmpmp, projection, tol, p);
172  fn(lup_invert)(tmpmp, p, projection, itmpmp);
173 
174  for (int i = 0; i < projection; i++) {
175  ftype sum = ZERO;
176  for (int j = 0; j < projection; j++)
177  sum += itmpmp[i][j] * e[j + offset[1]];
178  w[i] = sum;
179  }
180 
181  for (int i = 0; i < order; i++) {
182  ftype sum = ZERO;
183  for (int j = 0; j < projection; j++)
184  sum += x[offset[2] + i + j] * w[j];
185  dcoeffs[i] = sum;
186  }
187 
188  for (int i = 0; i < order; i++)
189  coeffs[i] = coeffs[i + order] = coeffs[i] + mu * dcoeffs[i];
190 
191  if (--offset[1] < 0)
192  offset[1] = projection - 1;
193 
194  if (--offset[2] < 0)
195  offset[2] = length - 1;
196 
197  switch (s->output_mode) {
198  case IN_MODE: output = input; break;
199  case DESIRED_MODE: output = desired; break;
200  case OUT_MODE: output = desired - output; break;
201  case NOISE_MODE: output = input - output; break;
202  case ERROR_MODE: break;
203  }
204  return output;
205 }
206 
207 static int fn(filter_channels)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
208 {
209  AudioAPContext *s = ctx->priv;
210  AVFrame *out = arg;
211  const int start = (out->ch_layout.nb_channels * jobnr) / nb_jobs;
212  const int end = (out->ch_layout.nb_channels * (jobnr+1)) / nb_jobs;
213 
214  for (int c = start; c < end; c++) {
215  const ftype *input = (const ftype *)s->frame[0]->extended_data[c];
216  const ftype *desired = (const ftype *)s->frame[1]->extended_data[c];
217  ftype *output = (ftype *)out->extended_data[c];
218 
219  for (int n = 0; n < out->nb_samples; n++) {
220  output[n] = fn(process_sample)(s, input[n], desired[n], c);
221  if (ctx->is_disabled)
222  output[n] = input[n];
223  }
224  }
225 
226  return 0;
227 }
out
FILE * out
Definition: movenc.c:55
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:225
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:374
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
w
uint8_t w
Definition: llviddspenc.c:38
IA
#define IA(x)
Definition: cast5.c:30
ftype
#define ftype
Definition: aap_template.c:30
fir_sample
static ftype fn() fir_sample(AudioAPContext *s, ftype sample, ftype *delay, ftype *coeffs, ftype *tmp, int *offset)
Definition: aap_template.c:51
ERROR_MODE
@ ERROR_MODE
Definition: af_aap.c:38
s
#define s(width, name)
Definition: cbs_vp9.c:198
process_sample
static ftype fn() process_sample(AudioAPContext *s, ftype input, ftype desired, int ch)
Definition: aap_template.c:128
ctx
AVFormatContext * ctx
Definition: movenc.c:49
DESIRED_MODE
@ DESIRED_MODE
Definition: af_aap.c:35
arg
const char * arg
Definition: jacosubdec.c:67
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
lup_decompose
static int fn() lup_decompose(ftype **MA, const int N, const ftype tol, int *P)
Definition: aap_template.c:72
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
lup_invert
static void fn() lup_invert(ftype *const *MA, const int *P, const int N, ftype **IA)
Definition: aap_template.c:109
filter_channels
static int fn() filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: aap_template.c:207
P
#define P
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
sample
#define sample
Definition: flacdsp_template.c:44
fn
#define fn(a)
Definition: aap_template.c:37
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
N
#define N
Definition: af_mcompand.c:54
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
ZERO
#define ZERO
Definition: aap_template.c:32
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
delta
float delta
Definition: vorbis_enc_data.h:430
len
int len
Definition: vorbis_enc_data.h:426
AudioAPContext
Definition: af_aap.c:42
NOISE_MODE
@ NOISE_MODE
Definition: af_aap.c:37
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
IN_MODE
@ IN_MODE
Definition: af_aap.c:34
OUT_MODE
@ OUT_MODE
Definition: af_aap.c:36
AVFilterContext
An instance of a filter.
Definition: avfilter.h:407
ONE
#define ONE
Definition: aap_template.c:31