Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2020-12-21 15:07:23 +0300
committerPaul B Mahol <onemda@gmail.com>2020-12-21 15:15:27 +0300
commit204a90643713b03003b4d818dbc9dddddbd465bd (patch)
tree900e993f35d6f1e74a1bcc65a1b9f298ad33537c /libavfilter/af_crystalizer.c
parent28aedc7f54cd5aca5161e65493795f34050f6d7d (diff)
avfilter/af_crystalizer: implement inverse filtering
Diffstat (limited to 'libavfilter/af_crystalizer.c')
-rw-r--r--libavfilter/af_crystalizer.c169
1 files changed, 161 insertions, 8 deletions
diff --git a/libavfilter/af_crystalizer.c b/libavfilter/af_crystalizer.c
index 5f7bce0a8c..d1f44984ac 100644
--- a/libavfilter/af_crystalizer.c
+++ b/libavfilter/af_crystalizer.c
@@ -36,7 +36,7 @@ typedef struct CrystalizerContext {
#define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
static const AVOption crystalizer_options[] = {
- { "i", "set intensity", OFFSET(mult), AV_OPT_TYPE_FLOAT, {.dbl=2.0}, 0, 10, A },
+ { "i", "set intensity", OFFSET(mult), AV_OPT_TYPE_FLOAT, {.dbl=2.0},-10, 10, A },
{ "c", "enable clipping", OFFSET(clip), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, A },
{ NULL }
};
@@ -91,7 +91,7 @@ static int filter_flt(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
const void **s = td->s;
const int nb_samples = td->nb_samples;
const int channels = td->channels;
- float mult = td->mult;
+ const float mult = td->mult;
const int clip = td->clip;
const int start = (channels * jobnr) / nb_jobs;
const int end = (channels * (jobnr+1)) / nb_jobs;
@@ -195,7 +195,7 @@ static int filter_dblp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
const void **s = td->s;
const int nb_samples = td->nb_samples;
const int channels = td->channels;
- double mult = td->mult;
+ const double mult = td->mult;
const int clip = td->clip;
const int start = (channels * jobnr) / nb_jobs;
const int end = (channels * (jobnr+1)) / nb_jobs;
@@ -220,16 +220,157 @@ static int filter_dblp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
return 0;
}
+static int ifilter_flt(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 div = -td->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) / div;
+ prv[c] = dst[c];
+ if (clip) {
+ dst[c] = av_clipf(dst[c], -1, 1);
+ }
+
+ dst += channels;
+ src += channels;
+ }
+ }
+
+ return 0;
+}
+
+static int ifilter_dbl(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 div = -td->mult + 1.f;
+ 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++) {
+ const double *src = s[0];
+ double *dst = d[0];
+
+ for (n = 0; n < nb_samples; n++) {
+ double current = src[c];
+
+ dst[c] = (current + prv[c] * mult) / div;
+ prv[c] = dst[c];
+ if (clip) {
+ dst[c] = av_clipd(dst[c], -1, 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 div = -td->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) / div;
+ prv[0] = dst[n];
+ if (clip) {
+ dst[n] = av_clipf(dst[n], -1, 1);
+ }
+ }
+ }
+
+ 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 div = -td->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 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) / div;
+ prv[0] = dst[n];
+ if (clip) {
+ dst[n] = av_clipd(dst[n], -1, 1);
+ }
+ }
+ }
+
+ return 0;
+}
+
static int config_input(AVFilterLink *inlink)
{
AVFilterContext *ctx = inlink->dst;
CrystalizerContext *s = ctx->priv;
switch (inlink->format) {
- case AV_SAMPLE_FMT_FLT: s->filter = filter_flt; break;
- case AV_SAMPLE_FMT_DBL: s->filter = filter_dbl; break;
- case AV_SAMPLE_FMT_FLTP: s->filter = filter_fltp; break;
- case AV_SAMPLE_FMT_DBLP: s->filter = filter_dblp; break;
+ case AV_SAMPLE_FMT_FLT: s->filter = s->mult >= 0.f ? filter_flt : ifilter_flt; break;
+ case AV_SAMPLE_FMT_DBL: s->filter = s->mult >= 0.f ? filter_dbl : ifilter_dbl; break;
+ case AV_SAMPLE_FMT_FLTP: s->filter = s->mult >= 0.f ? filter_fltp : ifilter_fltp; break;
+ case AV_SAMPLE_FMT_DBLP: s->filter = s->mult >= 0.f ? filter_dblp : ifilter_dblp; break;
}
return 0;
@@ -285,6 +426,18 @@ static av_cold void uninit(AVFilterContext *ctx)
av_frame_free(&s->prev);
}
+static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
+ char *res, int res_len, int flags)
+{
+ int ret;
+
+ ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
+ if (ret < 0)
+ return ret;
+
+ return config_input(ctx->inputs[0]);
+}
+
static const AVFilterPad inputs[] = {
{
.name = "default",
@@ -312,7 +465,7 @@ AVFilter ff_af_crystalizer = {
.uninit = uninit,
.inputs = inputs,
.outputs = outputs,
- .process_command = ff_filter_process_command,
+ .process_command = process_command,
.flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
AVFILTER_FLAG_SLICE_THREADS,
};