diff mbox series

[FFmpeg-devel] avfilter/f_graphmonitor: add tiny output mode

Message ID 20200909194632.2612-1-onemda@gmail.com
State New
Headers show
Series [FFmpeg-devel] avfilter/f_graphmonitor: add tiny output mode | expand

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

Paul B Mahol Sept. 9, 2020, 7:46 p.m. UTC
Signed-off-by: Paul B Mahol <onemda@gmail.com>
---
 doc/filters.texi             |   2 +-
 libavfilter/f_graphmonitor.c | 119 +++++++++++++++++++++++++++++++----
 2 files changed, 109 insertions(+), 12 deletions(-)

Comments

Paul B Mahol Sept. 12, 2020, 9:43 a.m. UTC | #1
On Wed, Sep 09, 2020 at 09:46:32PM +0200, Paul B Mahol wrote:
> Signed-off-by: Paul B Mahol <onemda@gmail.com>
> ---
>  doc/filters.texi             |   2 +-
>  libavfilter/f_graphmonitor.c | 119 +++++++++++++++++++++++++++++++----
>  2 files changed, 109 insertions(+), 12 deletions(-)
> 

Gonna apply.
diff mbox series

Patch

diff --git a/doc/filters.texi b/doc/filters.texi
index cbb16f22b2..c1672cc7f7 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -11909,7 +11909,7 @@  Set video output size. Default is @var{hd720}.
 Set video opacity. Default is @var{0.9}. Allowed range is from @var{0} to @var{1}.
 
 @item mode, m
-Set output mode, can be @var{fulll} or @var{compact}.
+Set output mode, can be @var{full} or @var{compact} or @var{tiny}.
 In @var{compact} mode only filters with some queued frames have displayed stats.
 
 @item flags, f
diff --git a/libavfilter/f_graphmonitor.c b/libavfilter/f_graphmonitor.c
index 74779965d9..e440a82af7 100644
--- a/libavfilter/f_graphmonitor.c
+++ b/libavfilter/f_graphmonitor.c
@@ -72,10 +72,11 @@  static const AVOption graphmonitor_options[] = {
     { "s",    "set monitor size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str="hd720"}, 0, 0, VF },
     { "opacity", "set video opacity", OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=.9}, 0, 1, VF },
     { "o",       "set video opacity", OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=.9}, 0, 1, VF },
