summaryrefslogtreecommitdiff
path: root/libavfilter/af_axcorrelate.c
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2021-10-08 13:09:07 +0200
committerPaul B Mahol <onemda@gmail.com>2021-10-09 01:44:23 +0200
commiteb22b8953c2d51c1677549200965e25ed79f796d (patch)
treedbbc32b7113840a10b365f88e7370082f03b42f5 /libavfilter/af_axcorrelate.c
parent21914e7a4e802772cc9cdeec3eec8b30da4fa95a (diff)
avfilter/af_axcorrelate: always process all input samples
Diffstat (limited to 'libavfilter/af_axcorrelate.c')
-rw-r--r--libavfilter/af_axcorrelate.c53
1 files changed, 31 insertions, 22 deletions
diff --git a/libavfilter/af_axcorrelate.c b/libavfilter/af_axcorrelate.c
index c27e42f2ed..d9ef853b69 100644
--- a/libavfilter/af_axcorrelate.c
+++ b/libavfilter/af_axcorrelate.c
@@ -42,8 +42,9 @@ typedef struct AudioXCorrelateContext {
AVFrame *num_sum;
AVFrame *den_sum[2];
int used;
+ int eof;
- int (*xcorrelate)(AVFilterContext *ctx, AVFrame *out);
+ int (*xcorrelate)(AVFilterContext *ctx, AVFrame *out, int available);
} AudioXCorrelateContext;
static float mean_sum(const float *in, int size)
@@ -86,10 +87,10 @@ static float xcorrelate(const float *x, const float *y, float sumx, float sumy,
return den <= 1e-6f ? 0.f : num / den;
}
-static int xcorrelate_slow(AVFilterContext *ctx, AVFrame *out)
+static int xcorrelate_slow(AVFilterContext *ctx, AVFrame *out, int available)
{
AudioXCorrelateContext *s = ctx->priv;
- const int size = s->size;
+ const int size = FFMIN(available, s->size);
int used;
for (int ch = 0; ch < out->channels; ch++) {
@@ -107,22 +108,24 @@ static int xcorrelate_slow(AVFilterContext *ctx, AVFrame *out)
}
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[n + size];
+ sumx[0] += x[idx];
sumy[0] -= y[n];
- sumy[0] += y[n + size];
+ sumy[0] += y[idx];
}
}
return used;
}
-static int xcorrelate_fast(AVFilterContext *ctx, AVFrame *out)
+static int xcorrelate_fast(AVFilterContext *ctx, AVFrame *out, int available)
{
AudioXCorrelateContext *s = ctx->priv;
- const int size = s->size;
+ const int size = FFMIN(available, s->size);
int used;
for (int ch = 0; ch < out->channels; ch++) {
@@ -142,6 +145,7 @@ static int xcorrelate_fast(AVFilterContext *ctx, AVFrame *out)
}
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;
@@ -150,13 +154,13 @@ static int xcorrelate_fast(AVFilterContext *ctx, AVFrame *out)
dst[n] = den <= 1e-6f ? 0.f : num / den;
num_sum[0] -= x[n] * y[n];
- num_sum[0] += x[n + size] * y[n + size];
+ 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_sumx[0] += x[n + size] * x[n + size];
den_sumy[0] -= y[n] * y[n];
+ den_sumy[0] += y[idx] * y[idx];
den_sumy[0] = FFMAX(den_sumy[0], 0.f);
- den_sumy[0] += y[n + size] * y[n + size];
}
}
@@ -187,8 +191,8 @@ static int activate(AVFilterContext *ctx)
}
available = FFMIN(av_audio_fifo_size(s->fifo[0]), av_audio_fifo_size(s->fifo[1]));
- if (available > s->size) {
- const int out_samples = available - s->size;
+ if (available > s->size || (s->eof && available > 0)) {
+ const int out_samples = s->eof ? available : available - s->size;
AVFrame *out;
if (!s->cache[0] || s->cache[0]->nb_samples < available) {
@@ -217,7 +221,7 @@ static int activate(AVFilterContext *ctx)
if (!out)
return AVERROR(ENOMEM);
- s->used = s->xcorrelate(ctx, out);
+ s->used = s->xcorrelate(ctx, out, available);
out->pts = s->pts;
s->pts += out_samples;
@@ -228,20 +232,25 @@ static int activate(AVFilterContext *ctx)
return ff_filter_frame(ctx->outputs[0], out);
}
- if (av_audio_fifo_size(s->fifo[0]) > s->size &&
- av_audio_fifo_size(s->fifo[1]) > s->size) {
- ff_filter_set_ready(ctx, 10);
+ for (int i = 0; i < 2 && !s->eof; i++) {
+ if (ff_inlink_acknowledge_status(ctx->inputs[i], &status, &pts))
+ s->eof = 1;
+ }
+
+ if (s->eof &&
+ (av_audio_fifo_size(s->fifo[0]) <= 0 ||
+ av_audio_fifo_size(s->fifo[1]) <= 0)) {
+ ff_outlink_set_status(ctx->outputs[0], AVERROR_EOF, s->pts);
return 0;
}
- for (int i = 0; i < 2; i++) {
- if (ff_inlink_acknowledge_status(ctx->inputs[i], &status, &pts)) {
- ff_outlink_set_status(ctx->outputs[0], status, pts);
- return 0;
- }
+ if ((av_audio_fifo_size(s->fifo[0]) > s->size &&
+ av_audio_fifo_size(s->fifo[1]) > s->size) || s->eof) {
+ ff_filter_set_ready(ctx, 10);
+ return 0;
}
- if (ff_outlink_frame_wanted(ctx->outputs[0])) {
+ if (ff_outlink_frame_wanted(ctx->outputs[0]) && !s->eof) {
for (int i = 0; i < 2; i++) {
if (av_audio_fifo_size(s->fifo[i]) > s->size)
continue;