avfilter/af_adynamicequalizer: do gain calculations in log domain
This commit is contained in:
		
							parent
							
								
									afb967b81e
								
							
						
					
					
						commit
						82be1e5c0d
					
				@ -26,8 +26,10 @@
 | 
			
		||||
#undef FMIN
 | 
			
		||||
#undef CLIP
 | 
			
		||||
#undef SAMPLE_FORMAT
 | 
			
		||||
#undef EPSILON
 | 
			
		||||
#undef FABS
 | 
			
		||||
#undef FLOG10
 | 
			
		||||
#undef FEXP10
 | 
			
		||||
#undef EPSILON
 | 
			
		||||
#if DEPTH == 32
 | 
			
		||||
#define SAMPLE_FORMAT float
 | 
			
		||||
#define SQRT sqrtf
 | 
			
		||||
@ -39,8 +41,10 @@
 | 
			
		||||
#define FMAX fmaxf
 | 
			
		||||
#define CLIP av_clipf
 | 
			
		||||
#define FABS fabsf
 | 
			
		||||
#define FLOG10 log10f
 | 
			
		||||
#define FEXP10 ff_exp10f
 | 
			
		||||
#define EPSILON (1.f / (1 << 23))
 | 
			
		||||
#define ftype float
 | 
			
		||||
#define EPSILON (1.f / (1 << 22))
 | 
			
		||||
#else
 | 
			
		||||
#define SAMPLE_FORMAT double
 | 
			
		||||
#define SQRT sqrt
 | 
			
		||||
@ -52,10 +56,15 @@
 | 
			
		||||
#define FMAX fmax
 | 
			
		||||
#define CLIP av_clipd
 | 
			
		||||
#define FABS fabs
 | 
			
		||||
#define FLOG10 log10
 | 
			
		||||
#define FEXP10 ff_exp10
 | 
			
		||||
#define EPSILON (1.0 / (1LL << 53))
 | 
			
		||||
#define ftype double
 | 
			
		||||
#define EPSILON (1.0 / (1LL << 51))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define LIN2LOG(x) (20.0 * FLOG10(x))
 | 
			
		||||
#define LOG2LIN(x) (FEXP10(x / 20.0))
 | 
			
		||||
 | 
			
		||||
#define fn3(a,b)   a##_##b
 | 
			
		||||
#define fn2(a,b)   fn3(a,b)
 | 
			
		||||
#define fn(a)      fn2(a, SAMPLE_FORMAT)
 | 
			
		||||
