[FFmpeg-cvslog] avfilter/af_axcorrelate: always process all input samples

Paul B Mahol git at videolan.org
Sat Oct 9 02:46:18 EEST 2021


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Fri Oct  8 13:09:07 2021 +0200| [eb22b8953c2d51c1677549200965e25ed79f796d] | committer: Paul B Mahol

avfilter/af_axcorrelate: always process all input samples

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=eb22b8953c2d51c1677549200965e25ed79f796d
---

 libavfilter/af_axcorrelate.c | 53 ++++++++++++++++++++++++++------------------
 1 file 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;



More information about the ffmpeg-cvslog mailing list