Go to the documentation of this file.
122 #define IIR_CH(name, type, min, max, need_clipping) \
123 static int iir_ch_## name(AVFilterContext *ctx, void *arg, int ch, int nb_jobs) \
125 AudioIIRContext *s = ctx->priv; \
126 const double ig = s->dry_gain; \
127 const double og = s->wet_gain; \
128 const double mix = s->mix; \
129 ThreadData *td = arg; \
130 AVFrame *in = td->in, *out = td->out; \
131 const type *src = (const type *)in->extended_data[ch]; \
132 double *ic = (double *)s->iir[ch].cache[0]; \
133 double *oc = (double *)s->iir[ch].cache[1]; \
134 const int nb_a = s->iir[ch].nb_ab[0]; \
135 const int nb_b = s->iir[ch].nb_ab[1]; \
136 const double *a = s->iir[ch].ab[0]; \
137 const double *b = s->iir[ch].ab[1]; \
138 const double g = s->iir[ch].g; \
139 int *clippings = &s->iir[ch].clippings; \
140 type *dst = (type *)out->extended_data[ch]; \
143 for (n = 0; n < in->nb_samples; n++) { \
144 double sample = 0.; \
147 memmove(&ic[1], &ic[0], (nb_b - 1) * sizeof(*ic)); \
148 memmove(&oc[1], &oc[0], (nb_a - 1) * sizeof(*oc)); \
149 ic[0] = src[n] * ig; \
150 for (x = 0; x < nb_b; x++) \
151 sample += b[x] * ic[x]; \
153 for (x = 1; x < nb_a; x++) \
154 sample -= a[x] * oc[x]; \
158 sample = sample * mix + ic[0] * (1. - mix); \
159 if (need_clipping && sample < min) { \
162 } else if (need_clipping && sample > max) { \
173 IIR_CH(s16p, int16_t, INT16_MIN, INT16_MAX, 1)
175 IIR_CH(fltp,
float, -1., 1., 0)
176 IIR_CH(dblp,
double, -1., 1., 0)
178 #define SERIAL_IIR_CH(name, type, min, max, need_clipping) \
179 static int iir_ch_serial_## name(AVFilterContext *ctx, void *arg, int ch, int nb_jobs) \
181 AudioIIRContext *s = ctx->priv; \
182 const double ig = s->dry_gain; \
183 const double og = s->wet_gain; \
184 const double mix = s->mix; \
185 ThreadData *td = arg; \
186 AVFrame *in = td->in, *out = td->out; \
187 const type *src = (const type *)in->extended_data[ch]; \
188 type *dst = (type *)out->extended_data[ch]; \
189 IIRChannel *iir = &s->iir[ch]; \
190 const double g = iir->g; \
191 int *clippings = &iir->clippings; \
192 int nb_biquads = (FFMAX(iir->nb_ab[0], iir->nb_ab[1]) + 1) / 2; \
195 for (i = 0; i < nb_biquads; i++) { \
196 const double a1 = -iir->biquads[i].a1; \
197 const double a2 = -iir->biquads[i].a2; \
198 const double b0 = iir->biquads[i].b0; \
199 const double b1 = iir->biquads[i].b1; \
200 const double b2 = iir->biquads[i].b2; \
201 double i1 = iir->biquads[i].i1; \
202 double i2 = iir->biquads[i].i2; \
203 double o1 = iir->biquads[i].o1; \
204 double o2 = iir->biquads[i].o2; \
206 for (n = 0; n < in->nb_samples; n++) { \
207 double sample = ig * (i ? dst[n] : src[n]); \
208 double o0 = sample * b0 + i1 * b1 + i2 * b2 + o1 * a1 + o2 * a2; \
216 o0 = o0 * mix + (1. - mix) * sample; \
217 if (need_clipping && o0 < min) { \
220 } else if (need_clipping && o0 > max) { \
227 iir->biquads[i].i1 = i1; \
228 iir->biquads[i].i2 = i2; \
229 iir->biquads[i].o1 = o1; \
230 iir->biquads[i].o2 = o2; \
249 for (p = item_str; *p && *p !=
'|'; p++) {
258 char *p, *
arg, *old_str, *prev_arg =
NULL, *saveptr =
NULL;
264 for (
i = 0;
i < nb_items;
i++) {
274 if (sscanf(
arg,
"%lf", &
s->iir[
i].g) != 1) {
290 char *p, *
arg, *old_str, *saveptr =
NULL;
296 for (
i = 0;
i < nb_items;
i++) {
301 if (sscanf(
arg,
"%lf", &dst[
i]) != 1) {
315 char *p, *
arg, *old_str, *saveptr =
NULL;
321 for (
i = 0;
i < nb_items;
i++) {
326 if (sscanf(
arg,
format, &dst[
i*2], &dst[
i*2+1]) != 2) {
338 static const char *
format[] = {
"%lf",
"%lf %lfi",
"%lf %lfr",
"%lf %lfd" };
343 char *p, *
arg, *old_str, *prev_arg =
NULL, *saveptr =
NULL;
365 if (!iir->
ab[ab] || !iir->
cache[ab]) {
387 static void multiply(
double wre,
double wim,
int npz,
double *coeffs)
389 double nwre = -wre, nwim = -wim;
393 for (
i = npz;
i >= 1;
i--) {
394 cre = coeffs[2 *
i + 0];
395 cim = coeffs[2 *
i + 1];
397 coeffs[2 *
i + 0] = (nwre * cre - nwim * cim) + coeffs[2 * (
i - 1) + 0];
398 coeffs[2 *
i + 1] = (nwre * cim + nwim * cre) + coeffs[2 * (
i - 1) + 1];
403 coeffs[0] = nwre * cre - nwim * cim;
404 coeffs[1] = nwre * cim + nwim * cre;
414 for (
i = 0;
i < nb;
i++) {
415 coeffs[2 * (
i + 1) ] = 0.0;
416 coeffs[2 * (
i + 1) + 1] = 0.0;
419 for (
i = 0;
i < nb;
i++)
420 multiply(pz[2 *
i], pz[2 *
i + 1], nb, coeffs);
422 for (
i = 0;
i < nb + 1;
i++) {
423 if (fabs(coeffs[2 *
i + 1]) > FLT_EPSILON) {
424 av_log(
ctx,
AV_LOG_ERROR,
"coeff: %f of z^%d is not real; poles/zeros are not complex conjugates.\n",
425 coeffs[2 *
i + 1],
i);
444 if (!topc || !botc) {
459 for (j = 0,
i = iir->
nb_ab[1];
i >= 0; j++,
i--) {
460 iir->
ab[1][j] = topc[2 *
i];
464 for (j = 0,
i = iir->
nb_ab[0];
i >= 0; j++,
i--) {
465 iir->
ab[0][j] = botc[2 *
i];
487 int current_biquad = 0;
493 while (nb_biquads--) {
494 Pair outmost_pole = { -1, -1 };
495 Pair nearest_zero = { -1, -1 };
496 double zeros[4] = { 0 };
497 double poles[4] = { 0 };
500 double min_distance = DBL_MAX;
504 for (
i = 0;
i < iir->
nb_ab[0];
i++) {
509 mag =
hypot(iir->
ab[0][2 *
i], iir->
ab[0][2 *
i + 1]);
517 for (
i = 0;
i < iir->
nb_ab[1];
i++) {
521 if (iir->
ab[0][2 *
i ] == iir->
ab[0][2 * outmost_pole.
a ] &&
522 iir->
ab[0][2 *
i + 1] == -iir->
ab[0][2 * outmost_pole.
a + 1]) {
530 if (outmost_pole.
a < 0 || outmost_pole.
b < 0)
533 for (
i = 0;
i < iir->
nb_ab[1];
i++) {
539 iir->
ab[0][2 * outmost_pole.
a + 1] - iir->
ab[1][2 *
i + 1]);
547 for (
i = 0;
i < iir->
nb_ab[1];
i++) {
551 if (iir->
ab[1][2 *
i ] == iir->
ab[1][2 * nearest_zero.
a ] &&
552 iir->
ab[1][2 *
i + 1] == -iir->
ab[1][2 * nearest_zero.
a + 1]) {
560 if (nearest_zero.
a < 0 || nearest_zero.
b < 0)
563 poles[0] = iir->
ab[0][2 * outmost_pole.
a ];
564 poles[1] = iir->
ab[0][2 * outmost_pole.
a + 1];
566 zeros[0] = iir->
ab[1][2 * nearest_zero.
a ];
567 zeros[1] = iir->
ab[1][2 * nearest_zero.
a + 1];
569 if (nearest_zero.
a == nearest_zero.
b && outmost_pole.
a == outmost_pole.
b) {
576 poles[2] = iir->
ab[0][2 * outmost_pole.
b ];
577 poles[3] = iir->
ab[0][2 * outmost_pole.
b + 1];
579 zeros[2] = iir->
ab[1][2 * nearest_zero.
b ];
580 zeros[3] = iir->
ab[1][2 * nearest_zero.
b + 1];
591 iir->
ab[0][2 * outmost_pole.
a] = iir->
ab[0][2 * outmost_pole.
a + 1] =
NAN;
592 iir->
ab[0][2 * outmost_pole.
b] = iir->
ab[0][2 * outmost_pole.
b + 1] =
NAN;
593 iir->
ab[1][2 * nearest_zero.
a] = iir->
ab[1][2 * nearest_zero.
a + 1] =
NAN;
594 iir->
ab[1][2 * nearest_zero.
b] = iir->
ab[1][2 * nearest_zero.
b + 1] =
NAN;
599 iir->
biquads[current_biquad].
b0 =
b[4] /
a[4] * (current_biquad ? 1.0 : iir->
g);
600 iir->
biquads[current_biquad].
b1 =
b[2] /
a[4] * (current_biquad ? 1.0 : iir->
g);
601 iir->
biquads[current_biquad].
b2 =
b[0] /
a[4] * (current_biquad ? 1.0 : iir->
g);
627 for (
n = 0;
n < iir->
nb_ab[0];
n++) {
628 double r = iir->
ab[0][2*
n];
629 double angle = iir->
ab[0][2*
n+1];
631 iir->
ab[0][2*
n] =
r * cos(angle);
632 iir->
ab[0][2*
n+1] =
r * sin(angle);
635 for (
n = 0;
n < iir->
nb_ab[1];
n++) {
636 double r = iir->
ab[1][2*
n];
637 double angle = iir->
ab[1][2*
n+1];
639 iir->
ab[1][2*
n] =
r * cos(angle);
640 iir->
ab[1][2*
n+1] =
r * sin(angle);
654 for (
n = 0;
n < iir->
nb_ab[0];
n++) {
655 double r = iir->
ab[0][2*
n];
656 double angle =
M_PI*iir->
ab[0][2*
n+1]/180.;
658 iir->
ab[0][2*
n] =
r * cos(angle);
659 iir->
ab[0][2*
n+1] =
r * sin(angle);
662 for (
n = 0;
n < iir->
nb_ab[1];
n++) {
663 double r = iir->
ab[1][2*
n];
664 double angle =
M_PI*iir->
ab[1][2*
n+1]/180.;
666 iir->
ab[1][2*
n] =
r * cos(angle);
667 iir->
ab[1][2*
n+1] =
r * sin(angle);
680 for (
i = 0; txt[
i];
i++) {
684 for (char_y = 0; char_y < font_height; char_y++) {
686 if (font[txt[
i] * font_height + char_y] &
mask)
697 int dx =
FFABS(x1-x0);
698 int dy =
FFABS(y1-y0), sy = y0 < y1 ? 1 : -1;
699 int err = (dx>dy ? dx : -dy) / 2, e2;
704 if (x0 == x1 && y0 == y1)
724 float *mag, *phase, *delay,
min = FLT_MAX,
max = FLT_MIN;
725 float min_delay = FLT_MAX, max_delay = FLT_MIN;
726 int prev_ymag = -1, prev_yphase = -1, prev_ydelay = -1;
730 memset(
out->data[0], 0,
s->h *
out->linesize[0]);
735 if (!mag || !phase || !delay)
738 ch = av_clip(
s->ir_channel, 0,
s->channels - 1);
739 for (
i = 0;
i <
s->w;
i++) {
740 const double *
b =
s->iir[
ch].ab[0];
741 const double *
a =
s->iir[
ch].ab[1];
742 double w =
i *
M_PI / (
s->w - 1);
745 double real, imag, div;
747 if (
s->format == 0) {
748 realz = 0., realp = 0.;
749 imagz = 0., imagp = 0.;
750 for (x = 0; x <
s->iir[
ch].nb_ab[1]; x++) {
751 realz += cos(-x *
w) *
a[x];
752 imagz += sin(-x *
w) *
a[x];
755 for (x = 0; x <
s->iir[
ch].nb_ab[0]; x++) {
756 realp += cos(-x *
w) *
b[x];
757 imagp += sin(-x *
w) *
b[x];
760 div = realp * realp + imagp * imagp;
761 real = (realz * realp + imagz * imagp) / div;
762 imag = (imagz * realp - imagp * realz) / div;
766 for (x = 0; x <
s->iir[
ch].nb_ab[1]; x++) {
767 double ore, oim,
re,
im;
769 re = cos(
w) -
a[2 * x];
770 im = sin(
w) -
a[2 * x + 1];
775 real = ore *
re - oim *
im;
776 imag = ore *
im + oim *
re;
779 for (x = 0; x <
s->iir[
ch].nb_ab[0]; x++) {
780 double ore, oim,
re,
im;
782 re = cos(
w) -
b[2 * x];
783 im = sin(
w) -
b[2 * x + 1];
789 real = (ore *
re + oim *
im) / div;
790 imag = (oim *
re - ore *
im) / div;
794 mag[
i] =
s->iir[
ch].g *
hypot(real, imag);
795 phase[
i] = atan2(imag, real);
800 for (
i = 0;
i <
s->w - 1;
i++) {
801 float dw =
M_PI / (
s->w - 1);
803 delay[
i] = -(phase[
i + 1] - phase[
i]) / dw;
804 min_delay =
fminf(min_delay, delay[
i]);
805 max_delay =
fmaxf(max_delay, delay[
i]);
808 delay[
i] = delay[
i - 1];
810 for (
i = 0;
i <
s->w;
i++) {
811 int ymag = mag[
i] /
max * (
s->h - 1);
812 int ydelay = (delay[
i] - min_delay) / (max_delay - min_delay) * (
s->h - 1);
813 int yphase = (0.5 * (1. + phase[
i] /
M_PI)) * (
s->h - 1);
815 ymag =
s->h - 1 - av_clip(ymag, 0,
s->h - 1);
816 yphase =
s->h - 1 - av_clip(yphase, 0,
s->h - 1);
817 ydelay =
s->h - 1 - av_clip(ydelay, 0,
s->h - 1);
822 prev_yphase = yphase;
824 prev_ydelay = ydelay;
831 prev_yphase = yphase;
832 prev_ydelay = ydelay;
835 if (
s->w > 400 &&
s->h > 100) {
840 drawtext(
out, 2, 12,
"Min Magnitude:", 0xDDDDDDDD);
845 snprintf(text,
sizeof(text),
"%.2f", max_delay);
849 snprintf(text,
sizeof(text),
"%.2f", min_delay);
866 s->channels =
inlink->channels;
883 if (
s->format == 2) {
885 }
else if (
s->format == 3) {
899 av_log(
ctx,
AV_LOG_WARNING,
"tf coefficients format is not recommended for too high number of zeros/poles.\n");
901 if (
s->format > 0 &&
s->process == 0) {
907 }
else if (
s->format == 0 &&
s->process == 1) {
910 }
else if (
s->format > 0 &&
s->process == 1) {
919 for (
ch = 0;
s->format == 0 &&
ch <
inlink->channels;
ch++) {
922 for (
i = 1;
i < iir->
nb_ab[0];
i++) {
923 iir->
ab[0][
i] /= iir->
ab[0][0];
926 for (
i = 0;
i < iir->
nb_ab[1];
i++) {
927 iir->
ab[1][
i] *= iir->
g / iir->
ab[0][0];
932 case AV_SAMPLE_FMT_DBLP:
s->iir_channel =
s->process == 1 ? iir_ch_serial_dblp : iir_ch_dblp;
break;
933 case AV_SAMPLE_FMT_FLTP:
s->iir_channel =
s->process == 1 ? iir_ch_serial_fltp : iir_ch_fltp;
break;
934 case AV_SAMPLE_FMT_S32P:
s->iir_channel =
s->process == 1 ? iir_ch_serial_s32p : iir_ch_s32p;
break;
935 case AV_SAMPLE_FMT_S16P:
s->iir_channel =
s->process == 1 ? iir_ch_serial_s16p : iir_ch_s16p;
break;
966 if (
s->iir[
ch].clippings > 0)
968 ch,
s->iir[
ch].clippings);
969 s->iir[
ch].clippings = 0;
977 int64_t old_pts =
s->video->pts;
980 if (new_pts > old_pts) {
981 s->video->pts = new_pts;
1011 if (!
s->a_str || !
s->b_str || !
s->g_str) {
1016 switch (
s->precision) {
1062 for (
ch = 0;
ch <
s->channels;
ch++) {
1088 #define OFFSET(x) offsetof(AudioIIRContext, x)
1089 #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1090 #define VF AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1101 {
"pr",
"Z-plane zeros/poles (polar radians)", 0,
AV_OPT_TYPE_CONST, {.i64=2}, 0, 0,
AF,
"format" },
1102 {
"pd",
"Z-plane zeros/poles (polar degrees)", 0,
AV_OPT_TYPE_CONST, {.i64=3}, 0, 0,
AF,
"format" },
1107 {
"dbl",
"double-precision floating-point", 0,
AV_OPT_TYPE_CONST, {.i64=0}, 0, 0,
AF,
"precision" },
1108 {
"flt",
"single-precision floating-point", 0,
AV_OPT_TYPE_CONST, {.i64=1}, 0, 0,
AF,
"precision" },
1113 {
"channel",
"set IR channel to display frequency response",
OFFSET(ir_channel),
AV_OPT_TYPE_INT, {.i64=0}, 0, 1024,
VF },
1123 .description =
NULL_IF_CONFIG_SMALL(
"Apply Infinite Impulse Response filter with supplied coefficients."),
1125 .priv_class = &aiir_class,
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
@ AV_SAMPLE_FMT_FLTP
float, planar
A list of supported channel layouts.
#define AV_LOG_WARNING
Something somehow does not look correct.
AVPixelFormat
Pixel format.
static void draw_response(AVFilterContext *ctx, AVFrame *out)
static int mix(int c0, int c1)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
AVFILTER_DEFINE_CLASS(aiir)
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
static enum AVSampleFormat sample_fmts[]
enum MovChannelLayoutTag * layouts
@ AV_OPT_TYPE_VIDEO_RATE
offset must point to AVRational
static const AVFilterPad inputs[]
AVFilterFormats * in_formats
Lists of formats and channel layouts supported by the input and output filters respectively.
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(const uint8_t *) pi - 0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(const int16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(const int16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(const int32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(const int32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(const int64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0f/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(const float *) pi *(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(const double *) pi *(INT64_C(1)<< 63))) #define FMT_PAIR_FUNC(out, in) static conv_func_type *const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={ FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64), };static void cpy1(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, len);} static void cpy2(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 2 *len);} static void cpy4(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 4 *len);} static void cpy8(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 8 *len);} AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, const int *ch_map, int flags) { AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) return NULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) return NULL;if(channels==1){ in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);} ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map) { switch(av_get_bytes_per_sample(in_fmt)){ case 1:ctx->simd_f=cpy1;break;case 2:ctx->simd_f=cpy2;break;case 4:ctx->simd_f=cpy4;break;case 8:ctx->simd_f=cpy8;break;} } if(HAVE_X86ASM &&1) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);return ctx;} void swri_audio_convert_free(AudioConvert **ctx) { av_freep(ctx);} int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len) { int ch;int off=0;const int os=(out->planar ? 1 :out->ch_count) *out->bps;unsigned misaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask) { int planes=in->planar ? in->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;} if(ctx->out_simd_align_mask) { int planes=out->planar ? out->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;} if(ctx->simd_f &&!ctx->ch_map &&!misaligned){ off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){ if(out->planar==in->planar){ int planes=out->planar ? out->ch_count :1;for(ch=0;ch< planes;ch++){ ctx->simd_f(out-> ch ch
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
static const AVOption aiir_options[]
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
static av_cold int end(AVCodecContext *avctx)
static int read_channels(AVFilterContext *ctx, int channels, uint8_t *item_str, int ab)
This structure describes decoded (raw) audio or video data.
#define IIR_CH(name, type, min, max, need_clipping)
@ AV_SAMPLE_FMT_S32P
signed 32 bits, planar
static int read_tf_coefficients(AVFilterContext *ctx, char *item_str, int nb_items, double *dst)
int(* iir_channel)(AVFilterContext *ctx, void *arg, int ch, int nb_jobs)
#define AV_LOG_VERBOSE
Detailed information.
static int config_output(AVFilterLink *outlink)
const char * name
Filter name.
static int config_video(AVFilterLink *outlink)
AVFormatInternal * internal
An opaque field for libavformat internal usage.
A link between two filters.
int channels
Number of channels.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
static int query_formats(AVFilterContext *ctx)
A filter pad used for either input or output.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
static int convert_zp2tf(AVFilterContext *ctx, int channels)
static const uint16_t mask[17]
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok().
AVRational sample_aspect_ratio
agreed upon sample aspect ratio
float fminf(float, float)
AVRational frame_rate
Frame rate of the stream on the link, or 1/0 if unknown or variable; if left to 0/0,...
static enum AVPixelFormat pix_fmts[]
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
#define SERIAL_IIR_CH(name, type, min, max, need_clipping)
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Describe the class of an AVClass context structure.
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
static const char * format[]
Rational number (pair of numerator and denominator).
@ AV_OPT_TYPE_IMAGE_SIZE
offset must point to two consecutive integers
static av_cold int init(AVFilterContext *ctx)
static int process(struct ResampleContext *c, AudioData *dst, int dst_size, AudioData *src, int src_size, int *consumed)
#define AVFILTER_FLAG_DYNAMIC_OUTPUTS
The number of the filter outputs is not determined just by AVFilter.outputs.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static void draw_line(AVFrame *out, int x0, int y0, int x1, int y1, uint32_t color)
float fmaxf(float, float)
static av_const double hypot(double x, double y)
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
static int read_zp_coefficients(AVFilterContext *ctx, char *item_str, int nb_items, double *dst, const char *format)
AVFilterContext * src
source filter
static void multiply(double wre, double wim, int npz, double *coeffs)
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
@ AV_SAMPLE_FMT_S16P
signed 16 bits, planar
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
enum AVSampleFormat sample_format
#define i(width, name, range_min, range_max)
int w
agreed upon image width
#define av_malloc_array(a, b)
AVSampleFormat
Audio sample formats.
Used for passing data between threads.
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
const char * name
Pad name.
static int expand(AVFilterContext *ctx, double *pz, int nb, double *coeffs)
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
static void convert_pr2zp(AVFilterContext *ctx, int channels)
int h
agreed upon image height
static int ff_insert_outpad(AVFilterContext *f, unsigned index, AVFilterPad *p)
Insert a new output pad for the filter.
@ AV_SAMPLE_FMT_DBLP
double, planar
AVRational time_base
Define the time base used by the PTS of the frames/samples which will pass through this link.
static int decompose_zp2biquads(AVFilterContext *ctx, int channels)
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
char * av_strdup(const char *s)
Duplicate a string.
static void count_coefficients(char *item_str, int *nb_items)
const uint8_t avpriv_cga_font[2048]
static float distance(float x, float y, int band)
#define flags(name, subs,...)
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
static av_cold void uninit(AVFilterContext *ctx)
static int read_gains(AVFilterContext *ctx, char *item_str, int nb_items)
static void convert_pd2zp(AVFilterContext *ctx, int channels)
static void drawtext(AVFrame *pic, int x, int y, const char *txt, uint32_t color)