summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2021-10-09 13:58:07 +0200
committerPaul B Mahol <onemda@gmail.com>2021-10-09 14:10:09 +0200
commit30d46094844cedaaf93e8007f6260b3f232946f3 (patch)
tree7c99e842c5db38b5365c3ab5066407d9cd7cb545
parent95cae4922d340e69de3bde592e2dc5c481c3956b (diff)
avfilter/af_axcorrelate: add DBLP sample format support
-rw-r--r--libavfilter/af_axcorrelate.c266
1 files changed, 150 insertions, 116 deletions
diff --git a/libavfilter/af_axcorrelate.c b/libavfilter/af_axcorrelate.c
index e0c37cb8ac..d0a91cd836 100644
--- a/libavfilter/af_axcorrelate.c
+++ b/libavfilter/af_axcorrelate.c
@@ -47,126 +47,156 @@ typedef struct AudioXCorrelateContext {
int (*xcorrelate)(AVFilterContext *ctx, AVFrame *out, int available);
} AudioXCorrelateContext;
-static float mean_sum(const float *in, int size)
-{
- float mean_sum = 0.f;
-
- for (int i = 0; i < size; i++)
- mean_sum += in[i];
-
- return mean_sum;
+#define MEAN_SUM(suffix, type, zero) \
+static type mean_sum_##suffix(const type *in, \
+ int size) \
+{ \
+ type mean_sum = zero; \
+ \
+ for (int i = 0; i < size; i++) \
+ mean_sum += in[i]; \
+ \
+ return mean_sum; \
}
-static float square_sum(const float *x, const float *y, int size)
-{
- float square_sum = 0.f;
-
- for (int i = 0; i < size; i++)
- square_sum += x[i] * y[i];
-
- return square_sum;
+MEAN_SUM(f, float, 0.f)
+MEAN_SUM(d, double, 0.0)
+
+#define SQUARE_SUM(suffix, type, zero) \
+static type square_sum_##suffix(const type *x, \
+ const type *y, \
+ int size) \
+{ \
+ type square_sum = zero; \
+ \
+ for (int i = 0; i < size; i++) \
+ square_sum += x[i] * y[i]; \
+ \
+ return square_sum; \
}
-static float xcorrelate(const float *x, const float *y, float sumx, float sumy, int size)
-{
- const float xm = sumx / size, ym = sumy / size;
- float num = 0.f, den, den0 = 0.f, den1 = 0.f;
-
- for (int i = 0; i < size; i++) {
- float xd = x[i] - xm;
- float yd = y[i] - ym;
-
- num += xd * yd;
- den0 += xd * xd;
- den1 += yd * yd;
- }
-
- num /= size;
- den = sqrtf((den0 * den1) / size / size);
-
- return den <= 1e-6f ? 0.f : num / den;
+SQUARE_SUM(f, float, 0.f)
+SQUARE_SUM(d, double, 0.0)
+
+#define XCORRELATE(suffix, type, zero, small, sqrtfun)\
+static type xcorrelate_##suffix(const type *x, \
+ const type *y, \
+ type sumx, \
+ type sumy, int size) \
+{ \
+ const type xm = sumx / size, ym = sumy / size; \
+ type num = zero, den, den0 = zero, den1 = zero; \
+ \
+ for (int i = 0; i < size; i++) { \
+ type xd = x[i] - xm; \
+ type yd = y[i] - ym; \
+ \
+ num += xd * yd; \
+ den0 += xd * xd; \
+ den1 += yd * yd; \
+ } \
+ \
+ num /= size; \
+ den = sqrtfun((den0 * den1) / size / size); \
+ \
+ return den <= small ? zero : num / den; \
}
-static int xcorrelate_slow(AVFilterContext *ctx, AVFrame *out, int available)
-{
- AudioXCorrelateContext *s = ctx->priv;
- const int size = FFMIN(available, s->size);
- int used;
-
- for (int ch = 0; ch < out->channels; ch++) {
- const float *x = (const float *)s->cache[0]->extended_data[ch];
- const float *y = (const float *)s->cache[1]->extended_data[ch];
- float *sumx = (float *)s->mean_sum[0]->extended_data[ch];
- float *sumy = (float *)s->mean_sum[1]->extended_data[ch];
- float *dst = (float *)out->extended_data[ch];
-
- used = s->used;
- if (!used) {
- sumx[0] = mean_sum(x, size);
- sumy[0] = mean_sum(y, size);
- used = 1;
- }
-
- for (int n = 0; n < out->nb_samples; n++) {
- const int idx = available <= s->size ? out->nb_samples - n - 1 : n + size;
-
- dst[n] = xcorrelate(x + n, y + n, sumx[0], sumy[0], size);
-
- sumx[0] -= x[n];
- sumx[0] += x[idx];
- sumy[0] -= y[n];
- sumy[0] += y[idx];
- }
- }
-
- return used;
+XCORRELATE(f, float, 0.f, 1e-6f, sqrtf)
+XCORRELATE(d, double, 0.0, 1e-9, sqrt)
+
+#define XCORRELATE_SLOW(suffix, type) \
+static int xcorrelate_slow_##suffix(AVFilterContext *ctx, \
+ AVFrame *out, int available) \
+{ \
+ AudioXCorrelateContext *s = ctx->priv; \
+ const int size = FFMIN(available, s->size); \
+ int used; \
+ \
+ for (int ch = 0; ch < out->channels; ch++) { \
+ const type *x = (const type *)s->cache[0]->extended_data[ch]; \
+ const type *y = (const type *)s->cache[1]->extended_data[ch]; \
+ type *sumx = (type *)s->mean_sum[0]->extended_data[ch]; \
+ type *sumy = (type *)s->mean_sum[1]->extended_data[ch]; \
+ type *dst = (type *)out->extended_data[ch]; \
+ \
+ used = s->used; \
+ if (!used) { \
+ sumx[0] = mean_sum_##suffix(x, size); \
+ sumy[0] = mean_sum_##suffix(y, size); \
+ used = 1; \
+ } \
+ \
+ for (int n = 0; n < out->nb_samples; n++) { \
+ const int idx = available <= s->size ? out->nb_samples - n - 1 : n + size; \
+ \
+ dst[n] = xcorrelate_##suffix(x + n, y + n, \
+ sumx[0], sumy[0], \
+ size); \
+ \
+ sumx[0] -= x[n]; \
+ sumx[0] += x[idx]; \
+ sumy[0] -= y[n]; \
+ sumy[0] += y[idx]; \
+ } \
+ } \
+ \
+ return used; \
}
-static int xcorrelate_fast(AVFilterContext *ctx, AVFrame *out, int available)
-{
- AudioXCorrelateContext *s = ctx->priv;
- const int size = FFMIN(available, s->size);
- int used;
-
- for (int ch = 0; ch < out->channels; ch++) {
- const float *x = (const float *)s->cache[0]->extended_data[ch];
- const float *y = (const float *)s->cache[1]->extended_data[ch];
- float *num_sum = (float *)s->num_sum->extended_data[ch];
- float *den_sumx = (float *)s->den_sum[0]->extended_data[ch];
- float *den_sumy = (float *)s->den_sum[1]->extended_data[ch];
- float *dst = (float *)out->extended_data[ch];
-
- used = s->used;
- if (!used) {
- num_sum[0] = square_sum(x, y, size);
- den_sumx[0] = square_sum(x, x, size);
- den_sumy[0] = square_sum(y, y, size);
- used = 1;
- }
-
- for (int n = 0; n < out->nb_samples; n++) {
- const int idx = available <= s->size ? out->nb_samples - n - 1 : n + size;
- float num, den;
-
- num = num_sum[0] / size;
- den = sqrtf((den_sumx[0] * den_sumy[0]) / size / size);
-
- dst[n] = den <= 1e-6f ? 0.f : num / den;
-
- num_sum[0] -= x[n] * y[n];
- num_sum[0] += x[idx] * y[idx];
- den_sumx[0] -= x[n] * x[n];
- den_sumx[0] += x[idx] * x[idx];
- den_sumx[0] = FFMAX(den_sumx[0], 0.f);
- den_sumy[0] -= y[n] * y[n];
- den_sumy[0] += y[idx] * y[idx];
- den_sumy[0] = FFMAX(den_sumy[0], 0.f);
- }
- }
-
- return used;
+XCORRELATE_SLOW(f, float)
+XCORRELATE_SLOW(d, double)
+
+#define XCORRELATE_FAST(suffix, type, zero, small, sqrtfun) \
+static int xcorrelate_fast_##suffix(AVFilterContext *ctx, AVFrame *out, \
+ int available) \
+{ \
+ AudioXCorrelateContext *s = ctx->priv; \
+ const int size = FFMIN(available, s->size); \
+ int used; \
+ \
+ for (int ch = 0; ch < out->channels; ch++) { \
+ const type *x = (const type *)s->cache[0]->extended_data[ch]; \
+ const type *y = (const type *)s->cache[1]->extended_data[ch]; \
+ type *num_sum = (type *)s->num_sum->extended_data[ch]; \
+ type *den_sumx = (type *)s->den_sum[0]->extended_data[ch]; \
+ type *den_sumy = (type *)s->den_sum[1]->extended_data[ch]; \
+ type *dst = (type *)out->extended_data[ch]; \
+ \
+ used = s->used; \
+ if (!used) { \
+ num_sum[0] = square_sum_##suffix(x, y, size); \
+ den_sumx[0] = square_sum_##suffix(x, x, size); \
+ den_sumy[0] = square_sum_##suffix(y, y, size); \
+ used = 1; \
+ } \
+ \
+ for (int n = 0; n < out->nb_samples; n++) { \
+ const int idx = available <= s->size ? out->nb_samples - n - 1 : n + size; \
+ type num, den; \
+ \
+ num = num_sum[0] / size; \
+ den = sqrtfun((den_sumx[0] * den_sumy[0]) / size / size); \
+ \
+ dst[n] = den <= small ? zero : num / den; \
+ \
+ num_sum[0] -= x[n] * y[n]; \
+ num_sum[0] += x[idx] * y[idx]; \
+ den_sumx[0] -= x[n] * x[n]; \
+ den_sumx[0] += x[idx] * x[idx]; \
+ den_sumx[0] = FFMAX(den_sumx[0], zero); \
+ den_sumy[0] -= y[n] * y[n]; \
+ den_sumy[0] += y[idx] * y[idx]; \
+ den_sumy[0] = FFMAX(den_sumy[0], zero); \
+ } \
+ } \
+ \
+ return used; \
}
+XCORRELATE_FAST(f, float, 0.f, 1e-6f, sqrtf)
+XCORRELATE_FAST(d, double, 0.0, 1e-9, sqrt)
+
static int activate(AVFilterContext *ctx)
{
AudioXCorrelateContext *s = ctx->priv;
@@ -265,13 +295,10 @@ static int activate(AVFilterContext *ctx)
static int config_output(AVFilterLink *outlink)
{
AVFilterContext *ctx = outlink->src;
- AVFilterLink *inlink = ctx->inputs[0];
AudioXCorrelateContext *s = ctx->priv;
s->pts = AV_NOPTS_VALUE;
- outlink->format = inlink->format;
- outlink->channels = inlink->channels;
s->fifo[0] = av_audio_fifo_alloc(outlink->format, outlink->channels, s->size);
s->fifo[1] = av_audio_fifo_alloc(outlink->format, outlink->channels, s->size);
if (!s->fifo[0] || !s->fifo[1])
@@ -287,8 +314,15 @@ static int config_output(AVFilterLink *outlink)
return AVERROR(ENOMEM);
switch (s->algo) {
- case 0: s->xcorrelate = xcorrelate_slow; break;
- case 1: s->xcorrelate = xcorrelate_fast; break;
+ case 0: s->xcorrelate = xcorrelate_slow_f; break;
+ case 1: s->xcorrelate = xcorrelate_fast_f; break;
+ }
+
+ if (outlink->format == AV_SAMPLE_FMT_DBLP) {
+ switch (s->algo) {
+ case 0: s->xcorrelate = xcorrelate_slow_d; break;
+ case 1: s->xcorrelate = xcorrelate_fast_d; break;
+ }
}
return 0;
@@ -350,5 +384,5 @@ const AVFilter ff_af_axcorrelate = {
.uninit = uninit,
FILTER_INPUTS(inputs),
FILTER_OUTPUTS(outputs),
- FILTER_SINGLE_SAMPLEFMT(AV_SAMPLE_FMT_FLTP),
+ FILTER_SAMPLEFMTS(AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_DBLP),
};