@ -85,8 +94,11 @@ static int fn(filter_prepare)(AVFilterContext *ctx)
 | 
			
		||||
    ftype *dm = fn(s->dm);
 | 
			
		||||
    ftype k;
 | 
			
		||||
 | 
			
		||||
    s->attack_coef = get_coef(s->attack, sample_rate);
 | 
			
		||||
    s->release_coef = get_coef(s->release, sample_rate);
 | 
			
		||||
    s->threshold_log = LIN2LOG(s->threshold);
 | 
			
		||||
    s->dattack_coef = get_coef(s->dattack, sample_rate);
 | 
			
		||||
    s->drelease_coef = get_coef(s->drelease, sample_rate);
 | 
			
		||||
    s->gattack_coef = s->dattack_coef * 0.25;
 | 
			
		||||
    s->grelease_coef = s->drelease_coef * 0.25;
 | 
			
		||||
 | 
			
		||||
    switch (dftype) {
 | 
			
		||||
    case 0:
 | 
			
		||||
@ -150,9 +162,11 @@ static int fn(filter_channels)(AVFilterContext *ctx, void *arg, int jobnr, int n
 | 
			
		||||
    const ftype range = s->range;
 | 
			
		||||
    const ftype tfrequency = FMIN(s->tfrequency, sample_rate * 0.5);
 | 
			
		||||
    const int mode = s->mode;
 | 
			
		||||
    const int power = (mode == CUT_BELOW || mode == CUT_ABOVE) ? -1 : 1;
 | 
			
		||||
    const ftype release = s->release_coef;
 | 
			
		||||
    const ftype attack = s->attack_coef;
 | 
			
		||||
    const ftype power = (mode == CUT_BELOW || mode == CUT_ABOVE) ? -ONE : ONE;
 | 
			
		||||
    const ftype grelease = s->grelease_coef;
 | 
			
		||||
    const ftype gattack = s->gattack_coef;
 | 
			
		||||
    const ftype drelease = s->drelease_coef;
 | 
			
		||||
    const ftype dattack = s->dattack_coef;
 | 
			
		||||
    const ftype tqfactor = s->tqfactor;
 | 
			
		||||
    const ftype itqfactor = ONE / tqfactor;
 | 
			
		||||
    const ftype fg = TAN(M_PI * tfrequency / sample_rate);
 | 
			
		||||
@ -164,21 +178,39 @@ static int fn(filter_channels)(AVFilterContext *ctx, void *arg, int jobnr, int n
 | 
			
		||||
    const ftype *da = fn(s->da);
 | 
			
		||||
    const ftype *dm = fn(s->dm);
 | 
			
		||||
 | 
			
		||||
    if (detection > 0) {
 | 
			
		||||
    if (detection == DET_ON) {
 | 
			
		||||
        for (int ch = start; ch < end; ch++) {
 | 
			
		||||
            const ftype *src = (const ftype *)in->extended_data[ch];
 | 
			
		||||
            ChannelContext *cc = &s->cc[ch];
 | 
			
		||||
            ftype *tstate = fn(cc->tstate);
 | 
			
		||||
            ftype new_threshold = ZERO;
 | 
			
		||||
 | 
			
		||||
            if (cc->detection != detection) {
 | 
			
		||||
                cc->detection = detection;
 | 
			
		||||
                fn(cc->new_threshold_log) = LIN2LOG(EPSILON);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (int n = 0; n < in->nb_samples; n++) {
 | 
			
		||||
                ftype detect = fn(get_svf)(src[n], dm, da, tstate);
 | 
			
		||||
                fn(cc->threshold) = FMAX(fn(cc->threshold), detect);
 | 
			
		||||
                ftype detect = FABS(fn(get_svf)(src[n], dm, da, tstate));
 | 
			
		||||
                new_threshold = FMAX(new_threshold, detect);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            fn(cc->new_threshold_log) = FMAX(fn(cc->new_threshold_log), LIN2LOG(new_threshold));
 | 
			
		||||
        }
 | 
			
		||||
    } else if (detection < 0) {
 | 
			
		||||
    } else if (detection == DET_DISABLED) {
 | 
			
		||||
        for (int ch = start; ch < end; ch++) {
 | 
			
		||||
            ChannelContext *cc = &s->cc[ch];
 | 
			
		||||
            fn(cc->threshold) = s->threshold;
 | 
			
		||||
            fn(cc->threshold_log) = s->threshold_log;
 | 
			
		||||
            cc->detection = detection;
 | 
			
		||||
        }
 | 
			
		||||
    } else if (detection == DET_OFF) {
 | 
			
		||||
        for (int ch = start; ch < end; ch++) {
 | 
			
		||||
            ChannelContext *cc = &s->cc[ch];
 | 
			
		||||
            if (cc->detection == DET_ON)
 | 
			
		||||
                fn(cc->threshold_log) = fn(cc->new_threshold_log);
 | 
			
		||||
            else if (cc->detection == DET_UNSET)
 | 
			
		||||
                fn(cc->threshold_log) = s->threshold_log;
 | 
			
		||||
            cc->detection = detection;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -186,95 +218,99 @@ static int fn(filter_channels)(AVFilterContext *ctx, void *arg, int jobnr, int n
 | 
			
		||||
        const ftype *src = (const ftype *)in->extended_data[ch];
 | 
			
		||||
        ftype *dst = (ftype *)out->extended_data[ch];
 | 
			
		||||
        ChannelContext *cc = &s->cc[ch];
 | 
			
		||||
        const ftype threshold = fn(cc->threshold);
 | 
			
		||||
        const ftype threshold_log = fn(cc->threshold_log);
 | 
			
		||||
        ftype *fa = fn(cc->fa), *fm = fn(cc->fm);
 | 
			
		||||
        ftype *fstate = fn(cc->fstate);
 | 
			
		||||
        ftype *dstate = fn(cc->dstate);
 | 
			
		||||
        ftype gain = fn(cc->gain);
 | 
			
		||||
        const int init = cc->init;
 | 
			
		||||
        ftype detect = fn(cc->detect);
 | 
			
		||||
        ftype lin_gain = fn(cc->lin_gain);
 | 
			
		||||
        int init = cc->init;
 | 
			
		||||
 | 
			
		||||
        for (int n = 0; n < out->nb_samples; n++) {
 | 
			
		||||
            ftype detect, v, listen, new_gain = ONE;
 | 
			
		||||
            ftype k, g;
 | 
			
		||||
            ftype new_detect, new_lin_gain = ONE;
 | 
			
		||||
            ftype f, v, listen, k, g, ld;
 | 
			
		||||
 | 
			
		||||
            detect = listen = fn(get_svf)(src[n], dm, da, dstate);
 | 
			
		||||
            detect = FABS(detect);
 | 
			
		||||
            listen = fn(get_svf)(src[n], dm, da, dstate);
 | 
			
		||||
            if (mode > LISTEN) {
 | 
			
		||||
                new_detect = FABS(listen);
 | 
			
		||||
                f = (new_detect > detect) * dattack + (new_detect <= detect) * drelease;
 | 
			
		||||
                detect = f * new_detect + (ONE - f) * detect;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            switch (mode) {
 | 
			
		||||
            case LISTEN:
 | 
			
		||||
                break;
 | 
			
		||||
            case CUT_BELOW:
 | 
			
		||||
            case BOOST_BELOW:
 | 
			
		||||
                if (detect < threshold)
 | 
			
		||||
                    new_gain = CLIP(ONE + makeup + (threshold - detect) * ratio, ONE, range);
 | 
			
		||||
                ld = LIN2LOG(detect);
 | 
			
		||||
                if (ld < threshold_log) {
 | 
			
		||||
                    ftype new_log_gain = CLIP(makeup + (threshold_log - ld) * ratio, ZERO, range) * power;
 | 
			
		||||
                    new_lin_gain = LOG2LIN(new_log_gain);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case CUT_ABOVE:
 | 
			
		||||
            case BOOST_ABOVE:
 | 
			
		||||
                if (detect > threshold)
 | 
			
		||||
                    new_gain = CLIP(ONE + makeup + (detect - threshold) * ratio, ONE, range);
 | 
			
		||||
                ld = LIN2LOG(detect);
 | 
			
		||||
                if (ld > threshold_log) {
 | 
			
		||||
                    ftype new_log_gain = CLIP(makeup + (ld - threshold_log) * ratio, ZERO, range) * power;
 | 
			
		||||
                    new_lin_gain = LOG2LIN(new_log_gain);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (power < 0)
 | 
			
		||||
                new_gain = ONE / new_gain;
 | 
			
		||||
            f = (new_lin_gain > lin_gain) * gattack + (new_lin_gain <= lin_gain) * grelease;
 | 
			
		||||
            new_lin_gain = f * new_lin_gain + (ONE - f) * lin_gain;
 | 
			
		||||
 | 
			
		||||
            if (mode > LISTEN) {
 | 
			
		||||
                ftype delta = new_gain - gain;
 | 
			
		||||
 | 
			
		||||
                if (delta > EPSILON)
 | 
			
		||||
                    new_gain = gain + attack * delta;
 | 
			
		||||
                else if (delta < -EPSILON)
 | 
			
		||||
                    new_gain = gain + release * delta;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (gain != new_gain || !init) {
 | 
			
		||||
                gain = new_gain;
 | 
			
		||||
            if (lin_gain != new_lin_gain || !init) {
 | 
			
		||||
                init = 1;
 | 
			
		||||
                lin_gain = new_lin_gain;
 | 
			
		||||
 | 
			
		||||
                switch (tftype) {
 | 
			
		||||
                case 0:
 | 
			
		||||
                    k = itqfactor / gain;
 | 
			
		||||
                    k = itqfactor / lin_gain;
 | 
			
		||||
 | 
			
		||||
                    fa[0] = ONE / (ONE + fg * (fg + k));
 | 
			
		||||
                    fa[1] = fg * fa[0];
 | 
			
		||||
                    fa[2] = fg * fa[1];
 | 
			
		||||
 | 
			
		||||
                    fm[0] = ONE;
 | 
			
		||||
                    fm[1] = k * (gain * gain - ONE);
 | 
			
		||||
                    fm[1] = k * (lin_gain * lin_gain - ONE);
 | 
			
		||||
                    fm[2] = ZERO;
 | 
			
		||||
                    break;
 | 
			
		||||
                case 1:
 | 
			
		||||
                    k = itqfactor;
 | 
			
		||||
                    g = fg / SQRT(gain);
 | 
			
		||||
                    g = fg / SQRT(lin_gain);
 | 
			
		||||
 | 
			
		||||
                    fa[0] = ONE / (ONE + g * (g + k));
 | 
			
		||||
                    fa[1] = g * fa[0];
 | 
			
		||||
                    fa[2] = g * fa[1];
 | 
			
		||||
 | 
			
		||||
                    fm[0] = ONE;
 | 
			
		||||
                    fm[1] = k * (gain - ONE);
 | 
			
		||||
                    fm[2] = gain * gain - ONE;
 | 
			
		||||
                    fm[1] = k * (lin_gain - ONE);
 | 
			
		||||
                    fm[2] = lin_gain * lin_gain - ONE;
 | 
			
		||||
                    break;
 | 
			
		||||
                case 2:
 | 
			
		||||
                    k = itqfactor;
 | 
			
		||||
                    g = fg * SQRT(gain);
 | 
			
		||||
                    g = fg * SQRT(lin_gain);
 | 
			
		||||
 | 
			
		||||
                    fa[0] = ONE / (ONE + g * (g + k));
 | 
			
		||||
                    fa[1] = g * fa[0];
 | 
			
		||||
                    fa[2] = g * fa[1];
 | 
			
		||||
 | 
			
		||||
                    fm[0] = gain * gain;
 | 
			
		||||
                    fm[1] = k * (ONE - gain) * gain;
 | 
			
		||||
                    fm[2] = ONE - gain * gain;
 | 
			
		||||
                    fm[0] = lin_gain * lin_gain;
 | 
			
		||||
                    fm[1] = k * (ONE - lin_gain) * lin_gain;
 | 
			
		||||
                    fm[2] = ONE - lin_gain * lin_gain;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            v = fn(get_svf)(src[n], fm, fa, fstate);
 | 
			
		||||
            v = mode == -1 ? listen : v;
 | 
			
		||||
            v = mode == LISTEN ? listen : v;
 | 
			
		||||
            dst[n] = is_disabled ? src[n] : v;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fn(cc->gain) = gain;
 | 
			
		||||
        fn(cc->detect) = detect;
 | 
			
		||||
        fn(cc->lin_gain) = lin_gain;
 | 
			
		||||
        cc->init = 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -18,18 +18,27 @@
 | 
			
		||||
 | 
			
		||||
#include <float.h>
 | 
			
		||||
 | 
			
		||||
#include "libavutil/ffmath.h"
 | 
			
		||||
#include "libavutil/opt.h"
 | 
			
		||||
#include "avfilter.h"
 | 
			
		||||
#include "audio.h"
 | 
			
		||||
#include "formats.h"
 | 
			
		||||
 | 
			
		||||
enum DetectionModes {
 | 
			
		||||
    DET_UNSET = 0,
 | 
			
		||||
    DET_DISABLED,
 | 
			
		||||
    DET_OFF,
 | 
			
		||||
    DET_ON,
 | 
			
		||||
    NB_DMODES,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum FilterModes {
 | 
			
		||||
    LISTEN = -1,
 | 
			
		||||
    CUT_BELOW,
 | 
			
		||||
    CUT_ABOVE,
 | 
			
		||||
    BOOST_BELOW,
 | 
			
		||||
    BOOST_ABOVE,
 | 
			
		||||
    NB_MODES,
 | 
			
		||||
    NB_FMODES,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct ChannelContext {
 | 
			
		||||
@ -37,14 +46,19 @@ typedef struct ChannelContext {
 | 
			
		||||
    double dstate_double[2];
 | 
			
		||||
    double fstate_double[2];
 | 
			
		||||
    double tstate_double[2];
 | 
			
		||||
    double gain_double;
 | 
			
		||||
    double threshold_double;
 | 
			
		||||
    double lin_gain_double;
 | 
			
		||||
    double detect_double;
 | 
			
		||||
    double threshold_log_double;
 | 
			
		||||
    double new_threshold_log_double;
 | 
			
		||||
    float fa_float[3], fm_float[3];
 | 
			
		||||
    float dstate_float[2];
 | 
			
		||||
    float fstate_float[2];
 | 
			
		||||
    float tstate_float[2];
 | 
			
		||||
    float gain_float;
 | 
			
		||||
    float threshold_float;
 | 
			
		||||
    float lin_gain_float;
 | 
			
		||||
    float detect_float;
 | 
			
		||||
    float threshold_log_float;
 | 
			
		||||
    float new_threshold_log_float;
 | 
			
		||||
    int detection;
 | 
			
		||||
    int init;
 | 
			
		||||
} ChannelContext;
 | 
			
		||||
 | 
			
		||||
@ -52,6 +66,7 @@ typedef struct AudioDynamicEqualizerContext {
 | 
			
		||||
    const AVClass *class;
 | 
			
		||||
 | 
			
		||||
    double threshold;
 | 
			
		||||
    double threshold_log;
 | 
			
		||||
    double dfrequency;
 | 
			
		||||
    double dqfactor;
 | 
			
		||||
    double tfrequency;
 | 
			
		||||
@ -59,10 +74,12 @@ typedef struct AudioDynamicEqualizerContext {
 | 
			
		||||
    double ratio;
 | 
			
		||||
    double range;
 | 
			
		||||
    double makeup;
 | 
			
		||||
    double attack;
 | 
			
		||||
    double release;
 | 
			
		||||
    double attack_coef;
 | 
			
		||||
    double release_coef;
 | 
			
		||||
    double dattack;
 | 
			
		||||
    double drelease;
 | 
			
		||||
    double dattack_coef;
 | 
			
		||||
    double drelease_coef;
 | 
			
		||||
    double gattack_coef;
 | 
			
		||||
    double grelease_coef;
 | 
			
		||||
    int mode;
 | 
			
		||||
    int detection;
 | 
			
		||||
    int tftype;
 | 
			
		||||
@ -100,7 +117,7 @@ static int query_formats(AVFilterContext *ctx)
 | 
			
		||||
 | 
			
		||||
static double get_coef(double x, double sr)
 | 
			
		||||
{
 | 
			
		||||
    return 1.0 - exp(-1000. / (x * sr));
 | 
			
		||||
    return 1.0 - exp(-1.0 / (0.001 * x * sr));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct ThreadData {
 | 
			
		||||
@ -135,12 +152,6 @@ static int config_input(AVFilterLink *inlink)
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) {
 | 
			
		||||
        ChannelContext *cc = &s->cc[ch];
 | 
			
		||||
        cc->gain_float = 1.f;
 | 
			
		||||
        cc->gain_double = 1.0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -191,12 +202,12 @@ static const AVOption adynamicequalizer_options[] = {
 | 
			
		||||
    { "dqfactor",   "set detection Q factor",  OFFSET(dqfactor),   AV_OPT_TYPE_DOUBLE, {.dbl=1},    0.001, 1000,    FLAGS },
 | 
			
		||||
    { "tfrequency", "set target frequency",    OFFSET(tfrequency), AV_OPT_TYPE_DOUBLE, {.dbl=1000},     2, 1000000, FLAGS },
 | 
			
		||||
    { "tqfactor",   "set target Q factor",     OFFSET(tqfactor),   AV_OPT_TYPE_DOUBLE, {.dbl=1},    0.001, 1000,    FLAGS },
 | 
			
		||||
    { "attack",     "set attack duration",     OFFSET(attack),     AV_OPT_TYPE_DOUBLE, {.dbl=20},       1, 2000,    FLAGS },
 | 
			
		||||
    { "release",    "set release duration",    OFFSET(release),    AV_OPT_TYPE_DOUBLE, {.dbl=200},      1, 2000,    FLAGS },
 | 
			
		||||
    { "attack", "set detection attack duration", OFFSET(dattack),  AV_OPT_TYPE_DOUBLE, {.dbl=20},    0.01, 2000,    FLAGS },
 | 
			
		||||
    { "release","set detection release duration",OFFSET(drelease), AV_OPT_TYPE_DOUBLE, {.dbl=200},   0.01, 2000,    FLAGS },
 | 
			
		||||
    { "ratio",      "set ratio factor",        OFFSET(ratio),      AV_OPT_TYPE_DOUBLE, {.dbl=1},        0, 30,      FLAGS },
 | 
			
		||||
    { "makeup",     "set makeup gain",         OFFSET(makeup),     AV_OPT_TYPE_DOUBLE, {.dbl=0},        0, 100,     FLAGS },
 | 
			
		||||
    { "range",      "set max gain",            OFFSET(range),      AV_OPT_TYPE_DOUBLE, {.dbl=50},       1, 200,     FLAGS },
 | 
			
		||||
    { "mode",       "set mode",                OFFSET(mode),       AV_OPT_TYPE_INT,    {.i64=0},  LISTEN,NB_MODES-1,FLAGS, "mode" },
 | 
			
		||||
    { "makeup",     "set makeup gain",         OFFSET(makeup),     AV_OPT_TYPE_DOUBLE, {.dbl=0},        0, 1000,    FLAGS },
 | 
			
		||||
    { "range",      "set max gain",            OFFSET(range),      AV_OPT_TYPE_DOUBLE, {.dbl=50},       1, 2000,    FLAGS },
 | 
			
		||||
    { "mode",       "set mode",                OFFSET(mode),       AV_OPT_TYPE_INT,    {.i64=0},  LISTEN,NB_FMODES-1,FLAGS, "mode" },
 | 
			
		||||
    {   "listen",   0,                         0,                  AV_OPT_TYPE_CONST,  {.i64=LISTEN},   0, 0,       FLAGS, "mode" },
 | 
			
		||||
    {   "cutbelow", 0,                         0,                  AV_OPT_TYPE_CONST,  {.i64=CUT_BELOW},0, 0,       FLAGS, "mode" },
 | 
			
		||||
    {   "cutabove", 0,                         0,                  AV_OPT_TYPE_CONST,  {.i64=CUT_ABOVE},0, 0,       FLAGS, "mode" },
 | 
			
		||||
@ -211,10 +222,10 @@ static const AVOption adynamicequalizer_options[] = {
 | 
			
		||||
    {   "bell",     0,                         0,                  AV_OPT_TYPE_CONST,  {.i64=0},        0, 0,       FLAGS, "tftype" },
 | 
			
		||||
    {   "lowshelf", 0,                         0,                  AV_OPT_TYPE_CONST,  {.i64=1},        0, 0,       FLAGS, "tftype" },
 | 
			
		||||
    {   "highshelf",0,                         0,                  AV_OPT_TYPE_CONST,  {.i64=2},        0, 0,       FLAGS, "tftype" },
 | 
			
		||||
    { "auto",       "set auto threshold",      OFFSET(detection),  AV_OPT_TYPE_INT,    {.i64=-1},      -1, 1,       FLAGS, "auto" },
 | 
			
		||||
    {   "disabled", 0,                         0,                  AV_OPT_TYPE_CONST,  {.i64=-1},       0, 0,       FLAGS, "auto" },
 | 
			
		||||
    {   "off",      0,                         0,                  AV_OPT_TYPE_CONST,  {.i64=0},        0, 0,       FLAGS, "auto" },
 | 
			
		||||
    {   "on",       0,                         0,                  AV_OPT_TYPE_CONST,  {.i64=1},        0, 0,       FLAGS, "auto" },
 | 
			
		||||
    { "auto",       "set auto threshold",      OFFSET(detection),  AV_OPT_TYPE_INT,    {.i64=DET_OFF},DET_DISABLED,NB_DMODES-1,FLAGS, "auto" },
 | 
			
		||||
    {   "disabled", 0,                         0,                  AV_OPT_TYPE_CONST,  {.i64=DET_DISABLED}, 0, 0,   FLAGS, "auto" },
 | 
			
		||||
    {   "off",      0,                         0,                  AV_OPT_TYPE_CONST,  {.i64=DET_OFF},      0, 0,   FLAGS, "auto" },
 | 
			
		||||
    {   "on",       0,                         0,                  AV_OPT_TYPE_CONST,  {.i64=DET_ON},       0, 0,   FLAGS, "auto" },
 | 
			
		||||
    { "precision", "set processing precision", OFFSET(precision),  AV_OPT_TYPE_INT,    {.i64=0},        0, 2,       AF, "precision" },
 | 
			
		||||
    {   "auto",  "set auto processing precision",                  0, AV_OPT_TYPE_CONST, {.i64=0},      0, 0,       AF, "precision" },
 | 
			
		||||
    {   "float", "set single-floating point processing precision", 0, AV_OPT_TYPE_CONST, {.i64=1},      0, 0,       AF, "precision" },
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user