46#define MAX_IR_STREAMS 32
135 const int min_part_size =
s->min_part_size;
136 const int prev_selir =
s->prev_selir;
137 const int selir =
s->selir;
142 fir_quantums_float(
ctx,
s,
out, min_part_size, ch,
offset, prev_selir, selir);
145 fir_quantums_double(
ctx,
s,
out, min_part_size, ch,
offset, prev_selir, selir);
149 if (selir != prev_selir &&
s->loading[ch] != 0)
150 s->loading[ch] += min_part_size;
159 const int start =
ff_slice_pos(
out->ch_layout.nb_channels, jobnr, nb_jobs);
160 const int end =
ff_slice_pos(
out->ch_layout.nb_channels, jobnr + 1, nb_jobs);
162 for (
int ch = start; ch < end; ch++)
184 s->prev_is_disabled =
ctx->is_disabled;
193 int offset,
int nb_partitions,
int part_size,
int index)
197 union {
double d;
float f; } cscale,
scale, iscale;
201 seg->
tx =
av_calloc(
ctx->inputs[0]->ch_layout.nb_channels,
sizeof(*seg->
tx));
204 if (!seg->
tx || !seg->
ctx || !seg->
itx)
224 iscale.f = 1.f /
sqrtf(2.f * part_size);
229 scale.d = 1.0 / sqrt(2.0 * part_size);
230 iscale.d = 1.0 / sqrt(2.0 * part_size);
237 for (
int ch = 0; ch <
ctx->inputs[0]->ch_layout.nb_channels && part_size >= 1; ch++) {
239 0, 2 * part_size, &cscale, 0);
244 0, 2 * part_size, &
scale, 0);
248 1, 2 * part_size, &iscale, 0);
273 for (
int ch = 0; ch <
s->nb_channels; ch++)
279 for (
int ch = 0; ch <
s->nb_channels; ch++)
285 for (
int ch = 0; ch <
s->nb_channels; ch++)
310 int ret, nb_taps, cur_nb_taps;
312 if (!
s->nb_taps[selir]) {
313 int part_size, max_part_size;
317 if (
s->nb_taps[selir] <= 0)
320 if (
s->minp >
s->maxp)
323 if (
s->nb_segments[selir])
326 left =
s->nb_taps[selir];
328 max_part_size = 1 <<
av_log2(
s->maxp);
330 for (
int i = 0;
left > 0;
i++) {
331 int step = (part_size == max_part_size) ? INT_MAX : 1 + (
i == 0);
332 int nb_partitions =
FFMIN(step, (
left + part_size - 1) / part_size);
334 s->nb_segments[selir] =
i + 1;
338 offset += nb_partitions * part_size;
340 left -= nb_partitions * part_size;
342 part_size =
FFMIN(part_size, max_part_size);
355 cur_nb_taps =
s->ir[selir]->nb_samples;
356 nb_taps = cur_nb_taps;
358 if (!
s->norm_ir[selir] ||
s->norm_ir[selir]->nb_samples < nb_taps) {
361 if (!
s->norm_ir[selir])
370 for (
int ch = 0; ch <
s->nb_channels; ch++) {
371 const float *tsrc = (
const float *)
s->ir[selir]->extended_data[!
s->one2many * ch];
373 s->ch_gain[ch] = ir_gain_float(
ctx,
s, nb_taps, tsrc);
379 for (
int ch = 0; ch <
s->nb_channels; ch++)
380 gain =
fminf(gain,
s->ch_gain[ch]);
382 for (
int ch = 0; ch <
s->nb_channels; ch++)
383 s->ch_gain[ch] = gain;
386 for (
int ch = 0; ch <
s->nb_channels; ch++) {
387 const float *tsrc = (
const float *)
s->ir[selir]->extended_data[!
s->one2many * ch];
388 float *time = (
float *)
s->norm_ir[selir]->extended_data[ch];
390 memcpy(time, tsrc,
sizeof(*time) * nb_taps);
391 for (
int i =
FFMAX(1,
s->length * nb_taps);
i < nb_taps;
i++)
394 ir_scale_float(
ctx,
s, nb_taps, ch, time,
s->ch_gain[ch]);
396 for (
int n = 0; n <
s->nb_segments[selir]; n++) {
405 convert_channel_float(
ctx,
s, ch, seg,
i, selir);
410 for (
int ch = 0; ch <
s->nb_channels; ch++) {
411 const double *tsrc = (
const double *)
s->ir[selir]->extended_data[!
s->one2many * ch];
413 s->ch_gain[ch] = ir_gain_double(
ctx,
s, nb_taps, tsrc);
419 for (
int ch = 0; ch <
s->nb_channels; ch++)
420 gain =
fmin(gain,
s->ch_gain[ch]);
422 for (
int ch = 0; ch <
s->nb_channels; ch++)
423 s->ch_gain[ch] = gain;
426 for (
int ch = 0; ch <
s->nb_channels; ch++) {
427 const double *tsrc = (
const double *)
s->ir[selir]->extended_data[!
s->one2many * ch];
428 double *time = (
double *)
s->norm_ir[selir]->extended_data[ch];
430 memcpy(time, tsrc,
sizeof(*time) * nb_taps);
431 for (
int i =
FFMAX(1,
s->length * nb_taps);
i < nb_taps;
i++)
434 ir_scale_double(
ctx,
s, nb_taps, ch, time,
s->ch_gain[ch]);
436 for (
int n = 0; n <
s->nb_segments[selir]; n++) {
445 convert_channel_double(
ctx,
s, ch, seg,
i, selir);
451 s->have_coeffs[selir] = 1;
460 int nb_taps, max_nb_taps;
463 max_nb_taps =
s->max_ir_len *
ctx->outputs[0]->sample_rate;
464 if (nb_taps > max_nb_taps) {
470 s->eof_coeffs[selir] = 1;
479 int ret, status, available, wanted;
485 for (
int i = 0;
i <
s->nb_irs;
i++) {
488 if (
s->ir_load && selir !=
s->selir)
491 if (!
s->eof_coeffs[selir]) {
496 if (!
s->eof_coeffs[selir]) {
503 if (!
s->have_coeffs[selir] &&
s->eof_coeffs[selir]) {
511 wanted =
FFMAX(
s->min_part_size, (available /
s->min_part_size) *
s->min_part_size);
516 if (
s->selir !=
s->prev_selir &&
s->loading[0] == 0)
517 s->prev_selir =
s->selir;
566 for (
int i = 1;
i <
ctx->nb_inputs;
i++) {
585 s->one2many =
ctx->inputs[1 +
s->selir]->ch_layout.nb_channels == 1;
594 s->ch_gain =
av_calloc(
ctx->inputs[0]->ch_layout.nb_channels,
sizeof(*
s->ch_gain));
595 s->loading =
av_calloc(
ctx->inputs[0]->ch_layout.nb_channels,
sizeof(*
s->loading));
596 if (!
s->loading || !
s->ch_gain)
601 if (!
s->fadein[0] || !
s->fadein[1])
606 if (!
s->xfade[0] || !
s->xfade[1])
611 for (
int ch = 0; ch <
s->nb_channels; ch++) {
612 float *dst0 = (
float *)
s->xfade[0]->extended_data[ch];
613 float *dst1 = (
float *)
s->xfade[1]->extended_data[ch];
615 for (
int n = 0; n <
s->min_part_size; n++) {
616 dst0[n] = (n + 1.f) /
s->min_part_size;
617 dst1[n] = 1.f - dst0[n];
622 for (
int ch = 0; ch <
s->nb_channels; ch++) {
623 double *dst0 = (
double *)
s->xfade[0]->extended_data[ch];
624 double *dst1 = (
double *)
s->xfade[1]->extended_data[ch];
626 for (
int n = 0; n <
s->min_part_size; n++) {
627 dst0[n] = (n + 1.0) /
s->min_part_size;
628 dst1[n] = 1.0 - dst0[n];
645 for (
int i = 0;
i <
s->nb_irs;
i++) {
646 for (
int j = 0; j <
s->nb_segments[
i]; j++)
666 s->prev_selir =
FFMIN(
s->nb_irs - 1,
s->selir);
677 for (
int n = 0; n <
s->nb_irs; n++) {
697 s->min_part_size = 1 <<
av_log2(
s->minp);
698 s->max_part_size = 1 <<
av_log2(
s->maxp);
713 prev_selir =
s->selir;
718 s->selir =
FFMIN(
s->nb_irs - 1,
s->selir);
719 if (
s->selir != prev_selir) {
720 s->prev_selir = prev_selir;
722 for (
int ch = 0; ch <
s->nb_channels; ch++)
729#define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
730#define AFR AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
731#define VF AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
732#define OFFSET(x) offsetof(AudioFIRContext, x)
760 {
"precision",
"set processing precision",
OFFSET(precision),
AV_OPT_TYPE_INT, {.i64=0}, 0, 2,
AF, .unit =
"precision" },
761 {
"auto",
"set auto processing precision", 0,
AV_OPT_TYPE_CONST, {.i64=0}, 0, 0,
AF, .unit =
"precision" },
762 {
"float",
"set single-floating point processing precision", 0,
AV_OPT_TYPE_CONST, {.i64=1}, 0, 0,
AF, .unit =
"precision" },
763 {
"double",
"set double-floating point processing precision", 0,
AV_OPT_TYPE_CONST, {.i64=2}, 0, 0,
AF, .unit =
"precision" },
765 {
"init",
"load all IRs on init", 0,
AV_OPT_TYPE_CONST, {.i64=0}, 0, 0,
AF, .unit =
"irload" },
766 {
"access",
"load IR on access", 0,
AV_OPT_TYPE_CONST, {.i64=1}, 0, 0,
AF, .unit =
"irload" },
782 .p.description =
NULL_IF_CONFIG_SMALL(
"Apply Finite Impulse Response filter with supplied coefficients in additional stream(s)."),
783 .p.priv_class = &afir_class,
static enum AVSampleFormat sample_fmts[]
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
static const AVFilterPad outputs[]
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
static av_unused void ff_afir_init(AudioFIRDSPContext *dsp)
static ftype fn ir_gain(AVFilterContext *ctx, AudioFIRContext *s, int cur_nb_taps, const ftype *time)
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
int ff_append_inpad_free_name(AVFilterContext *f, AVFilterPad *p)
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
int ff_inlink_check_available_samples(AVFilterLink *link, unsigned min)
Test if enough samples are available on the link.
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
int ff_append_inpad(AVFilterContext *f, AVFilterPad *p)
Append a new input/output pad to the filter's list of such pads.
int ff_outlink_frame_wanted(AVFilterLink *link)
Test if a frame is wanted on an output link.
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max, AVFrame **rframe)
Take samples from the link's FIFO and update the link's stats.
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
Mark a filter ready and schedule it for activation.
int ff_inlink_queued_samples(AVFilterLink *link)
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
Main libavfilter public API header.
char * av_asprintf(const char *fmt,...)
static void BS_FUNC skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
static int BS_FUNC left(const BSCTX *bc)
Return the number of the bits left in a buffer.
#define flags(name, subs,...)
#define i(width, name, range_min, range_max)
Public libavutil channel layout APIs header.
static __device__ float sqrtf(float a)
static const uint16_t channel_layouts[7]
double fmin(double, double)
float fminf(float, float)
int(* init)(AVBSFContext *ctx)
reference-counted frame API
#define AV_OPT_FLAG_DEPRECATED
Set if option is deprecated, users should refer to AVOption.help text for more information.
@ AV_OPT_TYPE_IMAGE_SIZE
Underlying C type is two consecutive integers.
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
@ AV_OPT_TYPE_VIDEO_RATE
Underlying C type is AVRational.
@ AV_OPT_TYPE_INT
Underlying C type is int.
@ AV_OPT_TYPE_FLOAT
Underlying C type is float.
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
#define AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
Same as AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, except that the filter will have its filter_frame() c...
#define AVFILTER_FLAG_DYNAMIC_INPUTS
The number of the filter inputs is not determined just by AVFilter.inputs.
#define AV_CHANNEL_LAYOUT_MONO
int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src)
Make a copy of a channel layout.
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
#define AVERROR_EOF
End of file.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
AVSampleFormat
Audio sample formats.
@ AV_SAMPLE_FMT_FLTP
float, planar
@ AV_SAMPLE_FMT_DBLP
double, planar
static void scale(int *out, const int *in, const int w, const int h, const int shift)
static av_cold void uninit(AVBitStreamFilterContext *ctx)
static int activate(AVBitStreamFilterContext *ctx)
static int config_output(AVBitStreamFilterLink *outlink)
static int process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
static int fir_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int init_segment(AVFilterContext *ctx, AudioFIRSegment *seg, int selir, int offset, int nb_partitions, int part_size, int index)
static int fir_frame(AudioFIRContext *s, AVFrame *in, AVFilterLink *outlink)
static int fir_channel(AVFilterContext *ctx, AVFrame *out, int ch)
static int convert_coeffs(AVFilterContext *ctx, int selir)
static void uninit_segment(AVFilterContext *ctx, AudioFIRSegment *seg)
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
static int activate(AVFilterContext *ctx)
static av_cold void uninit(AVFilterContext *ctx)
static int check_ir(AVFilterLink *link, int selir)
static int config_output(AVFilterLink *outlink)
static const AVOption afir_options[]
const FFFilter ff_af_afir
#define FILTER_OUTPUTS(array)
static int ff_slice_pos(int total, int jobnr, int nb_jobs)
Compute the boundary index for a slice when work of size total is split into nb_jobs slices.
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
#define FFERROR_NOT_READY
Filters implementation helper functions and internal structures.
#define FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, filter)
Forward the status on an output link to all input links.
#define AVFILTER_DEFINE_CLASS(fname)
#define FILTER_QUERY_FUNC2(func)
size_t av_cpu_max_align(void)
Get the maximum data alignment that may be required by FFmpeg.
av_cold AVFloatDSPContext * avpriv_float_dsp_alloc(int bit_exact)
Allocate a float DSP context.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
void * av_calloc(size_t nmemb, size_t size)
Memory handling functions.
enum MovChannelLayoutTag * layouts
Utilities for rational number calculation.
An AVChannelLayout holds information about the channel layout of audio data.
int nb_channels
Number of channels in this layout.
Describe the class of an AVClass context structure.
A list of supported channel layouts.
A link between two filters.
AVFilterContext * src
source filter
AVRational time_base
Define the time base used by the PTS of the frames/samples which will pass through this link.
int sample_rate
samples per second
AVChannelLayout ch_layout
channel layout of current buffer (see libavutil/channel_layout.h)
AVFilterContext * dst
dest filter
int format
agreed upon media format
A filter pad used for either input or output.
const char * name
Pad name.
This structure describes decoded (raw) audio or video data.
int nb_samples
number of audio samples (per channel) described by this frame
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Rational number (pair of numerator and denominator).
int nb_taps[MAX_IR_STREAMS]
int max_offset[MAX_IR_STREAMS]
AVFrame * ir[MAX_IR_STREAMS]
int eof_coeffs[MAX_IR_STREAMS]
int have_coeffs[MAX_IR_STREAMS]
AudioFIRDSPContext afirdsp
int nb_segments[MAX_IR_STREAMS]
AVFrame * norm_ir[MAX_IR_STREAMS]
AudioFIRSegment seg[MAX_IR_STREAMS][1024]
static AVFormatContext * ctx
av_cold void av_tx_uninit(AVTXContext **ctx)
Frees a context and sets *ctx to NULL, does nothing when *ctx == NULL.
av_cold int av_tx_init(AVTXContext **ctx, av_tx_fn *tx, enum AVTXType type, int inv, int len, const void *scale, uint64_t flags)
Initialize a transform context with the given configuration (i)MDCTs with an odd length are currently...
@ AV_TX_FLOAT_RDFT
Real to complex and complex to real DFTs.
void(* av_tx_fn)(AVTXContext *s, void *out, void *in, ptrdiff_t stride)
Function pointer to a function to perform the transform.