[FFmpeg-cvslog] avfilter/avf_showfreqs: stop using audio fifo

Paul B Mahol git at videolan.org
Wed Feb 23 18:07:47 EET 2022


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Wed Feb 23 16:43:29 2022 +0100| [d27e1cb6332157d1bfb04e5f3c4686c459fc5644] | committer: Paul B Mahol

avfilter/avf_showfreqs: stop using audio fifo

Also stop rewriting pts.

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

 libavfilter/avf_showfreqs.c | 90 +++++++++++++++------------------------------
 1 file changed, 30 insertions(+), 60 deletions(-)

diff --git a/libavfilter/avf_showfreqs.c b/libavfilter/avf_showfreqs.c
index 08dbce53c8..6f9b55943a 100644
--- a/libavfilter/avf_showfreqs.c
+++ b/libavfilter/avf_showfreqs.c
@@ -22,7 +22,6 @@
 #include <math.h>
 
 #include "libavutil/tx.h"
-#include "libavutil/audio_fifo.h"
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/channel_layout.h"
@@ -56,6 +55,7 @@ typedef struct ShowFreqsContext {
     av_tx_fn tx_fn;
     AVComplexFloat **fft_input;
     AVComplexFloat **fft_data;
+    AVFrame *window;
     float **avg_data;
     float *window_func_lut;
     float overlap;
@@ -66,8 +66,6 @@ typedef struct ShowFreqsContext {
     int win_size;
     float scale;
     char *colors;
-    AVAudioFifo *fifo;
-    int64_t pts;
 } ShowFreqsContext;
 
 #define OFFSET(x) offsetof(ShowFreqsContext, x)
@@ -138,15 +136,6 @@ static int query_formats(AVFilterContext *ctx)
     return 0;
 }
 
-static av_cold int init(AVFilterContext *ctx)
-{
-    ShowFreqsContext *s = ctx->priv;
-
-    s->pts = AV_NOPTS_VALUE;
-
-    return 0;
-}
-
 static int config_output(AVFilterLink *outlink)
 {
     AVFilterContext *ctx = outlink->src;
@@ -157,7 +146,6 @@ static int config_output(AVFilterLink *outlink)
 
     s->nb_freq = s->fft_size / 2;
     s->win_size = s->fft_size;
-    av_audio_fifo_free(s->fifo);
     av_tx_uninit(&s->fft);
     ret = av_tx_init(&s->fft, &s->tx_fn, AV_TX_FLOAT_FFT, 0, s->fft_size, &scale, 0);
     if (ret < 0) {
@@ -214,14 +202,16 @@ static int config_output(AVFilterLink *outlink)
         s->scale += s->window_func_lut[i] * s->window_func_lut[i];
     }
 
-    outlink->frame_rate = av_make_q(inlink->sample_rate, s->win_size * (1.-s->overlap));
+    s->window = ff_get_audio_buffer(inlink, s->win_size * 2);
+    if (!s->window)
+        return AVERROR(ENOMEM);
+
+    outlink->frame_rate = av_make_q(inlink->sample_rate, s->hop_size);
+    outlink->time_base = av_inv_q(outlink->frame_rate);
     outlink->sample_aspect_ratio = (AVRational){1,1};
     outlink->w = s->w;
     outlink->h = s->h;
 
-    s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, s->win_size);
-    if (!s->fifo)
-        return AVERROR(ENOMEM);
     return 0;
 }
 
@@ -349,11 +339,12 @@ static inline void plot_freq(ShowFreqsContext *s, int ch,
     }
 }
 
-static int plot_freqs(AVFilterLink *inlink, AVFrame *in)
+static int plot_freqs(AVFilterLink *inlink, int64_t pts)
 {
     AVFilterContext *ctx = inlink->dst;
     AVFilterLink *outlink = ctx->outputs[0];
     ShowFreqsContext *s = ctx->priv;
+    AVFrame *in = s->window;
     const int win_size = s->win_size;
     char *colors, *color, *saveptr = NULL;
     AVFrame *out;
@@ -370,14 +361,10 @@ static int plot_freqs(AVFilterLink *inlink, AVFrame *in)
     for (ch = 0; ch < s->nb_channels; ch++) {
         const float *p = (float *)in->extended_data[ch];
 
-        for (n = 0; n < in->nb_samples; n++) {
+        for (n = 0; n < win_size; n++) {
             s->fft_input[ch][n].re = p[n] * s->window_func_lut[n];
             s->fft_input[ch][n].im = 0;
         }
-        for (; n < win_size; n++) {
-            s->fft_input[ch][n].re = 0;
-            s->fft_input[ch][n].im = 0;
-        }
     }
 
     /* run FFT on each samples set */
@@ -440,37 +427,29 @@ static int plot_freqs(AVFilterLink *inlink, AVFrame *in)
     }
 
     av_free(colors);
-    out->pts = in->pts;
+    out->pts = av_rescale_q(pts, inlink->time_base, outlink->time_base);
     out->sample_aspect_ratio = (AVRational){1,1};
     return ff_filter_frame(outlink, out);
 }
 
