History

avfilter: add asisdr filter

Paul B Mahol committed 3 years ago

Commit e41d5221 parent 951def84 files · +72 −1Browse files

Unified · Split

4 files
  1. doc/filters.texi +7 −0
  2. libavfilter/Makefile +1 −0
  3. libavfilter/af_asdr.c +63 −1
  4. libavfilter/allfilters.c +1 −0
doc/filters.texi+7−0
@@ -3141,6 +3141,13 @@ audio, the data is treated as if all the planes were concatenated. · 3140 unmodified lines
3141A list of Adler-32 checksums for each data plane.3141A list of Adler-32 checksums for each data plane.
3142@end table3142@end table
3143 3143
3144@section asisdr
3145Measure Audio Scaled-Invariant Signal-to-Distortion Ratio.
3146
3147This filter takes two audio streams for input, and outputs first
3148audio stream.
3149Results are in dB per channel at end of either input.
3150
3144@section asoftclip3151@section asoftclip
3145Apply audio soft clipping.3152Apply audio soft clipping.
3146 3153
libavfilter/Makefile+1−0
@@ -102,6 +102,7 @@ OBJS-$(CONFIG_ASETRATE_FILTER) += af_asetrate.o · 101 unmodified lines
102OBJS-$(CONFIG_ASETTB_FILTER) += settb.o102OBJS-$(CONFIG_ASETTB_FILTER) += settb.o
103OBJS-$(CONFIG_ASHOWINFO_FILTER) += af_ashowinfo.o103OBJS-$(CONFIG_ASHOWINFO_FILTER) += af_ashowinfo.o
104OBJS-$(CONFIG_ASIDEDATA_FILTER) += f_sidedata.o104OBJS-$(CONFIG_ASIDEDATA_FILTER) += f_sidedata.o
105OBJS-$(CONFIG_ASISDR_FILTER) += af_asdr.o
105OBJS-$(CONFIG_ASOFTCLIP_FILTER) += af_asoftclip.o106OBJS-$(CONFIG_ASOFTCLIP_FILTER) += af_asoftclip.o
106OBJS-$(CONFIG_ASPECTRALSTATS_FILTER) += af_aspectralstats.o107OBJS-$(CONFIG_ASPECTRALSTATS_FILTER) += af_aspectralstats.o
107OBJS-$(CONFIG_ASPLIT_FILTER) += split.o108OBJS-$(CONFIG_ASPLIT_FILTER) += split.o
libavfilter/af_asdr.c+63−1
@@ -32,6 +32,7 @@ typedef struct AudioSDRContext { · 31 unmodified lines
32 uint64_t nb_samples;32 uint64_t nb_samples;
33 double max;33 double max;
34 double *sum_u;34 double *sum_u;
35 double *sum_v;
35 double *sum_uv;36 double *sum_uv;
36 37
37 AVFrame *cache[2];38 AVFrame *cache[2];
@@ -71,6 +72,41 @@ static int sdr_##name(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)\ · 33 unmodified lines
71SDR_FILTER(fltp, float)72SDR_FILTER(fltp, float)
72SDR_FILTER(dblp, double)73SDR_FILTER(dblp, double)
73 74
75#define SISDR_FILTER(name, type) \
76static int sisdr_##name(AVFilterContext *ctx, void *arg,int jobnr,int nb_jobs)\
77{ \
78 AudioSDRContext *s = ctx->priv; \
79 AVFrame *u = s->cache[0]; \
80 AVFrame *v = s->cache[1]; \
81 const int channels = u->ch_layout.nb_channels; \
82 const int start = (channels * jobnr) / nb_jobs; \
83 const int end = (channels * (jobnr+1)) / nb_jobs; \
84 const int nb_samples = u->nb_samples; \
85 \
86 for (int ch = start; ch < end; ch++) { \
87 const type *const us = (type *)u->extended_data[ch]; \
88 const type *const vs = (type *)v->extended_data[ch]; \
89 double sum_uv = 0.; \
90 double sum_u = 0.; \
91 double sum_v = 0.; \
92 \
93 for (int n = 0; n < nb_samples; n++) { \
94 sum_u += us[n] * us[n]; \
95 sum_v += vs[n] * vs[n]; \
96 sum_uv += us[n] * vs[n]; \
97 } \
98 \
99 s->sum_uv[ch] += sum_uv; \
100 s->sum_u[ch] += sum_u; \
101 s->sum_v[ch] += sum_v; \
102 } \
103 \
104 return 0; \
105}
106
107SISDR_FILTER(fltp, float)
108SISDR_FILTER(dblp, double)
109
74#define PSNR_FILTER(name, type) \110#define PSNR_FILTER(name, type) \
75static int psnr_##name(AVFilterContext *ctx, void *arg, int jobnr,int nb_jobs)\111static int psnr_##name(AVFilterContext *ctx, void *arg, int jobnr,int nb_jobs)\
76{ \112{ \
@@ -162,13 +198,16 @@ static int config_output(AVFilterLink *outlink) · 85 unmodified lines
162 198
163 if (!strcmp(ctx->filter->name, "asdr"))199 if (!strcmp(ctx->filter->name, "asdr"))
164 s->filter = inlink->format == AV_SAMPLE_FMT_FLTP ? sdr_fltp : sdr_dblp;200 s->filter = inlink->format == AV_SAMPLE_FMT_FLTP ? sdr_fltp : sdr_dblp;
201 else if (!strcmp(ctx->filter->name, "asisdr"))
202 s->filter = inlink->format == AV_SAMPLE_FMT_FLTP ? sisdr_fltp : sisdr_dblp;
165 else203 else
166 s->filter = inlink->format == AV_SAMPLE_FMT_FLTP ? psnr_fltp : psnr_dblp;204 s->filter = inlink->format == AV_SAMPLE_FMT_FLTP ? psnr_fltp : psnr_dblp;
167 s->max = inlink->format == AV_SAMPLE_FMT_FLTP ? FLT_MAX : DBL_MAX;205 s->max = inlink->format == AV_SAMPLE_FMT_FLTP ? FLT_MAX : DBL_MAX;
168 206
169 s->sum_u = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->sum_u));207 s->sum_u = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->sum_u));
208 s->sum_v = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->sum_v));
170 s->sum_uv = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->sum_uv));209 s->sum_uv = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->sum_uv));
171 if (!s->sum_u || !s->sum_uv)210 if (!s->sum_u || !s->sum_uv || !s->sum_v)
172 return AVERROR(ENOMEM);211 return AVERROR(ENOMEM);
173 212
174 return 0;213 return 0;
@@ -181,6 +220,13 @@ static av_cold void uninit(AVFilterContext *ctx) · 6 unmodified lines
181 if (!strcmp(ctx->filter->name, "asdr")) {220 if (!strcmp(ctx->filter->name, "asdr")) {
182 for (int ch = 0; ch < s->channels; ch++)221 for (int ch = 0; ch < s->channels; ch++)
183 av_log(ctx, AV_LOG_INFO, "SDR ch%d: %g dB\n", ch, 20. * log10(s->sum_u[ch] / s->sum_uv[ch]));222 av_log(ctx, AV_LOG_INFO, "SDR ch%d: %g dB\n", ch, 20. * log10(s->sum_u[ch] / s->sum_uv[ch]));
223 } else if (!strcmp(ctx->filter->name, "asisdr")) {
224 for (int ch = 0; ch < s->channels; ch++) {
225 double scale = s->sum_uv[ch] / s->sum_v[ch];
226 double sisdr = s->sum_u[ch] / (s->sum_u[ch] + scale*scale*s->sum_v[ch] - 2.0*scale*s->sum_uv[ch]);
227
228 av_log(ctx, AV_LOG_INFO, "SI-SDR ch%d: %g dB\n", ch, 10. * log10(sisdr));
229 }
184 } else {230 } else {
185 for (int ch = 0; ch < s->channels; ch++) {231 for (int ch = 0; ch < s->channels; ch++) {
186 double psnr = s->sum_uv[ch] > 0.0 ? 2.0 * log(s->max) - log(s->nb_samples / s->sum_uv[ch]) : INFINITY;232 double psnr = s->sum_uv[ch] > 0.0 ? 2.0 * log(s->max) - log(s->nb_samples / s->sum_uv[ch]) : INFINITY;
@@ -193,6 +239,7 @@ static av_cold void uninit(AVFilterContext *ctx) · 6 unmodified lines
193 av_frame_free(&s->cache[1]);239 av_frame_free(&s->cache[1]);
194 240
195 av_freep(&s->sum_u);241 av_freep(&s->sum_u);
242 av_freep(&s->sum_v);
196 av_freep(&s->sum_uv);243 av_freep(&s->sum_uv);
197}244}
198 245
@@ -244,3 +291,18 @@ const AVFilter ff_af_apsnr = { · 45 unmodified lines
244 FILTER_SAMPLEFMTS(AV_SAMPLE_FMT_FLTP,291 FILTER_SAMPLEFMTS(AV_SAMPLE_FMT_FLTP,
245 AV_SAMPLE_FMT_DBLP),292 AV_SAMPLE_FMT_DBLP),
246};293};
294
295const AVFilter ff_af_asisdr = {
296 .name = "asisdr",
297 .description = NULL_IF_CONFIG_SMALL("Measure Audio Scale-Invariant Signal-to-Distortion Ratio."),
298 .priv_size = sizeof(AudioSDRContext),
299 .activate = activate,
300 .uninit = uninit,
301 .flags = AVFILTER_FLAG_METADATA_ONLY |
302 AVFILTER_FLAG_SLICE_THREADS |
303 AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
304 FILTER_INPUTS(inputs),
305 FILTER_OUTPUTS(outputs),
306 FILTER_SAMPLEFMTS(AV_SAMPLE_FMT_FLTP,
307 AV_SAMPLE_FMT_DBLP),
308};
libavfilter/allfilters.c+1−0
@@ -88,6 +88,7 @@ extern const AVFilter ff_af_asetrate; · 87 unmodified lines
88extern const AVFilter ff_af_asettb;88extern const AVFilter ff_af_asettb;
89extern const AVFilter ff_af_ashowinfo;89extern const AVFilter ff_af_ashowinfo;
90extern const AVFilter ff_af_asidedata;90extern const AVFilter ff_af_asidedata;
91extern const AVFilter ff_af_asisdr;
91extern const AVFilter ff_af_asoftclip;92extern const AVFilter ff_af_asoftclip;
92extern const AVFilter ff_af_aspectralstats;93extern const AVFilter ff_af_aspectralstats;
93extern const AVFilter ff_af_asplit;94extern const AVFilter ff_af_asplit;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t