[FFmpeg-cvslog] avfilter/avf_showfreqs: add rate option

Paul B Mahol git at videolan.org
Sat Apr 30 16:39:50 EEST 2022


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Sat Apr 30 15:33:13 2022 +0200| [d8e8aa944aa633dbb1990c4d33654234aaf0d312] | committer: Paul B Mahol

avfilter/avf_showfreqs: add rate option

Fix possible buffer overflow.

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

 doc/filters.texi            |  3 +++
 libavfilter/avf_showfreqs.c | 58 +++++++++++++++++++++++++--------------------
 2 files changed, 35 insertions(+), 26 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 72628af9b2..478a75bd3a 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -28476,6 +28476,9 @@ Specify size of video. For the syntax of this option, check the
 @ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
 Default is @code{1024x512}.
 
+ at item rate, r
+Set video rate. Default is @code{25}.
+
 @item mode
 Set display mode.
 This set how each frequency bin will be represented.
diff --git a/libavfilter/avf_showfreqs.c b/libavfilter/avf_showfreqs.c
index 5d13f71a2b..6dcff686b6 100644
--- a/libavfilter/avf_showfreqs.c
+++ b/libavfilter/avf_showfreqs.c
@@ -70,6 +70,9 @@ typedef struct ShowFreqsContext {
     int win_size;
     float scale;
     char *colors;
+    int64_t pts;
+    int64_t old_pts;
+    AVRational frame_rate;
 } ShowFreqsContext;
 
 #define OFFSET(x) offsetof(ShowFreqsContext, x)
