History

avfilter/afir_template: make IR transitions artifacts free

Paul B Mahol committed 3 years ago

Commit 38795551 parent 62da0b43 files · +161 −69Browse files

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

Unified · Split

3 files
  1. libavfilter/af_afir.c +66 −18
  2. libavfilter/af_afir.h +4 −5
  3. libavfilter/afir_template.c +91 −46
libavfilter/af_afir.c+66−18
@@ -155,7 +155,7 @@ static int fir_frame(AudioFIRContext *s, AVFrame *in, AVFilterLink *outlink) · 154 unmodified lines
155 return ff_filter_frame(outlink, out);155 return ff_filter_frame(outlink, out);
156}156}
157 157
158static int init_segment(AVFilterContext *ctx, AudioFIRSegment *seg,158static int init_segment(AVFilterContext *ctx, AudioFIRSegment *seg, int selir,
159 int offset, int nb_partitions, int part_size, int index)159 int offset, int nb_partitions, int part_size, int index)
160{160{
161 AudioFIRContext *s = ctx->priv;161 AudioFIRContext *s = ctx->priv;
@@ -221,12 +221,10 @@ static int init_segment(AVFilterContext *ctx, AudioFIRSegment *seg, · 59 unmodified lines
221 seg->tempin = ff_get_audio_buffer(ctx->inputs[0], seg->block_size);221 seg->tempin = ff_get_audio_buffer(ctx->inputs[0], seg->block_size);
222 seg->tempout = ff_get_audio_buffer(ctx->inputs[0], seg->block_size);222 seg->tempout = ff_get_audio_buffer(ctx->inputs[0], seg->block_size);
223 seg->buffer = ff_get_audio_buffer(ctx->inputs[0], seg->part_size);223 seg->buffer = ff_get_audio_buffer(ctx->inputs[0], seg->part_size);
224 seg->coeff = ff_get_audio_buffer(ctx->inputs[0], seg->nb_partitions * seg->coeff_size * 2);
225 seg->input = ff_get_audio_buffer(ctx->inputs[0], seg->input_size);224 seg->input = ff_get_audio_buffer(ctx->inputs[0], seg->input_size);
226 seg->output = ff_get_audio_buffer(ctx->inputs[0], seg->part_size);225 seg->output = ff_get_audio_buffer(ctx->inputs[0], seg->part_size * 5);
227 seg->loaded = ff_get_audio_buffer(ctx->inputs[0], seg->nb_partitions);
228 if (!seg->buffer || !seg->sumin || !seg->sumout || !seg->blockout ||226 if (!seg->buffer || !seg->sumin || !seg->sumout || !seg->blockout ||
229 !seg->coeff || !seg->input || !seg->output || !seg->loaded || !seg->tempin || !seg->tempout)227 !seg->input || !seg->output || !seg->tempin || !seg->tempout)
230 return AVERROR(ENOMEM);228 return AVERROR(ENOMEM);
231 229
232 return 0;230 return 0;
@@ -264,18 +262,18 @@ static void uninit_segment(AVFilterContext *ctx, AudioFIRSegment *seg) · 31 unmodified lines
264 av_frame_free(&seg->sumin);262 av_frame_free(&seg->sumin);
265 av_frame_free(&seg->sumout);263 av_frame_free(&seg->sumout);
266 av_frame_free(&seg->buffer);264 av_frame_free(&seg->buffer);
267 av_frame_free(&seg->coeff);
268 av_frame_free(&seg->input);265 av_frame_free(&seg->input);
269 av_frame_free(&seg->output);266 av_frame_free(&seg->output);
270 av_frame_free(&seg->loaded);
271 seg->input_size = 0;267 seg->input_size = 0;
268
269 for (int i = 0; i < MAX_IR_STREAMS; i++)
270 av_frame_free(&seg->coeff[i]);
272}271}
273 272
274static int convert_coeffs(AVFilterContext *ctx, int selir)273static int convert_coeffs(AVFilterContext *ctx, int selir)
275{274{
276 AudioFIRContext *s = ctx->priv;275 AudioFIRContext *s = ctx->priv;
277 const int prev_selir = s->prev_selir;276 int ret, nb_taps, cur_nb_taps;
278 int ret, nb_taps, cur_nb_taps, prev_nb_taps;
279 277
280 if (!s->nb_taps[selir]) {278 if (!s->nb_taps[selir]) {
281 int part_size, max_part_size;279 int part_size, max_part_size;
@@ -302,7 +300,7 @@ static int convert_coeffs(AVFilterContext *ctx, int selir) · 20 unmodified lines
302 int nb_partitions = FFMIN(step, (left + part_size - 1) / part_size);300 int nb_partitions = FFMIN(step, (left + part_size - 1) / part_size);
303 301
304 s->nb_segments = i + 1;302 s->nb_segments = i + 1;
305 ret = init_segment(ctx, &s->seg[i], offset, nb_partitions, part_size, i);303 ret = init_segment(ctx, &s->seg[i], selir, offset, nb_partitions, part_size, i);
306 if (ret < 0)304 if (ret < 0)
307 return ret;305 return ret;
308 offset += nb_partitions * part_size;306 offset += nb_partitions * part_size;
@@ -333,19 +331,68 @@ skip: · 24 unmodified lines
333 }331 }
334 332
335 cur_nb_taps = s->ir[selir]->nb_samples;333 cur_nb_taps = s->ir[selir]->nb_samples;
336 prev_nb_taps = s->ir[prev_selir]->nb_samples;334 nb_taps = cur_nb_taps;
337 nb_taps = FFMAX(cur_nb_taps, prev_nb_taps);
338 335
339 if (!s->norm_ir || s->norm_ir->nb_samples < nb_taps) {336 if (!s->norm_ir[selir] || s->norm_ir[selir]->nb_samples < nb_taps) {
340 av_frame_free(&s->norm_ir);337 av_frame_free(&s->norm_ir[selir]);
341 s->norm_ir = ff_get_audio_buffer(ctx->inputs[0], FFALIGN(nb_taps, 8));338 s->norm_ir[selir] = ff_get_audio_buffer(ctx->inputs[0], FFALIGN(nb_taps, 8));
342 if (!s->norm_ir)339 if (!s->norm_ir[selir])
343 return AVERROR(ENOMEM);340 return AVERROR(ENOMEM);
344 }341 }
345 342
346 av_log(ctx, AV_LOG_DEBUG, "nb_taps: %d\n", cur_nb_taps);343 av_log(ctx, AV_LOG_DEBUG, "nb_taps: %d\n", cur_nb_taps);
347 av_log(ctx, AV_LOG_DEBUG, "nb_segments: %d\n", s->nb_segments);344 av_log(ctx, AV_LOG_DEBUG, "nb_segments: %d\n", s->nb_segments);
348 345
346 switch (s->format) {
347 case AV_SAMPLE_FMT_FLTP:
348 for (int ch = 0; ch < s->nb_channels; ch++) {
349 const float *tsrc = (const float *)s->ir[selir]->extended_data[!s->one2many * ch];
350 float *time = (float *)s->norm_ir[selir]->extended_data[ch];
351
352 memcpy(time, tsrc, sizeof(*time) * nb_taps);
353 for (int i = FFMAX(1, s->length * nb_taps); i < nb_taps; i++)
354 time[i] = 0;
355
356 get_power_float(ctx, s, nb_taps, ch, time);
357
358 for (int n = 0; n < s->nb_segments; n++) {
359 AudioFIRSegment *seg = &s->seg[n];
360
361 if (!seg->coeff[selir])
362 seg->coeff[selir] = ff_get_audio_buffer(ctx->inputs[0], seg->nb_partitions * seg->coeff_size * 2);
363 if (!seg->coeff[selir])
364 return AVERROR(ENOMEM);
365
366 for (int i = 0; i < seg->nb_partitions; i++)
367 convert_channel_float(ctx, s, ch, seg, i, selir);
368 }
369 }
370 break;
371 case AV_SAMPLE_FMT_DBLP:
372 for (int ch = 0; ch < s->nb_channels; ch++) {
373 const double *tsrc = (const double *)s->ir[selir]->extended_data[!s->one2many * ch];
374 double *time = (double *)s->norm_ir[selir]->extended_data[ch];
375
376 memcpy(time, tsrc, sizeof(*time) * nb_taps);
377 for (int i = FFMAX(1, s->length * nb_taps); i < nb_taps; i++)
378 time[i] = 0;
379
380 get_power_double(ctx, s, nb_taps, ch, time);
381 for (int n = 0; n < s->nb_segments; n++) {
382 AudioFIRSegment *seg = &s->seg[n];
383
384 if (!seg->coeff[selir])
385 seg->coeff[selir] = ff_get_audio_buffer(ctx->inputs[0], seg->nb_partitions * seg->coeff_size * 2);
386 if (!seg->coeff[selir])
387 return AVERROR(ENOMEM);
388
389 for (int i = 0; i < seg->nb_partitions; i++)
390 convert_channel_double(ctx, s, ch, seg, i, selir);
391 }
392 }
393 break;
394 }
395
349 s->have_coeffs[selir] = 1;396 s->have_coeffs[selir] = 1;
350 397
351 return 0;398 return 0;
@@ -536,9 +583,10 @@ static av_cold void uninit(AVFilterContext *ctx) · 184 unmodified lines
536 583
537 av_freep(&s->fdsp);584 av_freep(&s->fdsp);
538 585
539 av_frame_free(&s->norm_ir);586 for (int i = 0; i < s->nb_irs; i++) {
540 for (int i = 0; i < s->nb_irs; i++)
541 av_frame_free(&s->ir[i]);587 av_frame_free(&s->ir[i]);
588 av_frame_free(&s->norm_ir[i]);
589 }
542 590
543 av_frame_free(&s->video);591 av_frame_free(&s->video);
544}592}
libavfilter/af_afir.h+4−5
@@ -28,6 +28,8 @@ · 27 unmodified lines
28#include "avfilter.h"28#include "avfilter.h"
29#include "af_afirdsp.h"29#include "af_afirdsp.h"
30 30
31#define MAX_IR_STREAMS 32
32
31typedef struct AudioFIRSegment {33typedef struct AudioFIRSegment {
32 int nb_partitions;34 int nb_partitions;
33 int part_size;35 int part_size;
@@ -47,17 +49,14 @@ typedef struct AudioFIRSegment { · 13 unmodified lines
47 AVFrame *tempin;49 AVFrame *tempin;
48 AVFrame *tempout;50 AVFrame *tempout;
49 AVFrame *buffer;51 AVFrame *buffer;
50 AVFrame *coeff;52 AVFrame *coeff[MAX_IR_STREAMS];
51 AVFrame *input;53 AVFrame *input;
52 AVFrame *output;54 AVFrame *output;
53 AVFrame *loaded;
54 55
55 AVTXContext **ctx, **tx, **itx;56 AVTXContext **ctx, **tx, **itx;
56 av_tx_fn ctx_fn, tx_fn, itx_fn;57 av_tx_fn ctx_fn, tx_fn, itx_fn;
57} AudioFIRSegment;58} AudioFIRSegment;
58 59
59#define MAX_IR_STREAMS 32
60
61typedef struct AudioFIRContext {60typedef struct AudioFIRContext {
62 const AVClass *class;61 const AVClass *class;
63 62
@@ -91,7 +90,7 @@ typedef struct AudioFIRContext { · 27 unmodified lines
91 90
92 AVFrame *in;91 AVFrame *in;
93 AVFrame *ir[MAX_IR_STREAMS];92 AVFrame *ir[MAX_IR_STREAMS];
94 AVFrame *norm_ir;93 AVFrame *norm_ir[MAX_IR_STREAMS];
95 AVFrame *video;94 AVFrame *video;
96 int min_part_size;95 int min_part_size;
97 int64_t pts;96 int64_t pts;
libavfilter/afir_template.c+91−46
@@ -141,7 +141,8 @@ end: · 140 unmodified lines
141}141}
142 142
143static int fn(get_power)(AVFilterContext *ctx, AudioFIRContext *s,143static int fn(get_power)(AVFilterContext *ctx, AudioFIRContext *s,
144 int cur_nb_taps, int ch)144 int cur_nb_taps, int ch,
145 ftype *time)
145{146{
146 ftype ch_gain = 1;147 ftype ch_gain = 1;
147 148
@@ -151,7 +152,6 @@ static int fn(get_power)(AVFilterContext *ctx, AudioFIRContext *s, · 3 unmodified lines
151 break;152 break;
152 case 0:153 case 0:
153 {154 {
154 ftype *time = (ftype *)s->norm_ir->extended_data[ch];
155 ftype sum = 0;155 ftype sum = 0;
156 156
157 for (int i = 0; i < cur_nb_taps; i++)157 for (int i = 0; i < cur_nb_taps; i++)
@@ -161,7 +161,6 @@ static int fn(get_power)(AVFilterContext *ctx, AudioFIRContext *s, · 3 unmodified lines
161 break;161 break;
162 case 1:162 case 1:
163 {163 {
164 ftype *time = (ftype *)s->norm_ir->extended_data[ch];
165 ftype sum = 0;164 ftype sum = 0;
166 165
167 for (int i = 0; i < cur_nb_taps; i++)166 for (int i = 0; i < cur_nb_taps; i++)
@@ -171,7 +170,6 @@ static int fn(get_power)(AVFilterContext *ctx, AudioFIRContext *s, · 3 unmodified lines
171 break;170 break;
172 case 2:171 case 2:
173 {172 {
174 ftype *time = (ftype *)s->norm_ir->extended_data[ch];
175 ftype sum = 0;173 ftype sum = 0;
176 174
177 for (int i = 0; i < cur_nb_taps; i++)175 for (int i = 0; i < cur_nb_taps; i++)
@@ -182,7 +180,7 @@ static int fn(get_power)(AVFilterContext *ctx, AudioFIRContext *s, · 4 unmodified lines
182 case 3:180 case 3:
183 case 4:181 case 4:
184 {182 {
185 ftype *inc, *outc, scale;183 ftype *inc, *outc, scale, power;
186 AVTXContext *tx;184 AVTXContext *tx;
187 av_tx_fn tx_fn;185 av_tx_fn tx_fn;
188 int ret, size;186 int ret, size;
@@ -205,7 +203,6 @@ static int fn(get_power)(AVFilterContext *ctx, AudioFIRContext *s, · 16 unmodified lines
205 }203 }
206 204
207 {205 {
208 ftype power, *time = (ftype *)s->norm_ir->extended_data[ch];
209 memcpy(inc, time, cur_nb_taps * sizeof(SAMPLE_FORMAT));206 memcpy(inc, time, cur_nb_taps * sizeof(SAMPLE_FORMAT));
210 tx_fn(tx, outc, inc, sizeof(SAMPLE_FORMAT));207 tx_fn(tx, outc, inc, sizeof(SAMPLE_FORMAT));
211 208
@@ -233,7 +230,6 @@ static int fn(get_power)(AVFilterContext *ctx, AudioFIRContext *s, · 21 unmodified lines
233 }230 }
234 231
235 if (ch_gain != 1. || s->ir_gain != 1.) {232 if (ch_gain != 1. || s->ir_gain != 1.) {
236 ftype *time = (ftype *)s->norm_ir->extended_data[ch];
237 ftype gain = ch_gain * s->ir_gain;233 ftype gain = ch_gain * s->ir_gain;
238 234
239 av_log(ctx, AV_LOG_DEBUG, "ch%d gain %f\n", ch, gain);235 av_log(ctx, AV_LOG_DEBUG, "ch%d gain %f\n", ch, gain);
@@ -248,45 +244,24 @@ static int fn(get_power)(AVFilterContext *ctx, AudioFIRContext *s, · 8 unmodified lines
248}244}
249 245
250static void fn(convert_channel)(AVFilterContext *ctx, AudioFIRContext *s, int ch,246static void fn(convert_channel)(AVFilterContext *ctx, AudioFIRContext *s, int ch,
251 AudioFIRSegment *seg)247 AudioFIRSegment *seg, int coeff_partition, int selir)
252{248{
253 const int coeff_partition = seg->loading[ch];
254 const int coffset = coeff_partition * seg->coeff_size;249 const int coffset = coeff_partition * seg->coeff_size;
255 const int selir = s->selir;
256 const int nb_taps = s->nb_taps[selir];250 const int nb_taps = s->nb_taps[selir];
257 ftype *tsrc = (ftype *)s->ir[selir]->extended_data[!s->one2many * ch];251 ftype *time = (ftype *)s->norm_ir[selir]->extended_data[ch];
258 ftype *time = (ftype *)s->norm_ir->extended_data[ch];
259 ftype *tempin = (ftype *)seg->tempin->extended_data[ch];252 ftype *tempin = (ftype *)seg->tempin->extended_data[ch];
260 ftype *tempout = (ftype *)seg->tempout->extended_data[ch];253 ftype *tempout = (ftype *)seg->tempout->extended_data[ch];
261 ctype *coeff = (ctype *)seg->coeff->extended_data[ch];254 ctype *coeff = (ctype *)seg->coeff[selir]->extended_data[ch];
262 int *loaded = (int *)seg->loaded->extended_data[ch];
263 const int remaining = nb_taps - (seg->input_offset + coeff_partition * seg->part_size);255 const int remaining = nb_taps - (seg->input_offset + coeff_partition * seg->part_size);
264 const int size = remaining >= seg->part_size ? seg->part_size : remaining;256 const int size = remaining >= seg->part_size ? seg->part_size : remaining;
265 257
266 if (loaded[coeff_partition] == selir + 1)
267 return;
268 loaded[coeff_partition] = selir + 1;
269
270 memcpy(time, tsrc, sizeof(*time) * nb_taps);
271 for (int i = FFMAX(1, s->length * nb_taps); i < nb_taps; i++)
272 time[i] = 0;
273
274#if DEPTH == 32
275 get_power_float(ctx, s, nb_taps, ch);
276#else
277 get_power_double(ctx, s, nb_taps, ch);
278#endif
279
280 av_log(ctx, AV_LOG_DEBUG, "channel: %d\n", ch);
281
282 memset(tempin + size, 0, sizeof(*tempin) * (seg->block_size - size));258 memset(tempin + size, 0, sizeof(*tempin) * (seg->block_size - size));
283 memcpy(tempin, time + seg->input_offset + coeff_partition * seg->part_size,259 memcpy(tempin, time + seg->input_offset + coeff_partition * seg->part_size,
284 size * sizeof(*tempin));260 size * sizeof(*tempin));
285
286 seg->ctx_fn(seg->ctx[ch], tempout, tempin, sizeof(*tempin));261 seg->ctx_fn(seg->ctx[ch], tempout, tempin, sizeof(*tempin));
287
288 memcpy(coeff + coffset, tempout, seg->coeff_size * sizeof(*coeff));262 memcpy(coeff + coffset, tempout, seg->coeff_size * sizeof(*coeff));
289 263
264 av_log(ctx, AV_LOG_DEBUG, "channel: %d\n", ch);
290 av_log(ctx, AV_LOG_DEBUG, "nb_partitions: %d\n", seg->nb_partitions);265 av_log(ctx, AV_LOG_DEBUG, "nb_partitions: %d\n", seg->nb_partitions);
291 av_log(ctx, AV_LOG_DEBUG, "partition size: %d\n", seg->part_size);266 av_log(ctx, AV_LOG_DEBUG, "partition size: %d\n", seg->part_size);
292 av_log(ctx, AV_LOG_DEBUG, "block size: %d\n", seg->block_size);267 av_log(ctx, AV_LOG_DEBUG, "block size: %d\n", seg->block_size);
@@ -314,11 +289,12 @@ static int fn(fir_quantum)(AVFilterContext *ctx, AVFrame *out, int ch, int offse · 21 unmodified lines
314{289{
315 AudioFIRContext *s = ctx->priv;290 AudioFIRContext *s = ctx->priv;
316 const ftype *in = (const ftype *)s->in->extended_data[ch] + offset;291 const ftype *in = (const ftype *)s->in->extended_data[ch] + offset;
317 ftype *blockout, *buf, *ptr = (ftype *)out->extended_data[ch] + offset;292 ftype *blockout, *ptr = (ftype *)out->extended_data[ch] + offset;
318 const int min_part_size = s->min_part_size;293 const int min_part_size = s->min_part_size;
319 const int nb_samples = FFMIN(min_part_size, out->nb_samples - offset);294 const int nb_samples = FFMIN(min_part_size, out->nb_samples - offset);
320 const int nb_segments = s->nb_segments;295 const int nb_segments = s->nb_segments;
321 const float dry_gain = s->dry_gain;296 const float dry_gain = s->dry_gain;
297 const int selir = s->selir;
322 298
323 for (int segment = 0; segment < nb_segments; segment++) {299 for (int segment = 0; segment < nb_segments; segment++) {
324 AudioFIRSegment *seg = &s->seg[segment];300 AudioFIRSegment *seg = &s->seg[segment];
@@ -327,6 +303,7 @@ static int fn(fir_quantum)(AVFilterContext *ctx, AVFrame *out, int ch, int offse · 2 unmodified lines
327 ftype *sumin = (ftype *)seg->sumin->extended_data[ch];303 ftype *sumin = (ftype *)seg->sumin->extended_data[ch];
328 ftype *sumout = (ftype *)seg->sumout->extended_data[ch];304 ftype *sumout = (ftype *)seg->sumout->extended_data[ch];
329 ftype *tempin = (ftype *)seg->tempin->extended_data[ch];305 ftype *tempin = (ftype *)seg->tempin->extended_data[ch];
306 ftype *buf = (ftype *)seg->buffer->extended_data[ch];
330 int *output_offset = &seg->output_offset[ch];307 int *output_offset = &seg->output_offset[ch];
331 const int nb_partitions = seg->nb_partitions;308 const int nb_partitions = seg->nb_partitions;
332 const int input_offset = seg->input_offset;309 const int input_offset = seg->input_offset;
@@ -359,28 +336,71 @@ static int fn(fir_quantum)(AVFilterContext *ctx, AVFrame *out, int ch, int offse · 26 unmodified lines
359 }336 }
360 337
361 memset(sumin, 0, sizeof(*sumin) * seg->fft_length);338 memset(sumin, 0, sizeof(*sumin) * seg->fft_length);
339
340 if (seg->loading[ch] < nb_partitions) {
341 j = seg->part_index[ch] <= 0 ? nb_partitions - 1 : seg->part_index[ch] - 1;
342 for (int i = 0; i < nb_partitions; i++) {
343 const int input_partition = j;
344 const int coeff_partition = i;
345 const int coffset = coeff_partition * seg->coeff_size;
346 const ftype *blockout = (const ftype *)seg->blockout->extended_data[ch] + input_partition * seg->block_size;
347 const ctype *coeff = ((const ctype *)seg->coeff[selir]->extended_data[ch]) + coffset;
348
349 if (j == 0)
350 j = nb_partitions;
351 j--;
352
353#if DEPTH == 32
354 s->afirdsp.fcmul_add(sumin, blockout, (const ftype *)coeff, part_size);
355#else
356 s->afirdsp.dcmul_add(sumin, blockout, (const ftype *)coeff, part_size);
357#endif
358 }
359
360 seg->itx_fn(seg->itx[ch], sumout, sumin, sizeof(ctype));
361 memcpy(dst + part_size, sumout + part_size, part_size * sizeof(*buf));
362 memset(sumin, 0, sizeof(*sumin) * seg->fft_length);
363 }
364
362 blockout = (ftype *)seg->blockout->extended_data[ch] + seg->part_index[ch] * seg->block_size;365 blockout = (ftype *)seg->blockout->extended_data[ch] + seg->part_index[ch] * seg->block_size;
363 memset(tempin + part_size, 0, sizeof(*tempin) * (seg->block_size - part_size));366 memset(tempin + part_size, 0, sizeof(*tempin) * (seg->block_size - part_size));
364 memcpy(tempin, src, sizeof(*src) * part_size);367 memcpy(tempin, src, sizeof(*src) * part_size);
365
366 seg->tx_fn(seg->tx[ch], blockout, tempin, sizeof(ftype));368 seg->tx_fn(seg->tx[ch], blockout, tempin, sizeof(ftype));
367 369
368 j = seg->part_index[ch];
369 if (seg->loading[ch] < nb_partitions) {370 if (seg->loading[ch] < nb_partitions) {
371 const int selir = s->prev_selir;
372
373 j = seg->part_index[ch];
374 for (int i = 0; i < nb_partitions; i++) {
375 const int input_partition = j;
376 const int coeff_partition = i;
377 const int coffset = coeff_partition * seg->coeff_size;
378 const ftype *blockout = (const ftype *)seg->blockout->extended_data[ch] + input_partition * seg->block_size;
379 const ctype *coeff = ((const ctype *)seg->coeff[selir]->extended_data[ch]) + coffset;
380
381 if (j == 0)
382 j = nb_partitions;
383 j--;
384
370#if DEPTH == 32385#if DEPTH == 32
371 convert_channel_float(ctx, s, ch, seg);386 s->afirdsp.fcmul_add(sumin, blockout, (const ftype *)coeff, part_size);
372#else387#else
373 convert_channel_double(ctx, s, ch, seg);388 s->afirdsp.dcmul_add(sumin, blockout, (const ftype *)coeff, part_size);
374#endif389#endif
375 seg->loading[ch]++;390 }
391
392 seg->itx_fn(seg->itx[ch], sumout, sumin, sizeof(ctype));
393 memcpy(dst + 2 * part_size, sumout, 2 * part_size * sizeof(*dst));
394 memset(sumin, 0, sizeof(*sumin) * seg->fft_length);
376 }395 }
377 396
397 j = seg->part_index[ch];
378 for (int i = 0; i < nb_partitions; i++) {398 for (int i = 0; i < nb_partitions; i++) {
379 const int input_partition = j;399 const int input_partition = j;
380 const int coeff_partition = i;400 const int coeff_partition = i;
381 const int coffset = coeff_partition * seg->coeff_size;401 const int coffset = coeff_partition * seg->coeff_size;
382 const ftype *blockout = (const ftype *)seg->blockout->extended_data[ch] + input_partition * seg->block_size;402 const ftype *blockout = (const ftype *)seg->blockout->extended_data[ch] + input_partition * seg->block_size;
383 const ctype *coeff = ((const ctype *)seg->coeff->extended_data[ch]) + coffset;403 const ctype *coeff = ((const ctype *)seg->coeff[selir]->extended_data[ch]) + coffset;
384 404
385 if (j == 0)405 if (j == 0)
386 j = nb_partitions;406 j = nb_partitions;
@@ -395,18 +415,43 @@ static int fn(fir_quantum)(AVFilterContext *ctx, AVFrame *out, int ch, int offse · 8 unmodified lines
395 415
396 seg->itx_fn(seg->itx[ch], sumout, sumin, sizeof(ctype));416 seg->itx_fn(seg->itx[ch], sumout, sumin, sizeof(ctype));
397 417
398 buf = (ftype *)seg->buffer->extended_data[ch];418 if (seg->loading[ch] < nb_partitions) {
399 fn(fir_fadd)(s, buf, sumout, part_size);419 ftype *ptr1 = dst + part_size;
400 420 ftype *ptr2 = dst + part_size * 2;
401 memcpy(dst, buf, part_size * sizeof(*dst));421 ftype *ptr3 = dst + part_size * 3;
402 memcpy(buf, sumout + part_size, part_size * sizeof(*buf));422 ftype *ptr4 = dst + part_size * 4;
423 if (seg->loading[ch] == 0)
424 memcpy(ptr4, buf, sizeof(*ptr4) * part_size);
425 for (int n = 0; n < part_size; n++)
426 ptr2[n] += ptr4[n];
427
428 if (seg->loading[ch] < nb_partitions - 1)
429 memcpy(ptr4, ptr3, part_size * sizeof(*dst));
430 for (int n = 0; n < part_size; n++)
431 ptr1[n] += sumout[n];
432
433 if (seg->loading[ch] == nb_partitions - 1)
434 memcpy(buf, sumout + part_size, part_size * sizeof(*buf));
435
436 for (int i = 0; i < part_size; i++) {
437 const ftype factor = (part_size * seg->loading[ch] + i) / (ftype)(part_size * nb_partitions);
438 const ftype ifactor = 1 - factor;
439 dst[i] = ptr1[i] * factor + ptr2[i] * ifactor;
440 }
441 } else {
442 fn(fir_fadd)(s, buf, sumout, part_size);
443 memcpy(dst, buf, part_size * sizeof(*dst));
444 memcpy(buf, sumout + part_size, part_size * sizeof(*buf));
445 }
403 446
404 seg->part_index[ch] = (seg->part_index[ch] + 1) % nb_partitions;447 fn(fir_fadd)(s, ptr, dst, nb_samples);
405 448
406 if (part_size != min_part_size)449 if (part_size != min_part_size)
407 memmove(src, src + min_part_size, (seg->input_size - min_part_size) * sizeof(*src));450 memmove(src, src + min_part_size, (seg->input_size - min_part_size) * sizeof(*src));
408 451
409 fn(fir_fadd)(s, ptr, dst, nb_samples);452 seg->part_index[ch] = (seg->part_index[ch] + 1) % nb_partitions;
453 if (seg->loading[ch] < nb_partitions)
454 seg->loading[ch]++;
410 }455 }
411 456
412 if (s->wet_gain == 1.f)457 if (s->wet_gain == 1.f)

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