History

avfilter/vf_fftfilt: switch to rdft from lavu/tx

Paul B Mahol committed 4 years ago

Commit 8e825ec1 parent e26a0af2 files · +103 −59Browse files

Showing the changes to libavfilter (1 of 2 files). Show all

Unified · Split

libavfilter/vf_fftfilt.c+103−56
@@ -29,7 +29,7 @@ · 28 unmodified lines
2929 #include "libavutil/imgutils.h"
3030 #include "libavutil/opt.h"
3131 #include "libavutil/pixdesc.h"
32−#include "libavcodec/avfft.h"
32+#include "libavutil/tx.h"
3333 #include "libavutil/eval.h"
3434
3535 #define MAX_THREADS 32
@@ -51,16 +51,24 @@ typedef struct FFTFILTContext { · 15 unmodified lines
5151 int planewidth[MAX_PLANES];
5252 int planeheight[MAX_PLANES];
5353
54− RDFTContext *hrdft[MAX_THREADS][MAX_PLANES];
55− RDFTContext *vrdft[MAX_THREADS][MAX_PLANES];
56− RDFTContext *ihrdft[MAX_THREADS][MAX_PLANES];
57− RDFTContext *ivrdft[MAX_THREADS][MAX_PLANES];
54+ AVTXContext *hrdft[MAX_THREADS][MAX_PLANES];
55+ AVTXContext *vrdft[MAX_THREADS][MAX_PLANES];
56+ AVTXContext *ihrdft[MAX_THREADS][MAX_PLANES];
57+ AVTXContext *ivrdft[MAX_THREADS][MAX_PLANES];
58+
59+ av_tx_fn htx_fn, ihtx_fn;
60+ av_tx_fn vtx_fn, ivtx_fn;
61+
5862 int rdft_hbits[MAX_PLANES];
5963 int rdft_vbits[MAX_PLANES];
64+ size_t rdft_hstride[MAX_PLANES];
65+ size_t rdft_vstride[MAX_PLANES];
6066 size_t rdft_hlen[MAX_PLANES];
6167 size_t rdft_vlen[MAX_PLANES];
62− FFTSample *rdft_hdata[MAX_PLANES];
63− FFTSample *rdft_vdata[MAX_PLANES];
68+ float *rdft_hdata_in[MAX_PLANES];
69+ float *rdft_vdata_in[MAX_PLANES];
70+ float *rdft_hdata_out[MAX_PLANES];
71+ float *rdft_vdata_out[MAX_PLANES];
6472
6573 int dc[MAX_PLANES];
6674 char *weight_str[MAX_PLANES];
@@ -97,14 +105,14 @@ AVFILTER_DEFINE_CLASS(fftfilt); · 30 unmodified lines
97105 static inline double lum(void *priv, double x, double y, int plane)
98106 {
99107 FFTFILTContext *s = priv;
100− return s->rdft_vdata[plane][(int)x * s->rdft_vlen[plane] + (int)y];
108+ return s->rdft_vdata_out[plane][(int)x * s->rdft_vstride[plane] + (int)y];
101109 }
102110
103111 static double weight_Y(void *priv, double x, double y) { return lum(priv, x, y, Y); }
104112 static double weight_U(void *priv, double x, double y) { return lum(priv, x, y, U); }
105113 static double weight_V(void *priv, double x, double y) { return lum(priv, x, y, V); }
106114
107−static void copy_rev(FFTSample *dest, int w, int w2)
115+static void copy_rev(float *dest, int w, int w2)
108116 {
109117 int i;
110118
@@ -128,16 +136,19 @@ static int rdft_horizontal8(AVFilterContext *ctx, void *arg, int jobnr, int nb_j · 17 unmodified lines
128136
129137 for (int i = slice_start; i < slice_end; i++) {
130138 const uint8_t *src = in->data[plane] + i * in->linesize[plane];
131− float *hdata = s->rdft_hdata[plane] + i * s->rdft_hlen[plane];
139+ float *hdata_in = s->rdft_hdata_in[plane] + i * s->rdft_hstride[plane];
132140
133141 for (int j = 0; j < w; j++)
134− hdata[j] = src[j];
142+ hdata_in[j] = src[j];
135143
136− copy_rev(s->rdft_hdata[plane] + i * s->rdft_hlen[plane], w, s->rdft_hlen[plane]);
144+ copy_rev(s->rdft_hdata_in[plane] + i * s->rdft_hstride[plane], w, s->rdft_hlen[plane]);
137145 }
138146
139147 for (int i = slice_start; i < slice_end; i++)
140− av_rdft_calc(s->hrdft[jobnr][plane], s->rdft_hdata[plane] + i * s->rdft_hlen[plane]);
148+ s->htx_fn(s->hrdft[jobnr][plane],
149+ s->rdft_hdata_out[plane] + i * s->rdft_hstride[plane],
150+ s->rdft_hdata_in[plane] + i * s->rdft_hstride[plane],
151+ sizeof(float));
141152 }
142153
143154 return 0;
@@ -156,16 +167,19 @@ static int rdft_horizontal16(AVFilterContext *ctx, void *arg, int jobnr, int nb_ · 12 unmodified lines
156167
157168 for (int i = slice_start; i < slice_end; i++) {
158169 const uint16_t *src = (const uint16_t *)(in->data[plane] + i * in->linesize[plane]);
159− float *hdata = s->rdft_hdata[plane] + i * s->rdft_hlen[plane];
170+ float *hdata_in = s->rdft_hdata_in[plane] + i * s->rdft_hstride[plane];
160171
161172 for (int j = 0; j < w; j++)
162− hdata[j] = src[j];
173+ hdata_in[j] = src[j];
163174
164− copy_rev(s->rdft_hdata[plane] + i * s->rdft_hlen[plane], w, s->rdft_hlen[plane]);
175+ copy_rev(s->rdft_hdata_in[plane] + i * s->rdft_hstride[plane], w, s->rdft_hlen[plane]);
165176 }
166177
167178 for (int i = slice_start; i < slice_end; i++)
168− av_rdft_calc(s->hrdft[jobnr][plane], s->rdft_hdata[plane] + i * s->rdft_hlen[plane]);
179+ s->htx_fn(s->hrdft[jobnr][plane],
180+ s->rdft_hdata_out[plane] + i * s->rdft_hstride[plane],
181+ s->rdft_hdata_in[plane] + i * s->rdft_hstride[plane],
182+ sizeof(float));
169183 }
170184
171185 return 0;
@@ -183,11 +197,14 @@ static int irdft_horizontal8(AVFilterContext *ctx, void *arg, int jobnr, int nb_ · 11 unmodified lines
183197 const int slice_end = (h * (jobnr+1)) / nb_jobs;
184198
185199 for (int i = slice_start; i < slice_end; i++)
186− av_rdft_calc(s->ihrdft[jobnr][plane], s->rdft_hdata[plane] + i * s->rdft_hlen[plane]);
200+ s->ihtx_fn(s->ihrdft[jobnr][plane],
201+ s->rdft_hdata_out[plane] + i * s->rdft_hstride[plane],
202+ s->rdft_hdata_in[plane] + i * s->rdft_hstride[plane],
203+ sizeof(float));
187204
188205 for (int i = slice_start; i < slice_end; i++) {
189− const float scale = 4.f / (s->rdft_hlen[plane] * s->rdft_vlen[plane]);
190− const float *src = s->rdft_hdata[plane] + i * s->rdft_hlen[plane];
206+ const float scale = 1.f / (s->rdft_hlen[plane] * s->rdft_vlen[plane]);
207+ const float *src = s->rdft_hdata_out[plane] + i * s->rdft_hstride[plane];
191208 uint8_t *dst = out->data[plane] + i * out->linesize[plane];
192209
193210 for (int j = 0; j < w; j++)
@@ -211,11 +228,14 @@ static int irdft_horizontal16(AVFilterContext *ctx, void *arg, int jobnr, int nb · 17 unmodified lines
211228 const int slice_end = (h * (jobnr+1)) / nb_jobs;
212229
213230 for (int i = slice_start; i < slice_end; i++)
214− av_rdft_calc(s->ihrdft[jobnr][plane], s->rdft_hdata[plane] + i * s->rdft_hlen[plane]);
231+ s->ihtx_fn(s->ihrdft[jobnr][plane],
232+ s->rdft_hdata_out[plane] + i * s->rdft_hstride[plane],
233+ s->rdft_hdata_in[plane] + i * s->rdft_hstride[plane],
234+ sizeof(float));
215235
216236 for (int i = slice_start; i < slice_end; i++) {
217− const float scale = 4.f / (s->rdft_hlen[plane] * s->rdft_vlen[plane]);
218− const float *src = s->rdft_hdata[plane] + i * s->rdft_hlen[plane];
237+ const float scale = 1.f / (s->rdft_hlen[plane] * s->rdft_vlen[plane]);
238+ const float *src = s->rdft_hdata_out[plane] + i * s->rdft_hstride[plane];
219239 uint16_t *dst = (uint16_t *)(out->data[plane] + i * out->linesize[plane]);
220240
221241 for (int j = 0; j < w; j++)
@@ -303,34 +323,50 @@ static int config_props(AVFilterLink *inlink) · 81 unmodified lines
303323
304324 /* RDFT - Array initialization for Horizontal pass*/
305325 s->rdft_hlen[i] = 1 << (32 - ff_clz(w));
326+ s->rdft_hstride[i] = FFALIGN(s->rdft_hlen[i] + 2, av_cpu_max_align());
306327 s->rdft_hbits[i] = av_log2(s->rdft_hlen[i]);
307− if (!(s->rdft_hdata[i] = av_malloc_array(h, s->rdft_hlen[i] * sizeof(FFTSample))))
328+ if (!(s->rdft_hdata_in[i] = av_calloc(h, s->rdft_hstride[i] * sizeof(float))))
329+ return AVERROR(ENOMEM);
330+
331+ if (!(s->rdft_hdata_out[i] = av_calloc(h, s->rdft_hstride[i] * sizeof(float))))
308332 return AVERROR(ENOMEM);
309333
310334 for (int j = 0; j < s->nb_threads; j++) {
311− if (!(s->hrdft[j][i] = av_rdft_init(s->rdft_hbits[i], DFT_R2C)))
335+ float scale = 1.f, iscale = 1.f;
336+
337+ av_tx_init(&s->hrdft[j][i], &s->htx_fn, AV_TX_FLOAT_RDFT, 0, 1 << s->rdft_hbits[i], &scale, 0);
338+ if (!s->hrdft[j][i])
312339 return AVERROR(ENOMEM);
313− if (!(s->ihrdft[j][i] = av_rdft_init(s->rdft_hbits[i], IDFT_C2R)))
340+ av_tx_init(&s->ihrdft[j][i], &s->ihtx_fn, AV_TX_FLOAT_RDFT, 1, 1 << s->rdft_hbits[i], &iscale, 0);
341+ if (!s->ihrdft[j][i])
314342 return AVERROR(ENOMEM);
315343 }
316344
317345 /* RDFT - Array initialization for Vertical pass*/
318346 s->rdft_vlen[i] = 1 << (32 - ff_clz(h));
347+ s->rdft_vstride[i] = FFALIGN(s->rdft_vlen[i] + 2, av_cpu_max_align());
319348 s->rdft_vbits[i] = av_log2(s->rdft_vlen[i]);
320− if (!(s->rdft_vdata[i] = av_malloc_array(s->rdft_hlen[i], s->rdft_vlen[i] * sizeof(FFTSample))))
349+ if (!(s->rdft_vdata_in[i] = av_calloc(s->rdft_hstride[i], s->rdft_vstride[i] * sizeof(float))))
350+ return AVERROR(ENOMEM);
351+
352+ if (!(s->rdft_vdata_out[i] = av_calloc(s->rdft_hstride[i], s->rdft_vstride[i] * sizeof(float))))
321353 return AVERROR(ENOMEM);
322354
323355 for (int j = 0; j < s->nb_threads; j++) {
324− if (!(s->vrdft[j][i] = av_rdft_init(s->rdft_vbits[i], DFT_R2C)))
356+ float scale = 1.f, iscale = 1.f;
357+
358+ av_tx_init(&s->vrdft[j][i], &s->vtx_fn, AV_TX_FLOAT_RDFT, 0, 1 << s->rdft_vbits[i], &scale, 0);
359+ if (!s->vrdft[j][i])
325360 return AVERROR(ENOMEM);
326− if (!(s->ivrdft[j][i] = av_rdft_init(s->rdft_vbits[i], IDFT_C2R)))
361+ av_tx_init(&s->ivrdft[j][i], &s->ivtx_fn, AV_TX_FLOAT_RDFT, 1, 1 << s->rdft_vbits[i], &iscale, 0);
362+ if (!s->ivrdft[j][i])
327363 return AVERROR(ENOMEM);
328364 }
329365 }
330366
331367 /*Luminance value - Array initialization*/
332368 for (plane = 0; plane < 3; plane++) {
333− if(!(s->weight[plane] = av_malloc_array(s->rdft_hlen[plane], s->rdft_vlen[plane] * sizeof(double))))
369+ if(!(s->weight[plane] = av_calloc(s->rdft_hlen[plane], s->rdft_vlen[plane] * sizeof(double))))
334370 return AVERROR(ENOMEM);
335371
336372 if (s->eval_mode == EVAL_MODE_INIT)
@@ -360,7 +396,7 @@ static int multiply_data(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs · 23 unmodified lines
360396 /*Change user defined parameters*/
361397 for (int i = slice_start; i < slice_end; i++) {
362398 const double *weight = s->weight[plane] + i * s->rdft_vlen[plane];
363− float *vdata = s->rdft_vdata[plane] + i * s->rdft_vlen[plane];
399+ float *vdata = s->rdft_vdata_out[plane] + i * s->rdft_vstride[plane];
364400
365401 for (int j = 0; j < s->rdft_vlen[plane]; j++)
366402 vdata[j] *= weight[j];
@@ -377,16 +413,18 @@ static int copy_vertical(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs · 10 unmodified lines
377413 for (int plane = 0; plane < s->nb_planes; plane++) {
378414 const int hlen = s->rdft_hlen[plane];
379415 const int vlen = s->rdft_vlen[plane];
416+ const int hstride = s->rdft_hstride[plane];
417+ const int vstride = s->rdft_vstride[plane];
380418 const int slice_start = (hlen * jobnr) / nb_jobs;
381419 const int slice_end = (hlen * (jobnr+1)) / nb_jobs;
382420 const int h = s->planeheight[plane];
383− FFTSample *hdata = s->rdft_hdata[plane];
384− FFTSample *vdata = s->rdft_vdata[plane];
421+ float *hdata = s->rdft_hdata_out[plane];
422+ float *vdata = s->rdft_vdata_in[plane];
385423
386424 for (int i = slice_start; i < slice_end; i++) {
387425 for (int j = 0; j < h; j++)
388− vdata[i * vlen + j] = hdata[j * hlen + i];
389− copy_rev(vdata + i * vlen, h, vlen);
426+ vdata[i * vstride + j] = hdata[j * hstride + i];
427+ copy_rev(vdata + i * vstride, h, vlen);
390428 }
391429 }
392430
@@ -403,7 +441,10 @@ static int rdft_vertical(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs · 10 unmodified lines
403441 const int slice_end = (height * (jobnr+1)) / nb_jobs;
404442
405443 for (int i = slice_start; i < slice_end; i++)
406− av_rdft_calc(s->vrdft[jobnr][plane], s->rdft_vdata[plane] + i * s->rdft_vlen[plane]);
444+ s->vtx_fn(s->vrdft[jobnr][plane],
445+ s->rdft_vdata_out[plane] + i * s->rdft_vstride[plane],
446+ s->rdft_vdata_in[plane] + i * s->rdft_vstride[plane],
447+ sizeof(float));
407448 }
408449
409450 return 0;
@@ -419,7 +460,10 @@ static int irdft_vertical(AVFilterContext *ctx, void *arg, int jobnr, int nb_job · 9 unmodified lines
419460 const int slice_end = (height * (jobnr+1)) / nb_jobs;
420461
421462 for (int i = slice_start; i < slice_end; i++)
422− av_rdft_calc(s->ivrdft[jobnr][plane], s->rdft_vdata[plane] + i * s->rdft_vlen[plane]);
463+ s->ivtx_fn(s->ivrdft[jobnr][plane],
464+ s->rdft_vdata_in[plane] + i * s->rdft_vstride[plane],
465+ s->rdft_vdata_out[plane] + i * s->rdft_vstride[plane],
466+ sizeof(float));
423467 }
424468
425469 return 0;
@@ -431,16 +475,17 @@ static int copy_horizontal(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo · 5 unmodified lines
431475
432476 for (int plane = 0; plane < s->nb_planes; plane++) {
433477 const int hlen = s->rdft_hlen[plane];
434− const int vlen = s->rdft_vlen[plane];
478+ const int hstride = s->rdft_hstride[plane];
479+ const int vstride = s->rdft_vstride[plane];
435480 const int slice_start = (hlen * jobnr) / nb_jobs;
436481 const int slice_end = (hlen * (jobnr+1)) / nb_jobs;
437482 const int h = s->planeheight[plane];
438− FFTSample *hdata = s->rdft_hdata[plane];
439− FFTSample *vdata = s->rdft_vdata[plane];
483+ float *hdata = s->rdft_hdata_in[plane];
484+ float *vdata = s->rdft_vdata_in[plane];
440485
441486 for (int i = slice_start; i < slice_end; i++)
442487 for (int j = 0; j < h; j++)
443− hdata[j * hlen + i] = vdata[i * vlen + j];
488+ hdata[j * hstride + i] = vdata[i * vstride + j];
444489 }
445490
446491 return 0;
@@ -461,11 +506,6 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 14 unmodified lines
461506
462507 av_frame_copy_props(out, in);
463508
464− for (int plane = 0; plane < s->nb_planes; plane++) {
465− if (s->eval_mode == EVAL_MODE_FRAME)
466− do_eval(s, inlink, plane);
467− }
468−
469509 ff_filter_execute(ctx, s->rdft_horizontal, in, NULL,
470510 FFMIN(s->planeheight[1], s->nb_threads));
471511
@@ -475,11 +515,16 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 3 unmodified lines
475515 ff_filter_execute(ctx, rdft_vertical, NULL, NULL,
476516 FFMIN(s->planeheight[1], s->nb_threads));
477517
518+ for (int plane = 0; plane < s->nb_planes; plane++) {
519+ if (s->eval_mode == EVAL_MODE_FRAME)
520+ do_eval(s, inlink, plane);
521+ }
522+
478523 ff_filter_execute(ctx, multiply_data, NULL, NULL,
479524 FFMIN(s->planeheight[1], s->nb_threads));
480525
481526 for (int plane = 0; plane < s->nb_planes; plane++)
482− s->rdft_vdata[plane][0] += s->rdft_hlen[plane] * s->rdft_vlen[plane] * s->dc[plane];
527+ s->rdft_vdata_out[plane][0] += s->rdft_hlen[plane] * s->rdft_vlen[plane] * s->dc[plane] * (1 << (s->depth - 8));
483528
484529 ff_filter_execute(ctx, irdft_vertical, NULL, NULL,
485530 FFMIN(s->planeheight[1], s->nb_threads));
@@ -497,17 +542,19 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 11 unmodified lines
497542 static av_cold void uninit(AVFilterContext *ctx)
498543 {
499544 FFTFILTContext *s = ctx->priv;
500− int i;
501− for (i = 0; i < MAX_PLANES; i++) {
502− av_free(s->rdft_hdata[i]);
503− av_free(s->rdft_vdata[i]);
545+
546+ for (int i = 0; i < MAX_PLANES; i++) {
547+ av_freep(&s->rdft_hdata_in[i]);
548+ av_freep(&s->rdft_vdata_in[i]);
549+ av_freep(&s->rdft_hdata_out[i]);
550+ av_freep(&s->rdft_vdata_out[i]);
504551 av_expr_free(s->weight_expr[i]);
505− av_free(s->weight[i]);
552+ av_freep(&s->weight[i]);
506553 for (int j = 0; j < s->nb_threads; j++) {
507− av_rdft_end(s->hrdft[j][i]);
508− av_rdft_end(s->ihrdft[j][i]);
509− av_rdft_end(s->vrdft[j][i]);
510− av_rdft_end(s->ivrdft[j][i]);
554+ av_tx_uninit(&s->hrdft[j][i]);
555+ av_tx_uninit(&s->ihrdft[j][i]);
556+ av_tx_uninit(&s->vrdft[j][i]);
557+ av_tx_uninit(&s->ivrdft[j][i]);
511558 }
512559 }
513560 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t