]> git.sesse.net Git - ffmpeg/commitdiff
avfilter/vf_histogram: add slide modes for thistogram
authorPaul B Mahol <onemda@gmail.com>
Sat, 26 Sep 2020 19:57:46 +0000 (21:57 +0200)
committerPaul B Mahol <onemda@gmail.com>
Sat, 26 Sep 2020 20:04:27 +0000 (22:04 +0200)
doc/filters.texi
libavfilter/vf_histogram.c

index cbb16f22b27d274c6a5838aaac0f97b291839ec5..06572218b8bb7a2dae20341746542eff84b8df01 100644 (file)
@@ -18270,6 +18270,29 @@ Show envelope. Default is disabled.
 
 @item ecolor, ec
 Set envelope color. Default is @code{gold}.
+
+@item slide
+Set slide mode.
+
+Available values for slide is:
+@table @samp
+@item frame
+Draw new frame when right border is reached.
+
+@item replace
+Replace old columns with new ones.
+
+@item scroll
+Scroll from right to left.
+
+@item rscroll
+Scroll from left to right.
+
+@item picture
+Draw single picture.
+@end table
+
+Default is @code{replace}.
 @end table
 
 @section threshold
index 4800c06f26a34caa86d2d9ca3de8ef09d184e199..ed6892bc8ba6a2cd945d3abb8ca32876df6d563c 100644 (file)
@@ -34,6 +34,7 @@ typedef struct HistogramContext {
     const AVClass *class;               ///< AVClass context for log and options purpose
     int            thistogram;
     int            envelope;
+    int            slide;
     unsigned       histogram[256*256];
     int            histogram_size;
     int            width;
@@ -354,8 +355,25 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
         max_hval_log = log2(max_hval + 1);
 
         if (s->thistogram) {
+            const int bpp = 1 + (s->histogram_size > 256);
             int minh = s->histogram_size - 1, maxh = 0;
 
+            if (s->slide == 2) {
+                s->x_pos = out->width - 1;
+                for (j = 0; j < outlink->h; j++) {
+                    memmove(out->data[p] + j * out->linesize[p] ,
+                            out->data[p] + j * out->linesize[p] + bpp,
+                            (outlink->w - 1) * bpp);
+                }
+            } else if (s->slide == 3) {
+                s->x_pos = 0;
+                for (j = 0; j < outlink->h; j++) {
+                    memmove(out->data[p] + j * out->linesize[p] + bpp,
+                            out->data[p] + j * out->linesize[p],
+                            (outlink->w - 1) * bpp);
+                }
+            }
+
             for (int i = 0; i < s->histogram_size; i++) {
                 int idx = s->histogram_size - i - 1;
                 int value = s->start[p];
@@ -443,8 +461,15 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
     out->pts = in->pts;
     av_frame_free(&in);
     s->x_pos++;
-    if (s->x_pos >= s->width)
+    if (s->x_pos >= s->width) {
         s->x_pos = 0;
+        if (s->thistogram && (s->slide == 4 || s->slide == 0)) {
+            s->out = NULL;
+            goto end;
+        }
+    } else if (s->thistogram && s->slide == 4) {
+        return 0;
+    }
 
     if (s->thistogram) {
         AVFrame *clone = av_frame_clone(out);
@@ -453,6 +478,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
             return AVERROR(ENOMEM);
         return ff_filter_frame(outlink, clone);
     }
+end:
     return ff_filter_frame(outlink, out);
 }
 
@@ -491,6 +517,13 @@ AVFilter ff_vf_histogram = {
 
 #if CONFIG_THISTOGRAM_FILTER
 
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    HistogramContext *s = ctx->priv;
+
+    av_frame_free(&s->out);
+}
+
 static const AVOption thistogram_options[] = {
     { "width", "set width", OFFSET(width), AV_OPT_TYPE_INT, {.i64=0}, 0, 8192, FLAGS},
     { "w",     "set width", OFFSET(width), AV_OPT_TYPE_INT, {.i64=0}, 0, 8192, FLAGS},
@@ -501,6 +534,12 @@ static const AVOption thistogram_options[] = {
     { "e",        "display envelope", OFFSET(envelope), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS },
     { "ecolor", "set envelope color", OFFSET(envelope_rgba), AV_OPT_TYPE_COLOR, {.str="gold"}, 0, 0, FLAGS },
     { "ec",     "set envelope color", OFFSET(envelope_rgba), AV_OPT_TYPE_COLOR, {.str="gold"}, 0, 0, FLAGS },
+    { "slide", "set slide mode",                     OFFSET(slide), AV_OPT_TYPE_INT,   {.i64=1}, 0, 4, FLAGS, "slide" },
+        {"frame",   "draw new frames",               OFFSET(slide), AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "slide"},
+        {"replace", "replace old columns with new",  OFFSET(slide), AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "slide"},
+        {"scroll",  "scroll from right to left",     OFFSET(slide), AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "slide"},
+        {"rscroll", "scroll from left to right",     OFFSET(slide), AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, FLAGS, "slide"},
+        {"picture", "display graph in single frame", OFFSET(slide), AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, FLAGS, "slide"},
     { NULL }
 };
 
@@ -513,6 +552,7 @@ AVFilter ff_vf_thistogram = {
     .query_formats = query_formats,
     .inputs        = inputs,
     .outputs       = outputs,
+    .uninit        = uninit,
     .priv_class    = &thistogram_class,
 };