|
|
|
@ -52,197 +52,91 @@ typedef struct ThreadData { |
|
|
|
|
float mult; |
|
|
|
|
} ThreadData; |
|
|
|
|
|
|
|
|
|
static av_always_inline int filter_flt(AVFilterContext *ctx, void *arg, |
|
|
|
|
int jobnr, int nb_jobs, |
|
|
|
|
int inverse, int clip) |
|
|
|
|
{ |
|
|
|
|
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 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]; |
|
|
|
|
|
|
|
|
|
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) { |
|
|
|
|
dst[c] = av_clipf(dst[c], -1.f, 1.f); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
dst += channels; |
|
|
|
|
src += channels; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
#define filters(fmt, type, inverse, clp, inverset, clip, one, clip_fn, packed) \ |
|
|
|
|
static int filter_## inverse ##_## fmt ##_## clp(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 type mult = td->mult; \
|
|
|
|
|
const type scale = one / (-mult + one); \
|
|
|
|
|
const int start = (channels * jobnr) / nb_jobs; \
|
|
|
|
|
const int end = (channels * (jobnr+1)) / nb_jobs; \
|
|
|
|
|
\
|
|
|
|
|
if (packed) { \
|
|
|
|
|
type *prv = p[0]; \
|
|
|
|
|
for (int c = start; c < end; c++) { \
|
|
|
|
|
const type *src = s[0]; \
|
|
|
|
|
type *dst = d[0]; \
|
|
|
|
|
\
|
|
|
|
|
for (int n = 0; n < nb_samples; n++) { \
|
|
|
|
|
type current = src[c]; \
|
|
|
|
|
\
|
|
|
|
|
if (inverset) { \
|
|
|
|
|
dst[c] = (current - prv[c] * mult) * scale; \
|
|
|
|
|
prv[c] = dst[c]; \
|
|
|
|
|
} else { \
|
|
|
|
|
dst[c] = current + (current - prv[c]) * mult; \
|
|
|
|
|
prv[c] = current; \
|
|
|
|
|
} \
|
|
|
|
|
if (clip) { \
|
|
|
|
|
dst[c] = clip_fn(dst[c], -one, one); \
|
|
|
|
|
} \
|
|
|
|
|
\
|
|
|
|
|
dst += channels; \
|
|
|
|
|
src += channels; \
|
|
|
|
|
} \
|
|
|
|
|
} \
|
|
|
|
|
} else { \
|
|
|
|
|
for (int c = start; c < end; c++) { \
|
|
|
|
|
const type *src = s[c]; \
|
|
|
|
|
type *dst = d[c]; \
|
|
|
|
|
type *prv = p[c]; \
|
|
|
|
|
\
|
|
|
|
|
for (int n = 0; n < nb_samples; n++) { \
|
|
|
|
|
type current = src[n]; \
|
|
|
|
|
\
|
|
|
|
|
if (inverset) { \
|
|
|
|
|
dst[n] = (current - prv[0] * mult) * scale; \
|
|
|
|
|
prv[0] = dst[n]; \
|
|
|
|
|
} else { \
|
|
|
|
|
dst[n] = current + (current - prv[0]) * mult; \
|
|
|
|
|
prv[0] = current; \
|
|
|
|
|
} \
|
|
|
|
|
if (clip) { \
|
|
|
|
|
dst[n] = clip_fn(dst[n], -one, one); \
|
|
|
|
|
} \
|
|
|
|
|
} \
|
|
|
|
|
} \
|
|
|
|
|
} \
|
|
|
|
|
\
|
|
|
|
|
return 0; \
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static av_always_inline int filter_dbl(AVFilterContext *ctx, void *arg, |
|
|
|
|
int jobnr, int nb_jobs, |
|
|
|
|
int inverse, int clip) |
|
|
|
|
{ |
|
|
|
|
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 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++) { |
|
|
|
|
const double *src = s[0]; |
|
|
|
|
double *dst = d[0]; |
|
|
|
|
|
|
|
|
|
for (n = 0; n < nb_samples; n++) { |
|
|
|
|
double current = src[c]; |
|
|
|
|
|
|
|
|
|
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) { |
|
|
|
|
dst[c] = av_clipd(dst[c], -1., 1.); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
dst += channels; |
|
|
|
|
src += channels; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static av_always_inline int filter_fltp(AVFilterContext *ctx, void *arg, |
|
|
|
|
int jobnr, int nb_jobs, |
|
|
|
|
int inverse, int clip) |
|
|
|
|
{ |
|
|
|
|
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 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]; |
|
|
|
|
|
|
|
|
|
if (inverse) { |
|
|
|
|
dst[n] = (current - prv[0] * mult) * scale; |
|
|
|
|
prv[0] = dst[n]; |
|
|
|
|
} else { |
|
|
|
|
dst[n] = current + (current - prv[0]) * mult; |
|
|
|
|
prv[0] = current; |
|
|
|
|
} |
|
|
|
|
if (clip) { |
|
|
|
|
dst[n] = av_clipf(dst[n], -1.f, 1.f); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static av_always_inline int filter_dblp(AVFilterContext *ctx, void *arg, |
|
|
|
|
int jobnr, int nb_jobs, |
|
|
|
|
int inverse, int clip) |
|
|
|
|
{ |
|
|
|
|
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 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]; |
|
|
|
|
|
|
|
|
|
if (inverse) { |
|
|
|
|
dst[n] = (current - prv[0] * mult) * scale; |
|
|
|
|
prv[0] = dst[n]; |
|
|
|
|
} else { |
|
|
|
|
dst[n] = current + (current - prv[0]) * mult; |
|
|
|
|
prv[0] = current; |
|
|
|
|
} |
|
|
|
|
if (clip) { |
|
|
|
|
dst[n] = av_clipd(dst[n], -1., 1.); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#define filters(fmt, inverse, clip, i, c) \ |
|
|
|
|
static int filter_## inverse ##_## fmt ##_## clip(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
|
|
|
|
|
{ \
|
|
|
|
|
return filter_## fmt(ctx, arg, jobnr, nb_jobs, i, c); \
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
filters(flt, inverse, noclip, 1, 0) |
|
|
|
|
filters(flt, inverse, clip, 1, 1) |
|
|
|
|
filters(flt, noinverse, noclip, 0, 0) |
|
|
|
|
filters(flt, noinverse, clip, 0, 1) |
|
|
|
|
|
|
|
|
|
filters(fltp, inverse, noclip, 1, 0) |
|
|
|
|
filters(fltp, inverse, clip, 1, 1) |
|
|
|
|
filters(fltp, noinverse, noclip, 0, 0) |
|
|
|
|
filters(fltp, noinverse, clip, 0, 1) |
|
|
|
|
|
|
|
|
|
filters(dbl, inverse, noclip, 1, 0) |
|
|
|
|
filters(dbl, inverse, clip, 1, 1) |
|
|
|
|
filters(dbl, noinverse, noclip, 0, 0) |
|
|
|
|
filters(dbl, noinverse, clip, 0, 1) |
|
|
|
|
|
|
|
|
|
filters(dblp, inverse, noclip, 1, 0) |
|
|
|
|
filters(dblp, inverse, clip, 1, 1) |
|
|
|
|
filters(dblp, noinverse, noclip, 0, 0) |
|
|
|
|
filters(dblp, noinverse, clip, 0, 1) |
|
|
|
|
filters(flt, float, inverse, noclip, 1, 0, 1.f, av_clipf, 1) |
|
|
|
|
filters(flt, float, inverse, clip, 1, 1, 1.f, av_clipf, 1) |
|
|
|
|
filters(flt, float, noinverse, noclip, 0, 0, 1.f, av_clipf, 1) |
|
|
|
|
filters(flt, float, noinverse, clip, 0, 1, 1.f, av_clipf, 1) |
|
|
|
|
|
|
|
|
|
filters(fltp, float, inverse, noclip, 1, 0, 1.f, av_clipf, 0) |
|
|
|
|
filters(fltp, float, inverse, clip, 1, 1, 1.f, av_clipf, 0) |
|
|
|
|
filters(fltp, float, noinverse, noclip, 0, 0, 1.f, av_clipf, 0) |
|
|
|
|
filters(fltp, float, noinverse, clip, 0, 1, 1.f, av_clipf, 0) |
|
|
|
|
|
|
|
|
|
filters(dbl, double, inverse, noclip, 1, 0, 1.0, av_clipd, 1) |
|
|
|
|
filters(dbl, double, inverse, clip, 1, 1, 1.0, av_clipd, 1) |
|
|
|
|
filters(dbl, double, noinverse, noclip, 0, 0, 1.0, av_clipd, 1) |
|
|
|
|
filters(dbl, double, noinverse, clip, 0, 1, 1.0, av_clipd, 1) |
|
|
|
|
|
|
|
|
|
filters(dblp, double, inverse, noclip, 1, 0, 1.0, av_clipd, 0) |
|
|
|
|
filters(dblp, double, inverse, clip, 1, 1, 1.0, av_clipd, 0) |
|
|
|
|
filters(dblp, double, noinverse, noclip, 0, 0, 1.0, av_clipd, 0) |
|
|
|
|
filters(dblp, double, noinverse, clip, 0, 1, 1.0, av_clipd, 0) |
|
|
|
|
|
|
|
|
|
static int config_input(AVFilterLink *inlink) |
|
|
|
|
{ |
|
|
|
|