-    { "mode", "set mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, VF, "mode" },
-    { "m",    "set mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, VF, "mode" },
+    { "mode", "set mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, VF, "mode" },
+    { "m",    "set mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, VF, "mode" },
         { "full",     NULL, 0, AV_OPT_TYPE_CONST, {.i64=0},   0, 0, VF, "mode" },
         { "compact",  NULL, 0, AV_OPT_TYPE_CONST, {.i64=1},   0, 0, VF, "mode" },
+        { "tiny",     NULL, 0, AV_OPT_TYPE_CONST, {.i64=2},   0, 0, VF, "mode" },
     { "flags", "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64=MODE_QUEUE}, 0, INT_MAX, VF, "flags" },
     { "f",     "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64=MODE_QUEUE}, 0, INT_MAX, VF, "flags" },
         { "queue",            NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_QUEUE},   0, 0, VF, "flags" },
@@ -246,19 +247,11 @@  static void draw_items(AVFilterContext *ctx, AVFrame *out,
     }
 }
 
-static int create_frame(AVFilterContext *ctx, int64_t pts)
+static void full_compact(AVFilterContext *ctx, AVFrame *out)
 {
     GraphMonitorContext *s = ctx->priv;
-    AVFilterLink *outlink = ctx->outputs[0];
-    AVFrame *out;
     int xpos, ypos = 0;
 
-    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
-    if (!out)
-        return AVERROR(ENOMEM);
-
-    clear_image(s, out, outlink);
-
     for (int i = 0; i < ctx->graph->nb_filters; i++) {
         AVFilterContext *filter = ctx->graph->filters[i];
         char buffer[1024] = { 0 };
@@ -307,6 +300,110 @@  static int create_frame(AVFilterContext *ctx, int64_t pts)
         }
         ypos += 5;
     }
+}
+
+static void draw_box(AVFrame *out, int x, int y, int w, int h, uint32_t border, uint32_t fill)
+{
+    uint8_t *dst;
+
+    if (x + w >= out->width || y + h >= out->height)
+        return;
+
+    dst = out->data[0] + y * out->linesize[0] + x * 4;
+
+    for (int i = 0; i < w; i++) {
+        AV_WL24(dst + i * 4, border);
+    }
+
+    for (int i = 0; i < h; i++) {
+        AV_WL24(dst, border);
+        AV_WL24(dst + 4 * w, border);
+        dst += out->linesize[0];
+    }
+
+    dst = out->data[0] + (y + h - 1) * out->linesize[0] + x * 4;
+
+    for (int i = 0; i < w; i++) {
+        AV_WL24(dst + i * 4, border);
+    }
+
+    dst = out->data[0] + (y + 1) * out->linesize[0] + (x + 1) * 4;
+
+    for (int j = 0; j < h - 2; j++) {
+        for (int i = 0; i < w - 1; i++) {
+            AV_WL24(dst + i * 4, fill);
+        }
+        dst += out->linesize[0];
+    }
+}
+
+#define aicolor 0x11CC44
+#define aocolor 0xCC1144
+#define vicolor 0x99FF00
+#define vocolor 0xFF9900
+
+static void tiny(AVFilterContext *ctx, AVFrame *out)
+{
+    int xpos, ypos = 2;
+
+    for (int i = 0; i < ctx->graph->nb_filters; i++) {
+        AVFilterContext *filter = ctx->graph->filters[i];
+
+        xpos = 2;
+        for (int j = 0; j < filter->nb_inputs; j++) {
+            AVFilterLink *l = filter->inputs[j];
+            size_t frames = ff_inlink_queued_frames(l);
+            uint32_t icolor = l->type == AVMEDIA_TYPE_VIDEO ? vicolor : aicolor;
+
+            draw_box(out, xpos, ypos, 8, 8, icolor, FFMIN(255, frames));
+            xpos += 10;
+
+            draw_box(out, xpos, ypos, 4, 8, icolor, (l->frame_count_in % 255) << 8);
+            draw_box(out, xpos+4, ypos, 4, 8, icolor, (l->frame_count_out % 255) << 16);
+            xpos += 12;
+        }
+
+        xpos = 2;
+        ypos += 8 * (filter->nb_inputs > 0) + 2;
+
+        for (int j = 0; j < filter->nb_outputs; j++) {
+            AVFilterLink *l = filter->outputs[j];
+            size_t frames = ff_inlink_queued_frames(l);
+            uint32_t ocolor = l->type == AVMEDIA_TYPE_VIDEO ? vocolor : aocolor;
+
+            draw_box(out, xpos, ypos, 8, 8, ocolor, FFMIN(255, frames));
+            xpos += 10;
+
+            draw_box(out, xpos, ypos, 4, 8, ocolor, (l->frame_count_in % 255) << 8);
+            draw_box(out, xpos+4, ypos, 4, 8, ocolor, (l->frame_count_out % 255) << 16);
+            xpos += 12;
+        }
+
+        ypos += 8 * (filter->nb_outputs > 0) + 2;
+    }
+}
+
+static int create_frame(AVFilterContext *ctx, int64_t pts)
+{
+    GraphMonitorContext *s = ctx->priv;
+    AVFilterLink *outlink = ctx->outputs[0];
+    AVFrame *out;
+
+    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
+    if (!out)
+        return AVERROR(ENOMEM);
+
+    clear_image(s, out, outlink);
+
+    switch (s->mode) {
+    case 0:
+    case 1:
+        full_compact(ctx, out);
+        break;
+    case 2:
+        tiny(ctx, out);
+        break;
+    }
 
     out->pts = pts;
     s->pts = pts + 1;