[FFmpeg-devel] [PATCH] lavfi/showwaves: add display mode

Stefano Sabatini stefasab at gmail.com
Tue Jan 22 20:46:30 CET 2013


TODO: bump micro
---
 doc/filters.texi            |   13 +++++++++++++
 libavfilter/avf_showwaves.c |   31 ++++++++++++++++++++++++++++---
 2 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index ad8b5da..2b6793c 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -5702,6 +5702,19 @@ Convert input audio to a video output, representing the samples waves.
 
 The filter accepts the following named parameters:
 @table @option
+ at item mode
+Set display mode.
+
+Available values are:
+ at table @samp
+ at item point
+Draw a point for each sample.
+
+ at item line
+Draw a vertical line for each sample.
+ at end table
+
+Default value is @code{point}.
 
 @item n
 Set the number of samples which are printed on the same column. A
diff --git a/libavfilter/avf_showwaves.c b/libavfilter/avf_showwaves.c
index 20f127e..2fd2692 100644
--- a/libavfilter/avf_showwaves.c
+++ b/libavfilter/avf_showwaves.c
@@ -32,6 +32,12 @@
 #include "video.h"
 #include "internal.h"
 
+enum ShowWavesMode {
+    MODE_POINT,
+    MODE_LINE,
+    MODE_NB,
+};
+
 typedef struct {
     const AVClass *class;
     int w, h;
@@ -42,6 +48,7 @@ typedef struct {
     int req_fullfilled;
     int n;
     int sample_count_mod;
+    enum ShowWavesMode mode;
 } ShowWavesContext;
 
 #define OFFSET(x) offsetof(ShowWavesContext, x)
@@ -53,6 +60,10 @@ static const AVOption showwaves_options[] = {
     { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "600x240"}, 0, 0, FLAGS },
     { "s",    "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "600x240"}, 0, 0, FLAGS },
     { "n",    "set how many samples to show in the same point", OFFSET(n), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS },
+
+    {"mode",  "select display mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_POINT}, 0, MODE_NB-1, FLAGS, "mode"},
+    {"point", "draw a point for each sample", 0, AV_OPT_TYPE_CONST, {.i64=MODE_POINT}, INT_MIN, INT_MAX, FLAGS, "mode"},
+    {"line",  "draw a line for each sample", 0, AV_OPT_TYPE_CONST, {.i64=MODE_LINE}, INT_MIN, INT_MAX, FLAGS, "mode"},
     { NULL },
 };
 
@@ -187,7 +198,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
     int linesize = outpicref ? outpicref->linesize[0] : 0;
     int16_t *p = (int16_t *)insamples->data[0];
     int nb_channels = av_get_channel_layout_nb_channels(insamples->audio->channel_layout);
-    int i, j, h;
+    int i, j, k, h;
     const int n = showwaves->n;
     const int x = 255 / (nb_channels * n); /* multiplication factor, pre-computed to avoid in-loop divisions */
 
@@ -210,9 +221,23 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
         }
         for (j = 0; j < nb_channels; j++) {
             h = showwaves->h/2 - av_rescale(*p++, showwaves->h/2, MAX_INT16);
-            if (h >= 0 && h < outlink->h)
-                *(outpicref->data[0] + showwaves->buf_idx + h * linesize) += x;
+            switch (showwaves->mode) {
+            case MODE_POINT:
+                if (h >= 0 && h < outlink->h)
+                    *(outpicref->data[0] + showwaves->buf_idx + h * linesize) += x;
+                break;
+
+            case MODE_LINE:
+            {
+                int start = showwaves->h/2, end = av_clip(h, 0, outlink->h-1);
+                if (start > end) FFSWAP(int16_t, start, end);
+                for (k = start; k < end; k++)
+                    *(outpicref->data[0] + showwaves->buf_idx + k * linesize) += x;
+                break;
+            }
+            }
         }
+
         showwaves->sample_count_mod++;
         if (showwaves->sample_count_mod == n) {
             showwaves->sample_count_mod = 0;
-- 
1.7.9.5



More information about the ffmpeg-devel mailing list