-static int filter_frame(AVFilterLink *inlink)
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
     AVFilterContext *ctx = inlink->dst;
     ShowFreqsContext *s = ctx->priv;
-    AVFrame *fin = NULL;
-    int ret = 0;
+    const int offset = s->win_size - s->hop_size;
+    int64_t pts = in->pts;
 
-    fin = ff_get_audio_buffer(inlink, s->win_size);
-    if (!fin) {
-        ret = AVERROR(ENOMEM);
-        goto fail;
-    }
+    for (int ch = 0; ch < in->channels; ch++) {
+        float *dst = (float *)s->window->extended_data[ch];
 
-    fin->pts = s->pts;
-    s->pts += s->hop_size;
-    ret = av_audio_fifo_peek(s->fifo, (void **)fin->extended_data, s->win_size);
-    if (ret < 0)
-        goto fail;
+        memmove(dst, &dst[s->hop_size], offset * sizeof(float));
+        memcpy(&dst[offset], in->extended_data[ch], in->nb_samples * sizeof(float));
+        memset(&dst[offset + in->nb_samples], 0, (s->hop_size - in->nb_samples) * sizeof(float));
+    }
 
-    ret = plot_freqs(inlink, fin);
-    av_frame_free(&fin);
-    av_audio_fifo_drain(s->fifo, s->hop_size);
+    av_frame_free(&in);
 
-fail:
-    av_frame_free(&fin);
-    return ret;
+    return plot_freqs(inlink, pts);
 }
 
 static int activate(AVFilterContext *ctx)
@@ -478,27 +457,19 @@ static int activate(AVFilterContext *ctx)
     AVFilterLink *inlink = ctx->inputs[0];
     AVFilterLink *outlink = ctx->outputs[0];
     ShowFreqsContext *s = ctx->priv;
-    AVFrame *in = NULL;
-    int ret = 0;
+    AVFrame *in;
+    int ret;
 
     FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
 
-    if (av_audio_fifo_size(s->fifo) < s->win_size)
-        ret = ff_inlink_consume_samples(inlink, s->win_size, s->win_size, &in);
+    ret = ff_inlink_consume_samples(inlink, s->hop_size, s->hop_size, &in);
     if (ret < 0)
         return ret;
-    if (ret > 0) {
-        av_audio_fifo_write(s->fifo, (void **)in->extended_data, in->nb_samples);
-        if (s->pts == AV_NOPTS_VALUE)
-            s->pts = in->pts;
-        av_frame_free(&in);
-    }
 
-    if (av_audio_fifo_size(s->fifo) >= s->win_size) {
-        ret = filter_frame(inlink);
-        if (ret <= 0)
-            return ret;
-    }
+    if (ret > 0)
+        ret = filter_frame(inlink, in);
+    if (ret < 0)
+        return ret;
 
     FF_FILTER_FORWARD_STATUS(inlink, outlink);
     FF_FILTER_FORWARD_WANTED(outlink, inlink);
@@ -524,7 +495,7 @@ static av_cold void uninit(AVFilterContext *ctx)
     av_freep(&s->fft_data);
     av_freep(&s->avg_data);
     av_freep(&s->window_func_lut);
-    av_audio_fifo_free(s->fifo);
+    av_frame_free(&s->window);
 }
 
 static const AVFilterPad showfreqs_inputs[] = {
@@ -545,7 +516,6 @@ static const AVFilterPad showfreqs_outputs[] = {
 const AVFilter ff_avf_showfreqs = {
     .name          = "showfreqs",
     .description   = NULL_IF_CONFIG_SMALL("Convert input audio to a frequencies video output."),
-    .init          = init,
     .uninit        = uninit,
     .priv_size     = sizeof(ShowFreqsContext),
     .activate      = activate,



More information about the ffmpeg-cvslog mailing list