On 5/8/2017 7:00 PM, Paul B Mahol wrote: > Signed-off-by: Paul B Mahol <one...@gmail.com> > --- > configure | 2 + > doc/filters.texi | 23 ++ > libavfilter/Makefile | 1 + > libavfilter/af_afir.c | 535 > +++++++++++++++++++++++++++++++++++++++++ > libavfilter/af_afir.h | 82 +++++++ > libavfilter/allfilters.c | 1 + > libavfilter/x86/Makefile | 2 + > libavfilter/x86/af_afir.asm | 53 ++++ > libavfilter/x86/af_afir_init.c | 35 +++ > 9 files changed, 734 insertions(+) > create mode 100644 libavfilter/af_afir.c > create mode 100644 libavfilter/af_afir.h > create mode 100644 libavfilter/x86/af_afir.asm > create mode 100644 libavfilter/x86/af_afir_init.c > > diff --git a/configure b/configure > index 2e1786a..a46c375 100755 > --- a/configure > +++ b/configure > @@ -3081,6 +3081,8 @@ unix_protocol_select="network" > # filters > afftfilt_filter_deps="avcodec" > afftfilt_filter_select="fft" > +afir_filter_deps="avcodec" > +afir_filter_select="fft"
You also need to add avcodec to avfilter_deps in the corresponding section (Near the end of configure) when this filter is enabled. > amovie_filter_deps="avcodec avformat" > aresample_filter_deps="swresample" > ass_filter_deps="libass" > diff --git a/doc/filters.texi b/doc/filters.texi > index f431274..0efce9a 100644 > --- a/doc/filters.texi > +++ b/doc/filters.texi > @@ -878,6 +878,29 @@ afftfilt="1-clip((b/nb)*b,0,1)" > @end example > @end itemize > > +@section afir > + > +Apply an Arbitary Frequency Impulse Response filter. > + > +This filter uses second stream as FIR coefficients. > +If second stream holds single channel, it will be used > +for all input channels in first stream, otherwise > +number of channels in second stream must be same as > +number of channels in first stream. > + > +It accepts the following parameters: > + > +@table @option > +@item dry > +Set dry gain. This sets input gain. > + > +@item wet > +Set wet gain. This sets final output gain. > + > +@item length > +Set Impulse Response filter length. Default is 1, which means whole IR is > processed. > +@end table > + > @anchor{aformat} > @section aformat > > diff --git a/libavfilter/Makefile b/libavfilter/Makefile > index 0f99086..de5f992 100644 > --- a/libavfilter/Makefile > +++ b/libavfilter/Makefile > @@ -37,6 +37,7 @@ OBJS-$(CONFIG_AEMPHASIS_FILTER) += > af_aemphasis.o > OBJS-$(CONFIG_AEVAL_FILTER) += aeval.o > OBJS-$(CONFIG_AFADE_FILTER) += af_afade.o > OBJS-$(CONFIG_AFFTFILT_FILTER) += af_afftfilt.o window_func.o > +OBJS-$(CONFIG_AFIR_FILTER) += af_afir.o > OBJS-$(CONFIG_AFORMAT_FILTER) += af_aformat.o > OBJS-$(CONFIG_AGATE_FILTER) += af_agate.o > OBJS-$(CONFIG_AINTERLEAVE_FILTER) += f_interleave.o > diff --git a/libavfilter/af_afir.c b/libavfilter/af_afir.c > new file mode 100644 > index 0000000..eb59d53 > --- /dev/null > +++ b/libavfilter/af_afir.c > @@ -0,0 +1,535 @@ > +/* > + * Copyright (c) 2017 Paul B Mahol > + * > + * This file is part of FFmpeg. > + * > + * FFmpeg is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * FFmpeg is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with FFmpeg; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 > USA > + */ > + > +/** > + * @file > + * An arbitrary audio FIR filter > + */ > + > +#include "libavutil/audio_fifo.h" > +#include "libavutil/common.h" > +#include "libavutil/float_dsp.h" > +#include "libavutil/opt.h" > +#include "libavcodec/avfft.h" > + > +#include "audio.h" > +#include "avfilter.h" > +#include "formats.h" > +#include "internal.h" > +#include "af_afir.h" > + > +static void fcmul_add_c(float *sum, const float *t, const float *c, int len) ptrdiff_t for len. > +{ > + int n; > + > + for (n = 0; n < len; n++) { > + const float cre = c[2 * n ]; > + const float cim = c[2 * n + 1]; > + const float tre = t[2 * n ]; > + const float tim = t[2 * n + 1]; > + > + sum[2 * n ] += tre * cre - tim * cim; > + sum[2 * n + 1] += tre * cim + tim * cre; > + } > + > + sum[2 * n] += t[2 * n] * c[2 * n]; > +} [...] > +static int convert_coeffs(AVFilterContext *ctx) > +{ > + AudioFIRContext *s = ctx->priv; > + int i, ch, n, N; > + float power = 0; > + > + s->nb_taps = av_audio_fifo_size(s->fifo[1]); > + if (s->nb_taps <= 0) > + return AVERROR(EINVAL); > + > + for (n = 4; (1 << n) < s->nb_taps; n++); > + N = FFMIN(n, 16); > + s->ir_length = 1 << n; > + s->fft_length = (1 << (N + 1)) + 1; > + s->part_size = 1 << (N - 1); > + s->block_size = FFALIGN(s->fft_length, 16); > + s->coeff_size = FFALIGN(s->part_size + 1, 16); > + s->nb_partitions = (s->nb_taps + s->part_size - 1) / s->part_size; > + s->nb_coeffs = s->ir_length + s->nb_partitions; > + > + 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); > + } > + > + for (ch = 0; ch < ctx->inputs[1]->channels; ch++) { > + s->coeff[ch] = av_calloc(s->nb_partitions * s->coeff_size, > sizeof(**s->coeff)); Might be a good idea to add some padding since this is used in a SIMD function. Same with block below. [...] > diff --git a/libavfilter/x86/af_afir.asm b/libavfilter/x86/af_afir.asm > new file mode 100644 > index 0000000..b425055 > --- /dev/null > +++ b/libavfilter/x86/af_afir.asm > @@ -0,0 +1,53 @@ > +;***************************************************************************** > +;* x86-optimized functions for afir filter > +;* Copyright (c) 2017 Paul B Mahol > +;* > +;* This file is part of FFmpeg. > +;* > +;* FFmpeg is free software; you can redistribute it and/or > +;* modify it under the terms of the GNU Lesser General Public > +;* License as published by the Free Software Foundation; either > +;* version 2.1 of the License, or (at your option) any later version. > +;* > +;* FFmpeg is distributed in the hope that it will be useful, > +;* but WITHOUT ANY WARRANTY; without even the implied warranty of > +;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > +;* Lesser General Public License for more details. > +;* > +;* You should have received a copy of the GNU Lesser General Public > +;* License along with FFmpeg; if not, write to the Free Software > +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 > USA > +;****************************************************************************** > + > +%include "libavutil/x86/x86util.asm" > + > +SECTION_RODATA 32 Unused > + > +SECTION .text > + > +;------------------------------------------------------------------------------ > +; void ff_fcmul_add(float *sum, const float *t, const float *c, int len) > +;------------------------------------------------------------------------------ > + > +INIT_XMM sse3 You can add an YMM avx version as well. > +cglobal fcmul_add, 4,4,3, sum, t, c, len > + shl lend, 3 > + add lend, mmsize > + add tq, lenq > + add cq, lenq > + add sumq, lenq > + neg lenq > +ALIGN 16 > +.loop: > + movsldup m0, [tq + lenq] > + movaps m1, [cq + lenq] > + mulps m0, m1 > + shufps m1, m1, 0xb1 For AVX you'll have to change this into shufps m1, m1, m1, 0xb1, or yasm will fail to assemble it. Probably a bug in yasm or x86inc. > + movshdup m2, [tq + lenq] > + mulps m2, m1 > + addsubps m0, m2; Stray ; > + addps m0, [sumq + lenq] > + movaps [sumq + lenq], m0 > + add lenq, mmsize > + jl .loop > + REP_RET Just use RET. > diff --git a/libavfilter/x86/af_afir_init.c b/libavfilter/x86/af_afir_init.c > new file mode 100644 > index 0000000..1cd5290 > --- /dev/null > +++ b/libavfilter/x86/af_afir_init.c > @@ -0,0 +1,35 @@ > +/* > + * This file is part of FFmpeg. > + * > + * FFmpeg is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * FFmpeg is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with FFmpeg; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 > USA > + */ > + > +#include "config.h" > +#include "libavutil/attributes.h" > +#include "libavutil/cpu.h" > +#include "libavutil/x86/cpu.h" > +#include "libavfilter/af_afir.h" > + > +void ff_fcmul_add_sse3(float *sum, const float *t, const float *c, > + int len); > + > +av_cold void ff_afir_init_x86(AudioFIRContext *s) > +{ > + int cpu_flags = av_get_cpu_flags(); > + > + if (EXTERNAL_SSE3(cpu_flags)) { > + s->fcmul_add = ff_fcmul_add_sse3; > + } > +} > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel