* [FFmpeg-devel] [PATCH] apsnr and asisdr filter
@ 2023-08-13 3:14 Paul B Mahol
2023-08-13 22:15 ` Paul B Mahol
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Paul B Mahol @ 2023-08-13 3:14 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1: Type: text/plain, Size: 10 bytes --]
Attached.
[-- Attachment #2: 0003-avfilter-af_asdr-use-single-structure-for-sums.patch --]
[-- Type: text/x-patch, Size: 7906 bytes --]
From ad9def7fad58a75450176413564543a16965d165 Mon Sep 17 00:00:00 2001
From: Paul B Mahol <onemda@gmail.com>
Date: Sun, 13 Aug 2023 05:03:00 +0200
Subject: [PATCH 3/3] avfilter/af_asdr: use single structure for sums
Signed-off-by: Paul B Mahol <onemda@gmail.com>
---
libavfilter/af_asdr.c | 44 +++++++++++++++++++++++--------------------
1 file changed, 24 insertions(+), 20 deletions(-)
diff --git a/libavfilter/af_asdr.c b/libavfilter/af_asdr.c
index 53069427bf..dbbb7e3419 100644
--- a/libavfilter/af_asdr.c
+++ b/libavfilter/af_asdr.c
@@ -27,13 +27,18 @@
#include "filters.h"
#include "internal.h"
+typedef struct ChanStats {
+ double u;
+ double v;
+ double uv;
+} ChanStats;
+
typedef struct AudioSDRContext {
int channels;
uint64_t nb_samples;
double max;
- double *sum_u;
- double *sum_v;
- double *sum_uv;
+
+ ChanStats *chs;
AVFrame *cache[2];
@@ -52,6 +57,7 @@ static int sdr_##name(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)\
const int nb_samples = u->nb_samples; \
\
for (int ch = start; ch < end; ch++) { \
+ ChanStats *chs = &s->chs[ch]; \
const type *const us = (type *)u->extended_data[ch]; \
const type *const vs = (type *)v->extended_data[ch]; \
double sum_uv = 0.; \
@@ -62,8 +68,8 @@ static int sdr_##name(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)\
sum_uv += (us[n] - vs[n]) * (us[n] - vs[n]); \
} \
\
- s->sum_uv[ch] += sum_uv; \
- s->sum_u[ch] += sum_u; \
+ chs->uv += sum_uv; \
+ chs->u += sum_u; \
} \
\
return 0; \
@@ -84,6 +90,7 @@ static int sisdr_##name(AVFilterContext *ctx, void *arg,int jobnr,int nb_jobs)\
const int nb_samples = u->nb_samples; \
\
for (int ch = start; ch < end; ch++) { \
+ ChanStats *chs = &s->chs[ch]; \
const type *const us = (type *)u->extended_data[ch]; \
const type *const vs = (type *)v->extended_data[ch]; \
double sum_uv = 0.; \
@@ -96,9 +103,9 @@ static int sisdr_##name(AVFilterContext *ctx, void *arg,int jobnr,int nb_jobs)\
sum_uv += us[n] * vs[n]; \
} \
\
- s->sum_uv[ch] += sum_uv; \
- s->sum_u[ch] += sum_u; \
- s->sum_v[ch] += sum_v; \
+ chs->uv += sum_uv; \
+ chs->u += sum_u; \
+ chs->v += sum_v; \
} \
\
return 0; \
@@ -119,6 +126,7 @@ static int psnr_##name(AVFilterContext *ctx, void *arg, int jobnr,int nb_jobs)\
const int nb_samples = u->nb_samples; \
\
for (int ch = start; ch < end; ch++) { \
+ ChanStats *chs = &s->chs[ch]; \
const type *const us = (type *)u->extended_data[ch]; \
const type *const vs = (type *)v->extended_data[ch]; \
double sum_uv = 0.; \
@@ -126,7 +134,7 @@ static int psnr_##name(AVFilterContext *ctx, void *arg, int jobnr,int nb_jobs)\
for (int n = 0; n < nb_samples; n++) \
sum_uv += (us[n] - vs[n]) * (us[n] - vs[n]); \
\
- s->sum_uv[ch] += sum_uv; \
+ chs->uv += sum_uv; \
} \
\
return 0; \
@@ -204,10 +212,8 @@ static int config_output(AVFilterLink *outlink)
s->filter = inlink->format == AV_SAMPLE_FMT_FLTP ? psnr_fltp : psnr_dblp;
s->max = inlink->format == AV_SAMPLE_FMT_FLTP ? FLT_MAX : DBL_MAX;
- s->sum_u = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->sum_u));
- s->sum_v = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->sum_v));
- s->sum_uv = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->sum_uv));
- if (!s->sum_u || !s->sum_uv || !s->sum_v)
+ s->chs = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->chs));
+ if (!s->chs)
return AVERROR(ENOMEM);
return 0;
@@ -219,17 +225,17 @@ static av_cold void uninit(AVFilterContext *ctx)
if (!strcmp(ctx->filter->name, "asdr")) {
for (int ch = 0; ch < s->channels; ch++)
- av_log(ctx, AV_LOG_INFO, "SDR ch%d: %g dB\n", ch, 20. * log10(s->sum_u[ch] / s->sum_uv[ch]));
+ av_log(ctx, AV_LOG_INFO, "SDR ch%d: %g dB\n", ch, 20. * log10(s->chs[ch].u / s->chs[ch].uv));
} else if (!strcmp(ctx->filter->name, "asisdr")) {
for (int ch = 0; ch < s->channels; ch++) {
- double scale = s->sum_uv[ch] / s->sum_v[ch];
- double sisdr = s->sum_u[ch] / (s->sum_u[ch] + scale*scale*s->sum_v[ch] - 2.0*scale*s->sum_uv[ch]);
+ double scale = s->chs[ch].uv / s->chs[ch].v;
+ double sisdr = s->chs[ch].u / fmax(0., s->chs[ch].u + scale*scale*s->chs[ch].v - 2.0*scale*s->chs[ch].uv);
av_log(ctx, AV_LOG_INFO, "SI-SDR ch%d: %g dB\n", ch, 10. * log10(sisdr));
}
} else {
for (int ch = 0; ch < s->channels; ch++) {
- double psnr = s->sum_uv[ch] > 0.0 ? 2.0 * log(s->max) - log(s->nb_samples / s->sum_uv[ch]) : INFINITY;
+ double psnr = s->chs[ch].uv > 0.0 ? 2.0 * log(s->max) - log(s->nb_samples / s->chs[ch].uv) : INFINITY;
av_log(ctx, AV_LOG_INFO, "PSNR ch%d: %g dB\n", ch, psnr);
}
@@ -238,9 +244,7 @@ static av_cold void uninit(AVFilterContext *ctx)
av_frame_free(&s->cache[0]);
av_frame_free(&s->cache[1]);
- av_freep(&s->sum_u);
- av_freep(&s->sum_v);
- av_freep(&s->sum_uv);
+ av_freep(&s->chs);
}
static const AVFilterPad inputs[] = {
--
2.39.1
[-- Attachment #3: 0002-avfilter-add-asisdr-filter.patch --]
[-- Type: text/x-patch, Size: 8056 bytes --]
From dfb20b0f4d08428a43b38185776baf6819fc4336 Mon Sep 17 00:00:00 2001
From: Paul B Mahol <onemda@gmail.com>
Date: Sun, 13 Aug 2023 04:19:08 +0200
Subject: [PATCH 2/3] avfilter: add asisdr filter
Signed-off-by: Paul B Mahol <onemda@gmail.com>
---
doc/filters.texi | 7 +++++
libavfilter/Makefile | 1 +
libavfilter/af_asdr.c | 64 +++++++++++++++++++++++++++++++++++++++-
libavfilter/allfilters.c | 1 +
4 files changed, 72 insertions(+), 1 deletion(-)
diff --git a/doc/filters.texi b/doc/filters.texi
index 1025917c63..159764bcb6 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -3197,6 +3197,13 @@ audio, the data is treated as if all the planes were concatenated.
A list of Adler-32 checksums for each data plane.
@end table
+@section asisdr
+Measure Audio Scaled-Invariant Signal-to-Distortion Ratio.
+
+This filter takes two audio streams for input, and outputs first
+audio stream.
+Results are in dB per channel at end of either input.
+
@section asoftclip
Apply audio soft clipping.
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 90c30e3388..ba07f4ab1e 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -103,6 +103,7 @@ OBJS-$(CONFIG_ASETRATE_FILTER) += af_asetrate.o
OBJS-$(CONFIG_ASETTB_FILTER) += settb.o
OBJS-$(CONFIG_ASHOWINFO_FILTER) += af_ashowinfo.o
OBJS-$(CONFIG_ASIDEDATA_FILTER) += f_sidedata.o
+OBJS-$(CONFIG_ASISDR_FILTER) += af_asdr.o
OBJS-$(CONFIG_ASOFTCLIP_FILTER) += af_asoftclip.o
OBJS-$(CONFIG_ASPECTRALSTATS_FILTER) += af_aspectralstats.o
OBJS-$(CONFIG_ASPLIT_FILTER) += split.o
diff --git a/libavfilter/af_asdr.c b/libavfilter/af_asdr.c
index b0401804f6..53069427bf 100644
--- a/libavfilter/af_asdr.c
+++ b/libavfilter/af_asdr.c
@@ -32,6 +32,7 @@ typedef struct AudioSDRContext {
uint64_t nb_samples;
double max;
double *sum_u;
+ double *sum_v;
double *sum_uv;
AVFrame *cache[2];
@@ -71,6 +72,41 @@ static int sdr_##name(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)\
SDR_FILTER(fltp, float)
SDR_FILTER(dblp, double)
+#define SISDR_FILTER(name, type) \
+static int sisdr_##name(AVFilterContext *ctx, void *arg,int jobnr,int nb_jobs)\
+{ \
+ AudioSDRContext *s = ctx->priv; \
+ AVFrame *u = s->cache[0]; \
+ AVFrame *v = s->cache[1]; \
+ const int channels = u->ch_layout.nb_channels; \
+ const int start = (channels * jobnr) / nb_jobs; \
+ const int end = (channels * (jobnr+1)) / nb_jobs; \
+ const int nb_samples = u->nb_samples; \
+ \
+ for (int ch = start; ch < end; ch++) { \
+ const type *const us = (type *)u->extended_data[ch]; \
+ const type *const vs = (type *)v->extended_data[ch]; \
+ double sum_uv = 0.; \
+ double sum_u = 0.; \
+ double sum_v = 0.; \
+ \
+ for (int n = 0; n < nb_samples; n++) { \
+ sum_u += us[n] * us[n]; \
+ sum_v += vs[n] * vs[n]; \
+ sum_uv += us[n] * vs[n]; \
+ } \
+ \
+ s->sum_uv[ch] += sum_uv; \
+ s->sum_u[ch] += sum_u; \
+ s->sum_v[ch] += sum_v; \
+ } \
+ \
+ return 0; \
+}
+
+SISDR_FILTER(fltp, float)
+SISDR_FILTER(dblp, double)
+
#define PSNR_FILTER(name, type) \
static int psnr_##name(AVFilterContext *ctx, void *arg, int jobnr,int nb_jobs)\
{ \
@@ -162,13 +198,16 @@ static int config_output(AVFilterLink *outlink)
if (!strcmp(ctx->filter->name, "asdr"))
s->filter = inlink->format == AV_SAMPLE_FMT_FLTP ? sdr_fltp : sdr_dblp;
+ else if (!strcmp(ctx->filter->name, "asisdr"))
+ s->filter = inlink->format == AV_SAMPLE_FMT_FLTP ? sisdr_fltp : sisdr_dblp;
else
s->filter = inlink->format == AV_SAMPLE_FMT_FLTP ? psnr_fltp : psnr_dblp;
s->max = inlink->format == AV_SAMPLE_FMT_FLTP ? FLT_MAX : DBL_MAX;
s->sum_u = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->sum_u));
+ s->sum_v = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->sum_v));
s->sum_uv = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->sum_uv));
- if (!s->sum_u || !s->sum_uv)
+ if (!s->sum_u || !s->sum_uv || !s->sum_v)
return AVERROR(ENOMEM);
return 0;
@@ -181,6 +220,13 @@ static av_cold void uninit(AVFilterContext *ctx)
if (!strcmp(ctx->filter->name, "asdr")) {
for (int ch = 0; ch < s->channels; ch++)
av_log(ctx, AV_LOG_INFO, "SDR ch%d: %g dB\n", ch, 20. * log10(s->sum_u[ch] / s->sum_uv[ch]));
+ } else if (!strcmp(ctx->filter->name, "asisdr")) {
+ for (int ch = 0; ch < s->channels; ch++) {
+ double scale = s->sum_uv[ch] / s->sum_v[ch];
+ double sisdr = s->sum_u[ch] / (s->sum_u[ch] + scale*scale*s->sum_v[ch] - 2.0*scale*s->sum_uv[ch]);
+
+ av_log(ctx, AV_LOG_INFO, "SI-SDR ch%d: %g dB\n", ch, 10. * log10(sisdr));
+ }
} else {
for (int ch = 0; ch < s->channels; ch++) {
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)
av_frame_free(&s->cache[1]);
av_freep(&s->sum_u);
+ av_freep(&s->sum_v);
av_freep(&s->sum_uv);
}
@@ -244,3 +291,18 @@ const AVFilter ff_af_apsnr = {
FILTER_SAMPLEFMTS(AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_DBLP),
};
+
+const AVFilter ff_af_asisdr = {
+ .name = "asisdr",
+ .description = NULL_IF_CONFIG_SMALL("Measure Audio Scale-Invariant Signal-to-Distortion Ratio."),
+ .priv_size = sizeof(AudioSDRContext),
+ .activate = activate,
+ .uninit = uninit,
+ .flags = AVFILTER_FLAG_METADATA_ONLY |
+ AVFILTER_FLAG_SLICE_THREADS |
+ AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
+ FILTER_INPUTS(inputs),
+ FILTER_OUTPUTS(outputs),
+ FILTER_SAMPLEFMTS(AV_SAMPLE_FMT_FLTP,
+ AV_SAMPLE_FMT_DBLP),
+};
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 949c5d4992..2cda06f251 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -89,6 +89,7 @@ extern const AVFilter ff_af_asetrate;
extern const AVFilter ff_af_asettb;
extern const AVFilter ff_af_ashowinfo;
extern const AVFilter ff_af_asidedata;
+extern const AVFilter ff_af_asisdr;
extern const AVFilter ff_af_asoftclip;
extern const AVFilter ff_af_aspectralstats;
extern const AVFilter ff_af_asplit;
--
2.39.1
[-- Attachment #4: 0001-avfilter-add-apsnr-filter.patch --]
[-- Type: text/x-patch, Size: 7273 bytes --]
From 8b457c83855ccc292a53be2bd716bf445d37d7e0 Mon Sep 17 00:00:00 2001
From: Paul B Mahol <onemda@gmail.com>
Date: Sun, 13 Aug 2023 02:57:57 +0200
Subject: [PATCH 1/3] avfilter: add apsnr filter
Signed-off-by: Paul B Mahol <onemda@gmail.com>
---
doc/filters.texi | 7 +++++
libavfilter/Makefile | 1 +
libavfilter/af_asdr.c | 67 ++++++++++++++++++++++++++++++++++++++--
libavfilter/allfilters.c | 1 +
4 files changed, 73 insertions(+), 3 deletions(-)
diff --git a/doc/filters.texi b/doc/filters.texi
index e041adc40f..1025917c63 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -2892,6 +2892,13 @@ Default value is 8.
This filter supports the all above options as @ref{commands}.
+@section apsnr
+Measure Audio Peak Signal-to-Noise Ratio.
+
+This filter takes two audio streams for input, and outputs first
+audio stream.
+Results are in dB per channel at end of either input.
+
@section apsyclip
Apply Psychoacoustic clipper to input audio stream.
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index b26a85a7d2..90c30e3388 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -85,6 +85,7 @@ OBJS-$(CONFIG_APAD_FILTER) += af_apad.o
OBJS-$(CONFIG_APERMS_FILTER) += f_perms.o
OBJS-$(CONFIG_APHASER_FILTER) += af_aphaser.o generate_wave_table.o
OBJS-$(CONFIG_APHASESHIFT_FILTER) += af_afreqshift.o
+OBJS-$(CONFIG_APSNR_FILTER) += af_asdr.o
OBJS-$(CONFIG_APSYCLIP_FILTER) += af_apsyclip.o
OBJS-$(CONFIG_APULSATOR_FILTER) += af_apulsator.o
OBJS-$(CONFIG_AREALTIME_FILTER) += f_realtime.o
diff --git a/libavfilter/af_asdr.c b/libavfilter/af_asdr.c
index 7d778b7f6b..b0401804f6 100644
--- a/libavfilter/af_asdr.c
+++ b/libavfilter/af_asdr.c
@@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <float.h>
+
#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
@@ -27,6 +29,8 @@
typedef struct AudioSDRContext {
int channels;
+ uint64_t nb_samples;
+ double max;
double *sum_u;
double *sum_uv;
@@ -67,6 +71,34 @@ static int sdr_##name(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)\
SDR_FILTER(fltp, float)
SDR_FILTER(dblp, double)
+#define PSNR_FILTER(name, type) \
+static int psnr_##name(AVFilterContext *ctx, void *arg, int jobnr,int nb_jobs)\
+{ \
+ AudioSDRContext *s = ctx->priv; \
+ AVFrame *u = s->cache[0]; \
+ AVFrame *v = s->cache[1]; \
+ const int channels = u->ch_layout.nb_channels; \
+ const int start = (channels * jobnr) / nb_jobs; \
+ const int end = (channels * (jobnr+1)) / nb_jobs; \
+ const int nb_samples = u->nb_samples; \
+ \
+ for (int ch = start; ch < end; ch++) { \
+ const type *const us = (type *)u->extended_data[ch]; \
+ const type *const vs = (type *)v->extended_data[ch]; \
+ double sum_uv = 0.; \
+ \
+ for (int n = 0; n < nb_samples; n++) \
+ sum_uv += (us[n] - vs[n]) * (us[n] - vs[n]); \
+ \
+ s->sum_uv[ch] += sum_uv; \
+ } \
+ \
+ return 0; \
+}
+
+PSNR_FILTER(fltp, float)
+PSNR_FILTER(dblp, double)
+
static int activate(AVFilterContext *ctx)
{
AudioSDRContext *s = ctx->priv;
@@ -97,6 +129,7 @@ static int activate(AVFilterContext *ctx)
out = s->cache[0];
s->cache[0] = NULL;
+ s->nb_samples += available;
return ff_filter_frame(outlink, out);
}
@@ -126,7 +159,12 @@ static int config_output(AVFilterLink *outlink)
AudioSDRContext *s = ctx->priv;
s->channels = inlink->ch_layout.nb_channels;
- s->filter = inlink->format == AV_SAMPLE_FMT_FLTP ? sdr_fltp : sdr_dblp;
+
+ if (!strcmp(ctx->filter->name, "asdr"))
+ s->filter = inlink->format == AV_SAMPLE_FMT_FLTP ? sdr_fltp : sdr_dblp;
+ else
+ s->filter = inlink->format == AV_SAMPLE_FMT_FLTP ? psnr_fltp : psnr_dblp;
+ s->max = inlink->format == AV_SAMPLE_FMT_FLTP ? FLT_MAX : DBL_MAX;
s->sum_u = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->sum_u));
s->sum_uv = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->sum_uv));
@@ -140,8 +178,16 @@ static av_cold void uninit(AVFilterContext *ctx)
{
AudioSDRContext *s = ctx->priv;
- for (int ch = 0; ch < s->channels; ch++)
- av_log(ctx, AV_LOG_INFO, "SDR ch%d: %g dB\n", ch, 20. * log10(s->sum_u[ch] / s->sum_uv[ch]));
+ if (!strcmp(ctx->filter->name, "asdr")) {
+ for (int ch = 0; ch < s->channels; ch++)
+ av_log(ctx, AV_LOG_INFO, "SDR ch%d: %g dB\n", ch, 20. * log10(s->sum_u[ch] / s->sum_uv[ch]));
+ } else {
+ for (int ch = 0; ch < s->channels; ch++) {
+ double psnr = s->sum_uv[ch] > 0.0 ? 2.0 * log(s->max) - log(s->nb_samples / s->sum_uv[ch]) : INFINITY;
+
+ av_log(ctx, AV_LOG_INFO, "PSNR ch%d: %g dB\n", ch, psnr);
+ }
+ }
av_frame_free(&s->cache[0]);
av_frame_free(&s->cache[1]);
@@ -183,3 +229,18 @@ const AVFilter ff_af_asdr = {
FILTER_SAMPLEFMTS(AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_DBLP),
};
+
+const AVFilter ff_af_apsnr = {
+ .name = "apsnr",
+ .description = NULL_IF_CONFIG_SMALL("Measure Audio Peak Signal-to-Noise Ratio."),
+ .priv_size = sizeof(AudioSDRContext),
+ .activate = activate,
+ .uninit = uninit,
+ .flags = AVFILTER_FLAG_METADATA_ONLY |
+ AVFILTER_FLAG_SLICE_THREADS |
+ AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
+ FILTER_INPUTS(inputs),
+ FILTER_OUTPUTS(outputs),
+ FILTER_SAMPLEFMTS(AV_SAMPLE_FMT_FLTP,
+ AV_SAMPLE_FMT_DBLP),
+};
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 286e601799..949c5d4992 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -71,6 +71,7 @@ extern const AVFilter ff_af_apad;
extern const AVFilter ff_af_aperms;
extern const AVFilter ff_af_aphaser;
extern const AVFilter ff_af_aphaseshift;
+extern const AVFilter ff_af_apsnr;
extern const AVFilter ff_af_apsyclip;
extern const AVFilter ff_af_apulsator;
extern const AVFilter ff_af_arealtime;
--
2.39.1
[-- Attachment #5: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [FFmpeg-devel] [PATCH] apsnr and asisdr filter
2023-08-13 3:14 [FFmpeg-devel] [PATCH] apsnr and asisdr filter Paul B Mahol
@ 2023-08-13 22:15 ` Paul B Mahol
2023-08-14 8:51 ` Michael Niedermayer
2023-08-14 8:56 ` Michael Niedermayer
2 siblings, 0 replies; 4+ messages in thread
From: Paul B Mahol @ 2023-08-13 22:15 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Will apply soon.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [FFmpeg-devel] [PATCH] apsnr and asisdr filter
2023-08-13 3:14 [FFmpeg-devel] [PATCH] apsnr and asisdr filter Paul B Mahol
2023-08-13 22:15 ` Paul B Mahol
@ 2023-08-14 8:51 ` Michael Niedermayer
2023-08-14 8:56 ` Michael Niedermayer
2 siblings, 0 replies; 4+ messages in thread
From: Michael Niedermayer @ 2023-08-14 8:51 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1.1: Type: text/plain, Size: 2395 bytes --]
On Sun, Aug 13, 2023 at 05:14:48AM +0200, Paul B Mahol wrote:
> Attached.
> af_asdr.c | 44 ++++++++++++++++++++++++--------------------
> 1 file changed, 24 insertions(+), 20 deletions(-)
> f0f248ba7e893a63a684b92a6d82ab246fc1995c 0003-avfilter-af_asdr-use-single-structure-for-sums.patch
> From ad9def7fad58a75450176413564543a16965d165 Mon Sep 17 00:00:00 2001
> From: Paul B Mahol <onemda@gmail.com>
> Date: Sun, 13 Aug 2023 05:03:00 +0200
> Subject: [PATCH 3/3] avfilter/af_asdr: use single structure for sums
>
> Signed-off-by: Paul B Mahol <onemda@gmail.com>
> ---
> libavfilter/af_asdr.c | 44 +++++++++++++++++++++++--------------------
> 1 file changed, 24 insertions(+), 20 deletions(-)
[...]
> doc/filters.texi | 7 +++++
> libavfilter/Makefile | 1
> libavfilter/af_asdr.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++-
> libavfilter/allfilters.c | 1
> 4 files changed, 72 insertions(+), 1 deletion(-)
> 8ed085a8902fa86f0a99838bbd6c4b2645e187d6 0002-avfilter-add-asisdr-filter.patch
> From dfb20b0f4d08428a43b38185776baf6819fc4336 Mon Sep 17 00:00:00 2001
> From: Paul B Mahol <onemda@gmail.com>
> Date: Sun, 13 Aug 2023 04:19:08 +0200
> Subject: [PATCH 2/3] avfilter: add asisdr filter
>
> Signed-off-by: Paul B Mahol <onemda@gmail.com>
> ---
> doc/filters.texi | 7 +++++
> libavfilter/Makefile | 1 +
> libavfilter/af_asdr.c | 64 +++++++++++++++++++++++++++++++++++++++-
> libavfilter/allfilters.c | 1 +
> 4 files changed, 72 insertions(+), 1 deletion(-)
[...]
> doc/filters.texi | 7 ++++
> libavfilter/Makefile | 1
> libavfilter/af_asdr.c | 67 ++++++++++++++++++++++++++++++++++++++++++++---
> libavfilter/allfilters.c | 1
> 4 files changed, 73 insertions(+), 3 deletions(-)
> 85562ee579f2ffd79d14e0d2d3d7938865dcaae3 0001-avfilter-add-apsnr-filter.patch
> From 8b457c83855ccc292a53be2bd716bf445d37d7e0 Mon Sep 17 00:00:00 2001
> From: Paul B Mahol <onemda@gmail.com>
> Date: Sun, 13 Aug 2023 02:57:57 +0200
> Subject: [PATCH 1/3] avfilter: add apsnr filter
Missing tests, please add fate tests
Thank you
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
When you are offended at any man's fault, turn to yourself and study your
own failings. Then you will forget your anger. -- Epictetus
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
[-- Attachment #2: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [FFmpeg-devel] [PATCH] apsnr and asisdr filter
2023-08-13 3:14 [FFmpeg-devel] [PATCH] apsnr and asisdr filter Paul B Mahol
2023-08-13 22:15 ` Paul B Mahol
2023-08-14 8:51 ` Michael Niedermayer
@ 2023-08-14 8:56 ` Michael Niedermayer
2 siblings, 0 replies; 4+ messages in thread
From: Michael Niedermayer @ 2023-08-14 8:56 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1.1: Type: text/plain, Size: 16629 bytes --]
On Sun, Aug 13, 2023 at 05:14:48AM +0200, Paul B Mahol wrote:
> Attached.
> af_asdr.c | 44 ++++++++++++++++++++++++--------------------
> 1 file changed, 24 insertions(+), 20 deletions(-)
> f0f248ba7e893a63a684b92a6d82ab246fc1995c 0003-avfilter-af_asdr-use-single-structure-for-sums.patch
> From ad9def7fad58a75450176413564543a16965d165 Mon Sep 17 00:00:00 2001
> From: Paul B Mahol <onemda@gmail.com>
> Date: Sun, 13 Aug 2023 05:03:00 +0200
> Subject: [PATCH 3/3] avfilter/af_asdr: use single structure for sums
>
> Signed-off-by: Paul B Mahol <onemda@gmail.com>
> ---
> libavfilter/af_asdr.c | 44 +++++++++++++++++++++++--------------------
> 1 file changed, 24 insertions(+), 20 deletions(-)
>
> diff --git a/libavfilter/af_asdr.c b/libavfilter/af_asdr.c
> index 53069427bf..dbbb7e3419 100644
> --- a/libavfilter/af_asdr.c
> +++ b/libavfilter/af_asdr.c
> @@ -27,13 +27,18 @@
> #include "filters.h"
> #include "internal.h"
>
> +typedef struct ChanStats {
> + double u;
> + double v;
> + double uv;
> +} ChanStats;
> +
> typedef struct AudioSDRContext {
> int channels;
> uint64_t nb_samples;
> double max;
> - double *sum_u;
> - double *sum_v;
> - double *sum_uv;
> +
> + ChanStats *chs;
>
> AVFrame *cache[2];
>
> @@ -52,6 +57,7 @@ static int sdr_##name(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)\
> const int nb_samples = u->nb_samples; \
> \
> for (int ch = start; ch < end; ch++) { \
> + ChanStats *chs = &s->chs[ch]; \
> const type *const us = (type *)u->extended_data[ch]; \
> const type *const vs = (type *)v->extended_data[ch]; \
> double sum_uv = 0.; \
> @@ -62,8 +68,8 @@ static int sdr_##name(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)\
> sum_uv += (us[n] - vs[n]) * (us[n] - vs[n]); \
> } \
> \
> - s->sum_uv[ch] += sum_uv; \
> - s->sum_u[ch] += sum_u; \
> + chs->uv += sum_uv; \
> + chs->u += sum_u; \
> } \
> \
> return 0; \
> @@ -84,6 +90,7 @@ static int sisdr_##name(AVFilterContext *ctx, void *arg,int jobnr,int nb_jobs)\
> const int nb_samples = u->nb_samples; \
> \
> for (int ch = start; ch < end; ch++) { \
> + ChanStats *chs = &s->chs[ch]; \
> const type *const us = (type *)u->extended_data[ch]; \
> const type *const vs = (type *)v->extended_data[ch]; \
> double sum_uv = 0.; \
> @@ -96,9 +103,9 @@ static int sisdr_##name(AVFilterContext *ctx, void *arg,int jobnr,int nb_jobs)\
> sum_uv += us[n] * vs[n]; \
> } \
> \
> - s->sum_uv[ch] += sum_uv; \
> - s->sum_u[ch] += sum_u; \
> - s->sum_v[ch] += sum_v; \
> + chs->uv += sum_uv; \
> + chs->u += sum_u; \
> + chs->v += sum_v; \
> } \
> \
> return 0; \
> @@ -119,6 +126,7 @@ static int psnr_##name(AVFilterContext *ctx, void *arg, int jobnr,int nb_jobs)\
> const int nb_samples = u->nb_samples; \
> \
> for (int ch = start; ch < end; ch++) { \
> + ChanStats *chs = &s->chs[ch]; \
> const type *const us = (type *)u->extended_data[ch]; \
> const type *const vs = (type *)v->extended_data[ch]; \
> double sum_uv = 0.; \
> @@ -126,7 +134,7 @@ static int psnr_##name(AVFilterContext *ctx, void *arg, int jobnr,int nb_jobs)\
> for (int n = 0; n < nb_samples; n++) \
> sum_uv += (us[n] - vs[n]) * (us[n] - vs[n]); \
> \
> - s->sum_uv[ch] += sum_uv; \
> + chs->uv += sum_uv; \
> } \
> \
> return 0; \
> @@ -204,10 +212,8 @@ static int config_output(AVFilterLink *outlink)
> s->filter = inlink->format == AV_SAMPLE_FMT_FLTP ? psnr_fltp : psnr_dblp;
> s->max = inlink->format == AV_SAMPLE_FMT_FLTP ? FLT_MAX : DBL_MAX;
>
> - s->sum_u = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->sum_u));
> - s->sum_v = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->sum_v));
> - s->sum_uv = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->sum_uv));
> - if (!s->sum_u || !s->sum_uv || !s->sum_v)
> + s->chs = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->chs));
> + if (!s->chs)
> return AVERROR(ENOMEM);
>
> return 0;
> @@ -219,17 +225,17 @@ static av_cold void uninit(AVFilterContext *ctx)
>
> if (!strcmp(ctx->filter->name, "asdr")) {
> for (int ch = 0; ch < s->channels; ch++)
> - av_log(ctx, AV_LOG_INFO, "SDR ch%d: %g dB\n", ch, 20. * log10(s->sum_u[ch] / s->sum_uv[ch]));
> + av_log(ctx, AV_LOG_INFO, "SDR ch%d: %g dB\n", ch, 20. * log10(s->chs[ch].u / s->chs[ch].uv));
> } else if (!strcmp(ctx->filter->name, "asisdr")) {
> for (int ch = 0; ch < s->channels; ch++) {
> - double scale = s->sum_uv[ch] / s->sum_v[ch];
> - double sisdr = s->sum_u[ch] / (s->sum_u[ch] + scale*scale*s->sum_v[ch] - 2.0*scale*s->sum_uv[ch]);
> + double scale = s->chs[ch].uv / s->chs[ch].v;
> + double sisdr = s->chs[ch].u / fmax(0., s->chs[ch].u + scale*scale*s->chs[ch].v - 2.0*scale*s->chs[ch].uv);
>
> av_log(ctx, AV_LOG_INFO, "SI-SDR ch%d: %g dB\n", ch, 10. * log10(sisdr));
> }
> } else {
> for (int ch = 0; ch < s->channels; ch++) {
> - double psnr = s->sum_uv[ch] > 0.0 ? 2.0 * log(s->max) - log(s->nb_samples / s->sum_uv[ch]) : INFINITY;
> + double psnr = s->chs[ch].uv > 0.0 ? 2.0 * log(s->max) - log(s->nb_samples / s->chs[ch].uv) : INFINITY;
>
> av_log(ctx, AV_LOG_INFO, "PSNR ch%d: %g dB\n", ch, psnr);
> }
> @@ -238,9 +244,7 @@ static av_cold void uninit(AVFilterContext *ctx)
> av_frame_free(&s->cache[0]);
> av_frame_free(&s->cache[1]);
>
> - av_freep(&s->sum_u);
> - av_freep(&s->sum_v);
> - av_freep(&s->sum_uv);
> + av_freep(&s->chs);
> }
>
> static const AVFilterPad inputs[] = {
> --
> 2.39.1
>
> doc/filters.texi | 7 +++++
> libavfilter/Makefile | 1
> libavfilter/af_asdr.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++-
> libavfilter/allfilters.c | 1
> 4 files changed, 72 insertions(+), 1 deletion(-)
> 8ed085a8902fa86f0a99838bbd6c4b2645e187d6 0002-avfilter-add-asisdr-filter.patch
> From dfb20b0f4d08428a43b38185776baf6819fc4336 Mon Sep 17 00:00:00 2001
> From: Paul B Mahol <onemda@gmail.com>
> Date: Sun, 13 Aug 2023 04:19:08 +0200
> Subject: [PATCH 2/3] avfilter: add asisdr filter
>
> Signed-off-by: Paul B Mahol <onemda@gmail.com>
> ---
> doc/filters.texi | 7 +++++
> libavfilter/Makefile | 1 +
> libavfilter/af_asdr.c | 64 +++++++++++++++++++++++++++++++++++++++-
> libavfilter/allfilters.c | 1 +
> 4 files changed, 72 insertions(+), 1 deletion(-)
>
> diff --git a/doc/filters.texi b/doc/filters.texi
> index 1025917c63..159764bcb6 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -3197,6 +3197,13 @@ audio, the data is treated as if all the planes were concatenated.
> A list of Adler-32 checksums for each data plane.
> @end table
>
> +@section asisdr
> +Measure Audio Scaled-Invariant Signal-to-Distortion Ratio.
> +
> +This filter takes two audio streams for input, and outputs first
> +audio stream.
> +Results are in dB per channel at end of either input.
> +
> @section asoftclip
> Apply audio soft clipping.
>
> diff --git a/libavfilter/Makefile b/libavfilter/Makefile
> index 90c30e3388..ba07f4ab1e 100644
> --- a/libavfilter/Makefile
> +++ b/libavfilter/Makefile
> @@ -103,6 +103,7 @@ OBJS-$(CONFIG_ASETRATE_FILTER) += af_asetrate.o
> OBJS-$(CONFIG_ASETTB_FILTER) += settb.o
> OBJS-$(CONFIG_ASHOWINFO_FILTER) += af_ashowinfo.o
> OBJS-$(CONFIG_ASIDEDATA_FILTER) += f_sidedata.o
> +OBJS-$(CONFIG_ASISDR_FILTER) += af_asdr.o
> OBJS-$(CONFIG_ASOFTCLIP_FILTER) += af_asoftclip.o
> OBJS-$(CONFIG_ASPECTRALSTATS_FILTER) += af_aspectralstats.o
> OBJS-$(CONFIG_ASPLIT_FILTER) += split.o
> diff --git a/libavfilter/af_asdr.c b/libavfilter/af_asdr.c
> index b0401804f6..53069427bf 100644
> --- a/libavfilter/af_asdr.c
> +++ b/libavfilter/af_asdr.c
> @@ -32,6 +32,7 @@ typedef struct AudioSDRContext {
> uint64_t nb_samples;
> double max;
> double *sum_u;
> + double *sum_v;
> double *sum_uv;
>
> AVFrame *cache[2];
> @@ -71,6 +72,41 @@ static int sdr_##name(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)\
> SDR_FILTER(fltp, float)
> SDR_FILTER(dblp, double)
>
> +#define SISDR_FILTER(name, type) \
> +static int sisdr_##name(AVFilterContext *ctx, void *arg,int jobnr,int nb_jobs)\
> +{ \
> + AudioSDRContext *s = ctx->priv; \
> + AVFrame *u = s->cache[0]; \
> + AVFrame *v = s->cache[1]; \
> + const int channels = u->ch_layout.nb_channels; \
> + const int start = (channels * jobnr) / nb_jobs; \
> + const int end = (channels * (jobnr+1)) / nb_jobs; \
> + const int nb_samples = u->nb_samples; \
> + \
> + for (int ch = start; ch < end; ch++) { \
> + const type *const us = (type *)u->extended_data[ch]; \
> + const type *const vs = (type *)v->extended_data[ch]; \
> + double sum_uv = 0.; \
> + double sum_u = 0.; \
> + double sum_v = 0.; \
> +
\
> + for (int n = 0; n < nb_samples; n++) { \
> + sum_u += us[n] * us[n]; \
> + sum_v += vs[n] * vs[n]; \
> + sum_uv += us[n] * vs[n]; \
> + } \
These should be handled by DSP code which can be asm optimized
> + \
> + s->sum_uv[ch] += sum_uv; \
> + s->sum_u[ch] += sum_u; \
> + s->sum_v[ch] += sum_v; \
> + } \
> + \
> + return 0; \
> +}
> +
> +SISDR_FILTER(fltp, float)
> +SISDR_FILTER(dblp, double)
[...]
> @@ -67,6 +71,34 @@ static int sdr_##name(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)\
> SDR_FILTER(fltp, float)
> SDR_FILTER(dblp, double)
>
> +#define PSNR_FILTER(name, type) \
> +static int psnr_##name(AVFilterContext *ctx, void *arg, int jobnr,int nb_jobs)\
> +{ \
> + AudioSDRContext *s = ctx->priv; \
> + AVFrame *u = s->cache[0]; \
> + AVFrame *v = s->cache[1]; \
> + const int channels = u->ch_layout.nb_channels; \
> + const int start = (channels * jobnr) / nb_jobs; \
> + const int end = (channels * (jobnr+1)) / nb_jobs; \
> + const int nb_samples = u->nb_samples; \
> + \
> + for (int ch = start; ch < end; ch++) { \
> + const type *const us = (type *)u->extended_data[ch]; \
> + const type *const vs = (type *)v->extended_data[ch]; \
> + double sum_uv = 0.; \
> + \
> + for (int n = 0; n < nb_samples; n++) \
> + sum_uv += (us[n] - vs[n]) * (us[n] - vs[n]); \
These should be handled by DSP code which can be asm optimized
> + \
> + s->sum_uv[ch] += sum_uv; \
> + } \
> + \
> + return 0; \
> +}
> +
> +PSNR_FILTER(fltp, float)
> +PSNR_FILTER(dblp, double)
> +
> static int activate(AVFilterContext *ctx)
> {
> AudioSDRContext *s = ctx->priv;
[...]
Thx
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Any man who breaks a law that conscience tells him is unjust and willingly
accepts the penalty by staying in jail in order to arouse the conscience of
the community on the injustice of the law is at that moment expressing the
very highest respect for law. - Martin Luther King Jr
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
[-- Attachment #2: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2023-08-14 8:56 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-13 3:14 [FFmpeg-devel] [PATCH] apsnr and asisdr filter Paul B Mahol
2023-08-13 22:15 ` Paul B Mahol
2023-08-14 8:51 ` Michael Niedermayer
2023-08-14 8:56 ` Michael Niedermayer
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git