From 7312e027d6d3b8aa8220cceacd29c85c87292906 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Fri, 28 Dec 2018 17:57:24 +0100 Subject: avfilter/af_afir: introduce AudioFIRSegment structure and use it --- libavfilter/af_afir.c | 161 ++++++++++++++++++++++---------------------------- 1 file changed, 69 insertions(+), 92 deletions(-) (limited to 'libavfilter/af_afir.c') diff --git a/libavfilter/af_afir.c b/libavfilter/af_afir.c index 65737e05b1..89d7ed6c85 100644 --- a/libavfilter/af_afir.c +++ b/libavfilter/af_afir.c @@ -60,41 +60,41 @@ static int fir_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs) { AudioFIRContext *s = ctx->priv; const float *src = (const float *)s->in[0]->extended_data[ch]; - float *sum = s->sum[ch]; + float *sum = (float *)s->seg.sum->extended_data[ch]; AVFrame *out = arg; float *block, *dst, *ptr; int n, i, j; - memset(sum, 0, sizeof(*sum) * s->fft_length); - block = s->block[ch] + s->part_index * s->block_size; - memset(block, 0, sizeof(*block) * s->fft_length); + memset(sum, 0, sizeof(*sum) * s->seg.fft_length); + block = (float *)s->seg.block->extended_data[ch] + s->seg.part_index * s->seg.block_size; + memset(block, 0, sizeof(*block) * s->seg.fft_length); s->fdsp->vector_fmul_scalar(block, src, s->dry_gain, FFALIGN(out->nb_samples, 4)); emms_c(); - av_rdft_calc(s->rdft[ch], block); - block[2 * s->part_size] = block[1]; + av_rdft_calc(s->seg.rdft[ch], block); + block[2 * s->seg.part_size] = block[1]; block[1] = 0; - j = s->part_index; + j = s->seg.part_index; - for (i = 0; i < s->nb_partitions; i++) { - const int coffset = i * s->coeff_size; - const FFTComplex *coeff = s->coeff[ch * !s->one2many] + coffset; + for (i = 0; i < s->seg.nb_partitions; i++) { + const int coffset = i * s->seg.coeff_size; + const float *block = (const float *)s->seg.block->extended_data[ch] + j * s->seg.block_size; + const FFTComplex *coeff = s->seg.coeff[ch * !s->one2many] + coffset; - block = s->block[ch] + j * s->block_size; - s->fcmul_add(sum, block, (const float *)coeff, s->part_size); + s->fcmul_add(sum, block, (const float *)coeff, s->seg.part_size); if (j == 0) - j = s->nb_partitions; + j = s->seg.nb_partitions; j--; } - sum[1] = sum[2 * s->part_size]; - av_rdft_calc(s->irdft[ch], sum); + sum[1] = sum[2 * s->seg.part_size]; + av_rdft_calc(s->seg.irdft[ch], sum); - dst = (float *)s->buffer->extended_data[ch]; - for (n = 0; n < s->part_size; n++) { + dst = (float *)s->seg.buffer->extended_data[ch]; + for (n = 0; n < s->seg.part_size; n++) { dst[n] += sum[n]; } @@ -102,8 +102,8 @@ static int fir_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs) s->fdsp->vector_fmul_scalar(ptr, dst, s->wet_gain, FFALIGN(out->nb_samples, 4)); emms_c(); - dst = (float *)s->buffer->extended_data[ch]; - memcpy(dst, sum + s->part_size, s->part_size * sizeof(*dst)); + dst = (float *)s->seg.buffer->extended_data[ch]; + memcpy(dst, sum + s->seg.part_size, s->seg.part_size * sizeof(*dst)); return 0; } @@ -124,7 +124,7 @@ static int fir_frame(AudioFIRContext *s, AVFrame *in, AVFilterLink *outlink) s->in[0] = in; ctx->internal->execute(ctx, fir_channel, out, NULL, outlink->channels); - s->part_index = (s->part_index + 1) % s->nb_partitions; + s->seg.part_index = (s->seg.part_index + 1) % s->seg.nb_partitions; out->pts = s->pts; if (s->pts != AV_NOPTS_VALUE) @@ -286,39 +286,29 @@ static int convert_coeffs(AVFilterContext *ctx) for (n = av_log2(s->minp); (1 << n) < s->nb_taps; n++); N = FFMIN(n, av_log2(s->maxp)); - s->fft_length = (1 << (N + 1)) + 1; - s->part_size = 1 << (N - 1); - s->block_size = FFALIGN(s->fft_length, 32); - s->coeff_size = FFALIGN(s->part_size + 1, 32); - s->nb_partitions = (s->nb_taps + s->part_size - 1) / s->part_size; - - for (ch = 0; ch < ctx->inputs[0]->channels; ch++) { - s->sum[ch] = av_calloc(s->fft_length, sizeof(**s->sum)); - if (!s->sum[ch]) - return AVERROR(ENOMEM); - } + s->seg.fft_length = (1 << (N + 1)) + 1; + s->seg.part_size = 1 << (N - 1); + s->seg.block_size = FFALIGN(s->seg.fft_length, 32); + s->seg.coeff_size = FFALIGN(s->seg.part_size + 1, 32); + s->seg.nb_partitions = (s->nb_taps + s->seg.part_size - 1) / s->seg.part_size; for (ch = 0; ch < ctx->inputs[1]->channels; ch++) { - s->coeff[ch] = av_calloc(s->nb_partitions * s->coeff_size, sizeof(**s->coeff)); - if (!s->coeff[ch]) + s->seg.coeff[ch] = av_calloc(s->seg.nb_partitions * s->seg.coeff_size, sizeof(**s->seg.coeff)); + if (!s->seg.coeff[ch]) return AVERROR(ENOMEM); } for (ch = 0; ch < ctx->inputs[0]->channels; ch++) { - s->block[ch] = av_calloc(s->nb_partitions * s->block_size, sizeof(**s->block)); - if (!s->block[ch]) + s->seg.rdft[ch] = av_rdft_init(N, DFT_R2C); + s->seg.irdft[ch] = av_rdft_init(N, IDFT_C2R); + if (!s->seg.rdft[ch] || !s->seg.irdft[ch]) return AVERROR(ENOMEM); } - for (ch = 0; ch < ctx->inputs[0]->channels; ch++) { - s->rdft[ch] = av_rdft_init(N, DFT_R2C); - s->irdft[ch] = av_rdft_init(N, IDFT_C2R); - if (!s->rdft[ch] || !s->irdft[ch]) - return AVERROR(ENOMEM); - } - - s->buffer = ff_get_audio_buffer(ctx->inputs[0], s->part_size); - if (!s->buffer) + s->seg.sum = ff_get_audio_buffer(ctx->inputs[0], s->seg.fft_length); + s->seg.block = ff_get_audio_buffer(ctx->inputs[0], s->seg.nb_partitions * s->seg.block_size); + s->seg.buffer = ff_get_audio_buffer(ctx->inputs[0], s->seg.part_size); + if (!s->seg.buffer || !s->seg.sum || !s->seg.block) return AVERROR(ENOMEM); ret = ff_inlink_consume_samples(ctx->inputs[1], s->nb_taps, s->nb_taps, &s->in[1]); @@ -377,40 +367,40 @@ static int convert_coeffs(AVFilterContext *ctx) for (ch = 0; ch < ctx->inputs[1]->channels; ch++) { float *time = (float *)s->in[1]->extended_data[!s->one2many * ch]; - float *block = s->block[ch]; - FFTComplex *coeff = s->coeff[ch]; + float *block = (float *)s->seg.block->extended_data[ch]; + FFTComplex *coeff = s->seg.coeff[ch]; for (i = FFMAX(1, s->length * s->nb_taps); i < s->nb_taps; i++) time[i] = 0; - for (i = 0; i < s->nb_partitions; i++) { - const float scale = 1.f / s->part_size; - const int toffset = i * s->part_size; - const int coffset = i * s->coeff_size; - const int remaining = s->nb_taps - (i * s->part_size); - const int size = remaining >= s->part_size ? s->part_size : remaining; + for (i = 0; i < s->seg.nb_partitions; i++) { + const float scale = 1.f / s->seg.part_size; + const int toffset = i * s->seg.part_size; + const int coffset = i * s->seg.coeff_size; + const int remaining = s->nb_taps - (i * s->seg.part_size); + const int size = remaining >= s->seg.part_size ? s->seg.part_size : remaining; - memset(block, 0, sizeof(*block) * s->fft_length); + memset(block, 0, sizeof(*block) * s->seg.fft_length); memcpy(block, time + toffset, size * sizeof(*block)); - av_rdft_calc(s->rdft[0], block); + av_rdft_calc(s->seg.rdft[0], block); coeff[coffset].re = block[0] * scale; coeff[coffset].im = 0; - for (n = 1; n < s->part_size; n++) { + for (n = 1; n < s->seg.part_size; n++) { coeff[coffset + n].re = block[2 * n] * scale; coeff[coffset + n].im = block[2 * n + 1] * scale; } - coeff[coffset + s->part_size].re = block[1] * scale; - coeff[coffset + s->part_size].im = 0; + coeff[coffset + s->seg.part_size].re = block[1] * scale; + coeff[coffset + s->seg.part_size].im = 0; } } av_frame_free(&s->in[1]); av_log(ctx, AV_LOG_DEBUG, "nb_taps: %d\n", s->nb_taps); - av_log(ctx, AV_LOG_DEBUG, "nb_partitions: %d\n", s->nb_partitions); - av_log(ctx, AV_LOG_DEBUG, "partition size: %d\n", s->part_size); - av_log(ctx, AV_LOG_DEBUG, "fft_length: %d\n", s->fft_length); + av_log(ctx, AV_LOG_DEBUG, "nb_partitions: %d\n", s->seg.nb_partitions); + av_log(ctx, AV_LOG_DEBUG, "partition size: %d\n", s->seg.part_size); + av_log(ctx, AV_LOG_DEBUG, "fft_length: %d\n", s->seg.fft_length); s->have_coeffs = 1; @@ -469,7 +459,7 @@ static int activate(AVFilterContext *ctx) return ret; } - ret = ff_inlink_consume_samples(ctx->inputs[0], s->part_size, s->part_size, &in); + ret = ff_inlink_consume_samples(ctx->inputs[0], s->seg.part_size, s->seg.part_size, &in); if (ret > 0) ret = fir_frame(s, in, outlink); @@ -486,7 +476,7 @@ static int activate(AVFilterContext *ctx) } } - if (ff_inlink_queued_samples(ctx->inputs[0]) >= s->part_size) { + if (ff_inlink_queued_samples(ctx->inputs[0]) >= s->seg.part_size) { ff_filter_set_ready(ctx, 10); return 0; } @@ -580,12 +570,10 @@ static int config_output(AVFilterLink *outlink) outlink->channel_layout = ctx->inputs[0]->channel_layout; outlink->channels = ctx->inputs[0]->channels; - s->sum = av_calloc(outlink->channels, sizeof(*s->sum)); - s->coeff = av_calloc(ctx->inputs[1]->channels, sizeof(*s->coeff)); - s->block = av_calloc(ctx->inputs[0]->channels, sizeof(*s->block)); - s->rdft = av_calloc(outlink->channels, sizeof(*s->rdft)); - s->irdft = av_calloc(outlink->channels, sizeof(*s->irdft)); - if (!s->sum || !s->coeff || !s->block || !s->rdft || !s->irdft) + s->seg.coeff = av_calloc(ctx->inputs[1]->channels, sizeof(*s->seg.coeff)); + s->seg.rdft = av_calloc(outlink->channels, sizeof(*s->seg.rdft)); + s->seg.irdft = av_calloc(outlink->channels, sizeof(*s->seg.irdft)); + if (!s->seg.coeff || !s->seg.rdft || !s->seg.irdft) return AVERROR(ENOMEM); s->nb_channels = outlink->channels; @@ -600,43 +588,32 @@ static av_cold void uninit(AVFilterContext *ctx) AudioFIRContext *s = ctx->priv; int ch; - if (s->sum) { - for (ch = 0; ch < s->nb_channels; ch++) { - av_freep(&s->sum[ch]); - } - } - av_freep(&s->sum); - - if (s->coeff) { + if (s->seg.coeff) { for (ch = 0; ch < s->nb_coef_channels; ch++) { - av_freep(&s->coeff[ch]); - } - } - av_freep(&s->coeff); - - if (s->block) { - for (ch = 0; ch < s->nb_channels; ch++) { - av_freep(&s->block[ch]); + av_freep(&s->seg.coeff[ch]); } } - av_freep(&s->block); + av_freep(&s->seg.coeff); - if (s->rdft) { + if (s->seg.rdft) { for (ch = 0; ch < s->nb_channels; ch++) { - av_rdft_end(s->rdft[ch]); + av_rdft_end(s->seg.rdft[ch]); } } - av_freep(&s->rdft); + av_freep(&s->seg.rdft); - if (s->irdft) { + if (s->seg.irdft) { for (ch = 0; ch < s->nb_channels; ch++) { - av_rdft_end(s->irdft[ch]); + av_rdft_end(s->seg.irdft[ch]); } } - av_freep(&s->irdft); + av_freep(&s->seg.irdft); av_frame_free(&s->in[1]); - av_frame_free(&s->buffer); + + av_frame_free(&s->seg.block); + av_frame_free(&s->seg.sum); + av_frame_free(&s->seg.buffer); av_freep(&s->fdsp); -- cgit v1.2.3