@@ -78,6 +81,8 @@ typedef struct ShowFreqsContext {
 static const AVOption showfreqs_options[] = {
     { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "1024x512"}, 0, 0, FLAGS },
     { "s",    "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "1024x512"}, 0, 0, FLAGS },
+    { "rate", "set video rate",  OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, FLAGS },
+    { "r",    "set video rate",  OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, FLAGS },
     { "mode", "set display mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=BAR}, 0, NB_MODES-1, FLAGS, "mode" },
         { "line", "show lines",  0, AV_OPT_TYPE_CONST, {.i64=LINE},   0, 0, FLAGS, "mode" },
         { "bar",  "show bars",   0, AV_OPT_TYPE_CONST, {.i64=BAR},    0, 0, FLAGS, "mode" },
@@ -149,6 +154,7 @@ static int config_output(AVFilterLink *outlink)
     float overlap, scale;
     int i, ret;
 
+    s->old_pts = AV_NOPTS_VALUE;
     s->nb_freq = s->fft_size / 2;
     s->win_size = s->fft_size;
     av_tx_uninit(&s->fft);
@@ -215,7 +221,7 @@ static int config_output(AVFilterLink *outlink)
     if (!s->window)
         return AVERROR(ENOMEM);
 
-    outlink->frame_rate = av_make_q(inlink->sample_rate, s->hop_size);
+    outlink->frame_rate = s->frame_rate;
     outlink->time_base = av_inv_q(outlink->frame_rate);
     outlink->sample_aspect_ratio = (AVRational){1,1};
     outlink->w = s->w;
@@ -328,13 +334,13 @@ static inline void plot_freq(ShowFreqsContext *s, int ch,
 
     switch (s->avg) {
     case 0:
-        y = s->avg_data[ch][f] = !outlink->frame_count_in ? y : FFMIN(avg, y);
+        y = s->avg_data[ch][f] = !outlink->frame_count_in ? y : FFMIN(0, y);
         break;
     case 1:
         break;
     default:
-        s->avg_data[ch][f] = avg + y * (y - avg) / (FFMIN(outlink->frame_count_in + 1, s->avg) * y);
-        y = s->avg_data[ch][f];
+        s->avg_data[ch][f] = avg + y * (y - avg) / (FFMIN(outlink->frame_count_in + 1, s->avg) * (float)y);
+        y = av_clip(s->avg_data[ch][f], 0, outlink->h - 1);
         break;
     }
 
@@ -379,13 +385,6 @@ static int plot_freqs(AVFilterLink *inlink, int64_t pts)
     AVFrame *out;
     int ch, n;
 
-    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
-    if (!out)
-        return AVERROR(ENOMEM);
-
-    for (n = 0; n < outlink->h; n++)
-        memset(out->data[0] + out->linesize[0] * n, 0, outlink->w * 4);
-
     /* fill FFT input with the number of samples available */
     for (ch = 0; ch < s->nb_channels; ch++) {
         const float *p = (float *)in->extended_data[ch];
@@ -407,16 +406,26 @@ static int plot_freqs(AVFilterLink *inlink, int64_t pts)
         s->tx_fn(s->fft, s->fft_data[ch], s->fft_input[ch], sizeof(float));
     }
 
+    s->pts = av_rescale_q(pts, inlink->time_base, outlink->time_base);
+    if (s->old_pts >= s->pts)
+        return 0;
+    s->old_pts = s->pts;
+
 #define RE(x, ch) s->fft_data[ch][x].re
 #define IM(x, ch) s->fft_data[ch][x].im
 #define M(a, b) (sqrt((a) * (a) + (b) * (b)))
 #define P(a, b) (atan2((b), (a)))
 
     colors = av_strdup(s->colors);
-    if (!colors) {
-        av_frame_free(&out);
+    if (!colors)
         return AVERROR(ENOMEM);
-    }
+
+    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
+    if (!out)
+        return AVERROR(ENOMEM);
+
+    for (n = 0; n < outlink->h; n++)
+        memset(out->data[0] + out->linesize[0] * n, 0, outlink->w * 4);
 
     for (ch = 0; ch < s->nb_channels; ch++) {
         uint8_t fg[4] = { 0xff, 0xff, 0xff, 0xff };
@@ -432,29 +441,21 @@ static int plot_freqs(AVFilterLink *inlink, int64_t pts)
 
         switch (s->data_mode) {
         case MAGNITUDE:
-            a = av_clipd(M(RE(0, ch), 0) / s->scale, 0, 1);
-            plot_freq(s, ch, a, 0, fg, &prev_y, out, outlink);
-
-            for (f = 1; f < s->nb_freq; f++) {
+            for (f = 0; f < s->nb_freq; f++) {
                 a = av_clipd(M(RE(f, ch), IM(f, ch)) / s->scale, 0, 1);
 
                 plot_freq(s, ch, a, f, fg, &prev_y, out, outlink);
             }
             break;
         case PHASE:
-            a = av_clipd((M_PI + P(RE(0, ch), 0)) / (2. * M_PI), 0, 1);
-            plot_freq(s, ch, a, 0, fg, &prev_y, out, outlink);
-
-            for (f = 1; f < s->nb_freq; f++) {
+            for (f = 0; f < s->nb_freq; f++) {
                 a = av_clipd((M_PI + P(RE(f, ch), IM(f, ch))) / (2. * M_PI), 0, 1);
 
                 plot_freq(s, ch, a, f, fg, &prev_y, out, outlink);
             }
             break;
         case DELAY:
-            plot_freq(s, ch, 0, 0, fg, &prev_y, out, outlink);
-
-            for (f = 1; f < s->nb_freq; f++) {
+            for (f = 0; f < s->nb_freq; f++) {
                 a = av_clipd((M_PI - P(IM(f, ch) * RE(f-1, ch) - IM(f-1, ch) * RE(f, ch),
                                        RE(f, ch) * RE(f-1, ch) + IM(f, ch) * IM(f-1, ch))) / (2. * M_PI), 0, 1);
 
@@ -465,7 +466,7 @@ static int plot_freqs(AVFilterLink *inlink, int64_t pts)
     }
 
     av_free(colors);
-    out->pts = av_rescale_q(pts, inlink->time_base, outlink->time_base);
+    out->pts = s->pts;
     out->sample_aspect_ratio = (AVRational){1,1};
     return ff_filter_frame(outlink, out);
 }
@@ -509,6 +510,11 @@ static int activate(AVFilterContext *ctx)
     if (ret < 0)
         return ret;
 
+    if (ff_inlink_queued_samples(inlink) >= s->hop_size) {
+        ff_filter_set_ready(ctx, 10);
+        return 0;
+    }
+
     FF_FILTER_FORWARD_STATUS(inlink, outlink);
     FF_FILTER_FORWARD_WANTED(outlink, inlink);
 



More information about the ffmpeg-cvslog mailing list