From patchwork Wed Sep 9 19:46:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul B Mahol X-Patchwork-Id: 22242 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 8EB7A44B323 for ; Wed, 9 Sep 2020 22:46:50 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 7723268B96E; Wed, 9 Sep 2020 22:46:50 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ej1-f67.google.com (mail-ej1-f67.google.com [209.85.218.67]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 93A8968B96A for ; Wed, 9 Sep 2020 22:46:43 +0300 (EEST) Received: by mail-ej1-f67.google.com with SMTP id nw23so5302352ejb.4 for ; Wed, 09 Sep 2020 12:46:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id; bh=8V0NIZY7imsA48wydQK0xbJDAj9Bt+pnoEfr0fxvRnk=; b=SlyXWmFFKas4M2dAhgwwSbPBxKMVCJfQdYGF6M+6Eyb3FAeCtRYBeaHF0RHXMHE0px UM2Dann3vVKKGUAD+lZ9WJ5FXRafSAGRzG7OutRtjisVkvB/bZrqE5vEVPAKWaickvmW DgS0SsX4IIIwqtT9ME7d6a3m1KS858W/NBpS1dkxrOtlvTRnDdGn/V6xbeV609wN5TMm hhSHfFQlTmikHSt+JypdSVEU9HKItbMOmQPYjN6byKwxcr95AopcCoGzxqWVxvY2z0Y5 3UND1sZTawMw6ls/yBfY1BtUFL6ELw3qL2i1VNrAcHXgXtlwD5LBFZqsaud4sgF14+wZ DJkA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id; bh=8V0NIZY7imsA48wydQK0xbJDAj9Bt+pnoEfr0fxvRnk=; b=O1mKGv5TznRwjNzJxsPVNql/z3gIRVrzYTW7lblOnsrRKOtXcnSMXsE5q1GUmE8n5o pM5ovgGiVvq8EySVakX8zjn3hdLozFlmlLObtWoZRFLlZeTngcKBRnUwFdvCgIy1i4sC Z9samcMfk9WjyseJ2av8LQYOBYMhq2Z2byoNUVdKJAMmdV9copgL7C0Xh/CEmDbE/usB TqPCTVgJ+WPsoG6+NVDEKLYfGp0HRmAckfZGGDHNEB+xrRY+n80OB/bpPfFBVYgBVZp+ VVykW8Q4e6SeA4cqDlhsG3YMdlUbApScpMnKKDlLHrLdg+eUREooT6scln2y50j5x0rp AGhg== X-Gm-Message-State: AOAM532cO4waMu57BIexySrhiuFjBXvgYWI6ceHPAYV1/cdRXNlnRc03 x2oe3+Hn0QPfGKOD9pHhrSDoWlL87Z9BKg== X-Google-Smtp-Source: ABdhPJx/njkmm1Hx0/7xYuw51t/DYztS5IRbvdq/JIds2bfbueKhisqPaMeQGFWN9eNfckGlkJngkg== X-Received: by 2002:a17:906:f92:: with SMTP id q18mr5089377ejj.237.1599680802810; Wed, 09 Sep 2020 12:46:42 -0700 (PDT) Received: from localhost.localdomain ([94.250.162.52]) by smtp.gmail.com with ESMTPSA id c5sm3530817ejk.37.2020.09.09.12.46.41 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2020 12:46:42 -0700 (PDT) From: Paul B Mahol To: ffmpeg-devel@ffmpeg.org Date: Wed, 9 Sep 2020 21:46:32 +0200 Message-Id: <20200909194632.2612-1-onemda@gmail.com> X-Mailer: git-send-email 2.17.1 Subject: [FFmpeg-devel] [PATCH] avfilter/f_graphmonitor: add tiny output mode X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: Paul B Mahol --- 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;