[FFmpeg-devel,2/2] avfilter/avf_showspectrum: add fps option

Submitted by Paul B Mahol on Oct. 6, 2018, 12:30 p.m.

Details

Message ID 20181006123011.17742-2-onemda@gmail.com
State New
Headers show

Commit Message

Paul B Mahol Oct. 6, 2018, 12:30 p.m.
Signed-off-by: Paul B Mahol <onemda@gmail.com>
---
 libavfilter/avf_showspectrum.c | 31 +++++++++++++++++++++++--------
 1 file changed, 23 insertions(+), 8 deletions(-)

Patch hide | download patch | download mbox

diff --git a/libavfilter/avf_showspectrum.c b/libavfilter/avf_showspectrum.c
index 30238e0c3f..9e268f9d33 100644
--- a/libavfilter/avf_showspectrum.c
+++ b/libavfilter/avf_showspectrum.c
@@ -34,6 +34,7 @@ 
 #include "libavutil/avstring.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
 #include "libavutil/xga_font_data.h"
 #include "audio.h"
 #include "video.h"
@@ -52,6 +53,9 @@  enum Orientation  { VERTICAL, HORIZONTAL, NB_ORIENTATIONS };
 typedef struct ShowSpectrumContext {
     const AVClass *class;
     int w, h;
+    char *rate_str;
+    AVRational auto_frame_rate;
+    AVRational frame_rate;
     AVFrame *outpicref;
     int nb_display_channels;
     int orientation;
@@ -86,7 +90,7 @@  typedef struct ShowSpectrumContext {
     float **color_buffer;       ///< color buffer (3 * h * ch items)
     AVAudioFifo *fifo;
     int64_t pts;
-    int eof;
+    int64_t old_pts;
     int single_pic;
     int legend;
     int start_x, start_y;
@@ -158,6 +162,7 @@  static const AVOption showspectrum_options[] = {
     { "rotation", "color rotation", OFFSET(rotation), AV_OPT_TYPE_FLOAT, {.dbl = 0}, -1, 1, FLAGS },
     { "start", "start frequency", OFFSET(start), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT32_MAX, FLAGS },
     { "stop",  "stop frequency",  OFFSET(stop),  AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT32_MAX, FLAGS },
+    { "fps",   "set video rate",  OFFSET(rate_str), AV_OPT_TYPE_STRING, {.str = "auto"}, 0, 0, FLAGS },
     { NULL }
 };
 
@@ -605,11 +610,17 @@  static int config_output(AVFilterLink *outlink)
         (s->orientation == HORIZONTAL && s->xpos >= s->h))
         s->xpos = 0;
 
-    outlink->frame_rate = av_make_q(inlink->sample_rate, s->win_size * (1.-s->overlap));
+    s->auto_frame_rate = av_make_q(inlink->sample_rate, s->win_size * (1.-s->overlap));
     if (s->orientation == VERTICAL && s->sliding == FULLFRAME)
-        outlink->frame_rate.den *= s->w;
+        s->auto_frame_rate.den *= s->w;
     if (s->orientation == HORIZONTAL && s->sliding == FULLFRAME)
-        outlink->frame_rate.den *= s->h;
+        s->auto_frame_rate.den *= s->h;
+    if (strcmp(s->rate_str, "auto")) {
+        av_parse_video_rate(&s->frame_rate, s->rate_str);
+    } else {
+        s->frame_rate = s->auto_frame_rate;
+    }
+    outlink->frame_rate = s->frame_rate;
 
     if (s->orientation == VERTICAL) {
         s->combine_buffer =
@@ -956,10 +967,14 @@  static int plot_spectrum_column(AVFilterLink *inlink, AVFrame *insamples)
     if (s->orientation == HORIZONTAL && s->xpos >= s->h)
         s->xpos = 0;
     if (!s->single_pic && (s->sliding != FULLFRAME || s->xpos == 0)) {
-        ret = ff_filter_frame(outlink, av_frame_clone(s->outpicref));
-        if (ret < 0)
-            return ret;
-        return 0;
+        AVRational step = av_make_q(inlink->sample_rate, s->pts - s->old_pts);
+        if (av_cmp_q(outlink->frame_rate, step) >= 0) {
+            ret = ff_filter_frame(outlink, av_frame_clone(s->outpicref));
+            s->old_pts = s->pts;
+            if (ret < 0)
+                return ret;
+            return 0;
+        }
     }
 
     return 1;