[FFmpeg-devel] [PATCH] avfilter/f_graphmonitor: add tiny output mode
Paul B Mahol
onemda at gmail.com
Wed Sep 9 22:46:32 EEST 2020
Signed-off-by: Paul B Mahol <onemda at gmail.com>
---
doc/filters.texi | 2 +-
libavfilter/f_graphmonitor.c | 119 +++++++++++++++++++++++++++++++----
2 files changed, 109 insertions(+), 12 deletions(-)
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;
--
2.17.1
More information about the ffmpeg-devel
mailing list