avfilter/af_crystalizer: refactor some code

This commit is contained in:
Paul B Mahol 2021-08-29 00:04:54 +02:00
parent 5f55467c0b
commit 3b780e818a

View File

@ -29,7 +29,7 @@ typedef struct CrystalizerContext {
float mult; float mult;
int clip; int clip;
AVFrame *prev; AVFrame *prev;
int (*filter)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); int (*filter[2][2])(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs);
} CrystalizerContext; } CrystalizerContext;
#define OFFSET(x) offsetof(CrystalizerContext, x) #define OFFSET(x) offsetof(CrystalizerContext, x)
@ -68,10 +68,11 @@ typedef struct ThreadData {
int nb_samples; int nb_samples;
int channels; int channels;
float mult; float mult;
int clip;
} ThreadData; } ThreadData;
static int filter_flt(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) static av_always_inline int filter_flt(AVFilterContext *ctx, void *arg,
int jobnr, int nb_jobs,
int inverse, int clip)
{ {
ThreadData *td = arg; ThreadData *td = arg;
void **d = td->d; void **d = td->d;
@ -80,7 +81,7 @@ static int filter_flt(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
const int nb_samples = td->nb_samples; const int nb_samples = td->nb_samples;
const int channels = td->channels; const int channels = td->channels;
const float mult = td->mult; const float mult = td->mult;
const int clip = td->clip; const float scale = 1.f / (-mult + 1.f);
const int start = (channels * jobnr) / nb_jobs; const int start = (channels * jobnr) / nb_jobs;
const int end = (channels * (jobnr+1)) / nb_jobs; const int end = (channels * (jobnr+1)) / nb_jobs;
float *prv = p[0]; float *prv = p[0];
@ -92,8 +93,14 @@ static int filter_flt(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
for (n = 0; n < nb_samples; n++) { for (n = 0; n < nb_samples; n++) {
float current = src[c]; float current = src[c];
dst[c] = current + (current - prv[c]) * mult;
prv[c] = current; if (inverse) {
dst[c] = (current - prv[c] * mult) * scale;
prv[c] = dst[c];
} else {
dst[c] = current + (current - prv[c]) * mult;
prv[c] = current;
}
if (clip) { if (clip) {
dst[c] = av_clipf(dst[c], -1.f, 1.f); dst[c] = av_clipf(dst[c], -1.f, 1.f);
} }
@ -106,7 +113,9 @@ static int filter_flt(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
return 0; return 0;
} }
static int filter_dbl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) static av_always_inline int filter_dbl(AVFilterContext *ctx, void *arg,
int jobnr, int nb_jobs,
int inverse, int clip)
{ {
ThreadData *td = arg; ThreadData *td = arg;
void **d = td->d; void **d = td->d;
@ -115,7 +124,7 @@ static int filter_dbl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
const int nb_samples = td->nb_samples; const int nb_samples = td->nb_samples;
const int channels = td->channels; const int channels = td->channels;
const double mult = td->mult; const double mult = td->mult;
const int clip = td->clip; const double scale = 1.0 / (-mult + 1.0);
const int start = (channels * jobnr) / nb_jobs; const int start = (channels * jobnr) / nb_jobs;
const int end = (channels * (jobnr+1)) / nb_jobs; const int end = (channels * (jobnr+1)) / nb_jobs;
double *prv = p[0]; double *prv = p[0];
@ -128,8 +137,13 @@ static int filter_dbl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
for (n = 0; n < nb_samples; n++) { for (n = 0; n < nb_samples; n++) {
double current = src[c]; double current = src[c];
dst[c] = current + (current - prv[c]) * mult; if (inverse) {
prv[c] = current; dst[c] = (current - prv[c] * mult) * scale;
prv[c] = dst[c];
} else {
dst[c] = current + (current - prv[c]) * mult;
prv[c] = current;
}
if (clip) { if (clip) {
dst[c] = av_clipd(dst[c], -1., 1.); dst[c] = av_clipd(dst[c], -1., 1.);
} }
@ -142,7 +156,9 @@ static int filter_dbl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
return 0; return 0;
} }
static int filter_fltp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) static av_always_inline int filter_fltp(AVFilterContext *ctx, void *arg,
int jobnr, int nb_jobs,
int inverse, int clip)
{ {
ThreadData *td = arg; ThreadData *td = arg;
void **d = td->d; void **d = td->d;
@ -151,7 +167,7 @@ static int filter_fltp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
const int nb_samples = td->nb_samples; const int nb_samples = td->nb_samples;
const int channels = td->channels; const int channels = td->channels;
const float mult = td->mult; const float mult = td->mult;
const int clip = td->clip; const float scale = 1.f / (-mult + 1.f);
const int start = (channels * jobnr) / nb_jobs; const int start = (channels * jobnr) / nb_jobs;
const int end = (channels * (jobnr+1)) / nb_jobs; const int end = (channels * (jobnr+1)) / nb_jobs;
int n, c; int n, c;
@ -164,8 +180,13 @@ static int filter_fltp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
for (n = 0; n < nb_samples; n++) { for (n = 0; n < nb_samples; n++) {
float current = src[n]; float current = src[n];
dst[n] = current + (current - prv[0]) * mult; if (inverse) {
prv[0] = current; dst[n] = (current - prv[0] * mult) * scale;
prv[0] = dst[n];
} else {
dst[n] = current + (current - prv[0]) * mult;
prv[0] = current;
}
if (clip) { if (clip) {
dst[n] = av_clipf(dst[n], -1.f, 1.f); dst[n] = av_clipf(dst[n], -1.f, 1.f);
} }
@ -175,7 +196,9 @@ static int filter_fltp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
return 0; return 0;
} }
static int filter_dblp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) static av_always_inline int filter_dblp(AVFilterContext *ctx, void *arg,
int jobnr, int nb_jobs,
int inverse, int clip)
{ {
ThreadData *td = arg; ThreadData *td = arg;
void **d = td->d; void **d = td->d;
@ -184,7 +207,7 @@ static int filter_dblp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
const int nb_samples = td->nb_samples; const int nb_samples = td->nb_samples;
const int channels = td->channels; const int channels = td->channels;
const double mult = td->mult; const double mult = td->mult;
const int clip = td->clip; const double scale = 1.0 / (-mult + 1.0);
const int start = (channels * jobnr) / nb_jobs; const int start = (channels * jobnr) / nb_jobs;
const int end = (channels * (jobnr+1)) / nb_jobs; const int end = (channels * (jobnr+1)) / nb_jobs;
int n, c; int n, c;
@ -197,8 +220,13 @@ static int filter_dblp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
for (n = 0; n < nb_samples; n++) { for (n = 0; n < nb_samples; n++) {
double current = src[n]; double current = src[n];
dst[n] = current + (current - prv[0]) * mult; if (inverse) {
prv[0] = current; dst[n] = (current - prv[0] * mult) * scale;
prv[0] = dst[n];
} else {
dst[n] = current + (current - prv[0]) * mult;
prv[0] = current;
}
if (clip) { if (clip) {
dst[n] = av_clipd(dst[n], -1., 1.); dst[n] = av_clipd(dst[n], -1., 1.);
} }
@ -208,146 +236,31 @@ static int filter_dblp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
return 0; return 0;
} }
static int ifilter_flt(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) #define filters(fmt, inverse, clip, i, c) \
{ static int filter_## inverse ##_## fmt ##_## clip(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
ThreadData *td = arg; { \
void **d = td->d; return filter_## fmt(ctx, arg, jobnr, nb_jobs, i, c); \
void **p = td->p;
const void **s = td->s;
const int nb_samples = td->nb_samples;
const int channels = td->channels;
const float mult = -td->mult;
const float scale = 1.f / (mult + 1.f);
const int clip = td->clip;
const int start = (channels * jobnr) / nb_jobs;
const int end = (channels * (jobnr+1)) / nb_jobs;
float *prv = p[0];
int n, c;
for (c = start; c < end; c++) {
const float *src = s[0];
float *dst = d[0];
for (n = 0; n < nb_samples; n++) {
float current = src[c];
dst[c] = (current + prv[c] * mult) * scale;
prv[c] = dst[c];
if (clip) {
dst[c] = av_clipf(dst[c], -1.f, 1.f);
}
dst += channels;
src += channels;
}
}
return 0;
} }
static int ifilter_dbl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) filters(flt, inverse, noclip, 1, 0)
{ filters(flt, inverse, clip, 1, 1)
ThreadData *td = arg; filters(flt, noinverse, noclip, 0, 0)
void **d = td->d; filters(flt, noinverse, clip, 0, 1)
void **p = td->p;
const void **s = td->s;
const int nb_samples = td->nb_samples;
const int channels = td->channels;
const double mult = -td->mult;
const double scale = 1.0 / (mult + 1.0);
const int clip = td->clip;
const int start = (channels * jobnr) / nb_jobs;
const int end = (channels * (jobnr+1)) / nb_jobs;
double *prv = p[0];
int n, c;
for (c = start; c < end; c++) { filters(fltp, inverse, noclip, 1, 0)
const double *src = s[0]; filters(fltp, inverse, clip, 1, 1)
double *dst = d[0]; filters(fltp, noinverse, noclip, 0, 0)
filters(fltp, noinverse, clip, 0, 1)
for (n = 0; n < nb_samples; n++) { filters(dbl, inverse, noclip, 1, 0)
double current = src[c]; filters(dbl, inverse, clip, 1, 1)
filters(dbl, noinverse, noclip, 0, 0)
filters(dbl, noinverse, clip, 0, 1)
dst[c] = (current + prv[c] * mult) * scale; filters(dblp, inverse, noclip, 1, 0)
prv[c] = dst[c]; filters(dblp, inverse, clip, 1, 1)
if (clip) { filters(dblp, noinverse, noclip, 0, 0)
dst[c] = av_clipd(dst[c], -1., 1.); filters(dblp, noinverse, clip, 0, 1)
}
dst += channels;
src += channels;
}
}
return 0;
}
static int ifilter_fltp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
{
ThreadData *td = arg;
void **d = td->d;
void **p = td->p;
const void **s = td->s;
const int nb_samples = td->nb_samples;
const int channels = td->channels;
const float mult = -td->mult;
const float scale = 1.f / (mult + 1.f);
const int clip = td->clip;
const int start = (channels * jobnr) / nb_jobs;
const int end = (channels * (jobnr+1)) / nb_jobs;
int n, c;
for (c = start; c < end; c++) {
const float *src = s[c];
float *dst = d[c];
float *prv = p[c];
for (n = 0; n < nb_samples; n++) {
float current = src[n];
dst[n] = (current + prv[0] * mult) * scale;
prv[0] = dst[n];
if (clip) {
dst[n] = av_clipf(dst[n], -1.f, 1.f);
}
}
}
return 0;
}
static int ifilter_dblp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
{
ThreadData *td = arg;
void **d = td->d;
void **p = td->p;
const void **s = td->s;
const int nb_samples = td->nb_samples;
const int channels = td->channels;
const double mult = -td->mult;
const double scale = 1.0 / (mult + 1.0);
const int clip = td->clip;
const int start = (channels * jobnr) / nb_jobs;
const int end = (channels * (jobnr+1)) / nb_jobs;
int n, c;
for (c = start; c < end; c++) {
const double *src = s[c];
double *dst = d[c];
double *prv = p[c];
for (n = 0; n < nb_samples; n++) {
double current = src[n];
dst[n] = (current + prv[0] * mult) * scale;
prv[0] = dst[n];
if (clip) {
dst[n] = av_clipd(dst[n], -1., 1.);
}
}
}
return 0;
}
static int config_input(AVFilterLink *inlink) static int config_input(AVFilterLink *inlink)
{ {
@ -355,10 +268,32 @@ static int config_input(AVFilterLink *inlink)
CrystalizerContext *s = ctx->priv; CrystalizerContext *s = ctx->priv;
switch (inlink->format) { switch (inlink->format) {
case AV_SAMPLE_FMT_FLT: s->filter = s->mult >= 0.f ? filter_flt : ifilter_flt; break; case AV_SAMPLE_FMT_FLT:
case AV_SAMPLE_FMT_DBL: s->filter = s->mult >= 0.f ? filter_dbl : ifilter_dbl; break; s->filter[0][0] = filter_inverse_flt_noclip;
case AV_SAMPLE_FMT_FLTP: s->filter = s->mult >= 0.f ? filter_fltp : ifilter_fltp; break; s->filter[1][0] = filter_noinverse_flt_noclip;
case AV_SAMPLE_FMT_DBLP: s->filter = s->mult >= 0.f ? filter_dblp : ifilter_dblp; break; s->filter[0][1] = filter_inverse_flt_clip;
s->filter[1][1] = filter_noinverse_flt_clip;
break;
case AV_SAMPLE_FMT_FLTP:
s->filter[0][0] = filter_inverse_fltp_noclip;
s->filter[1][0] = filter_noinverse_fltp_noclip;
s->filter[0][1] = filter_inverse_fltp_clip;
s->filter[1][1] = filter_noinverse_fltp_clip;
break;
case AV_SAMPLE_FMT_DBL:
s->filter[0][0] = filter_inverse_dbl_noclip;
s->filter[1][0] = filter_noinverse_dbl_noclip;
s->filter[0][1] = filter_inverse_dbl_clip;
s->filter[1][1] = filter_noinverse_dbl_clip;
break;
case AV_SAMPLE_FMT_DBLP:
s->filter[0][0] = filter_inverse_dblp_noclip;
s->filter[1][0] = filter_noinverse_dblp_noclip;
s->filter[0][1] = filter_inverse_dblp_clip;
s->filter[1][1] = filter_noinverse_dblp_clip;
break;
default:
return AVERROR_BUG;
} }
return 0; return 0;
@ -397,8 +332,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
td.nb_samples = in->nb_samples; td.nb_samples = in->nb_samples;
td.channels = in->channels; td.channels = in->channels;
td.mult = ctx->is_disabled ? 0.f : s->mult; td.mult = ctx->is_disabled ? 0.f : s->mult;
td.clip = s->clip; ff_filter_execute(ctx, s->filter[td.mult >= 0.f][s->clip], &td, NULL,
ff_filter_execute(ctx, s->filter, &td, NULL,
FFMIN(inlink->channels, ff_filter_get_nb_threads(ctx))); FFMIN(inlink->channels, ff_filter_get_nb_threads(ctx)));
if (out != in) if (out != in)