From patchwork Sun May 24 23:50:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lance Wang X-Patchwork-Id: 19839 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 8807F44AF1D for ; Mon, 25 May 2020 02:50:40 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 6833A687F6C; Mon, 25 May 2020 02:50:40 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pj1-f51.google.com (mail-pj1-f51.google.com [209.85.216.51]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6133F687F68 for ; Mon, 25 May 2020 02:50:34 +0300 (EEST) Received: by mail-pj1-f51.google.com with SMTP id cx22so7814595pjb.1 for ; Sun, 24 May 2020 16:50:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=23McD7ZBiC28+SDnYiRoyZMWwBLDB3TiI+PTx3MZThM=; b=tlgPQVugnYQ5IndZ4j2GYbR2BRtWGQZZ2rJvuGrTZhzp5WbtPvGXbcv4YCP4eD41+O vR10iUe6tYNQi3smANVvBSK++AxGfs03WpASnhL4dBglwTqsWlRVHrFlhQPxI8GhRUn+ WgggDy9fNI0O398lGo0WIQ8x0asZvW3/Z0HeARlKggV68SkeAyDRMyKZHimV79Ewr5Za +zZ7Kx4IMFA6Qr63CuTFbRYqrPifLc+O+NcqOxLMgPV0aELag/rwsMa1mQ84dftSHzr3 lRPApD/SZMhxu+GDRczdJeHTOl2+a1KlZWje2d0fmcx0TI65hKfibWb43VvjMJhPvQEB 5EpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=23McD7ZBiC28+SDnYiRoyZMWwBLDB3TiI+PTx3MZThM=; b=QFHy2oWI6GBar83eVvhvDDKBpuS2ihRPPIIttjdtiZ0/8lls/8ixvD1UhabXr6DuLA jmHQpZYA897WpZxHhj53Nnlc0yXjqUELdcleS6Xx44MteIHZCO8myO7+qhoLqOtLGZbh 9v4CB/CZTd163tUDsWqbFPWu2fUItRjZe4aUhh8XdumDtrJgzXWltnI7Pk7kQC9w3UoB oGN2Shh6kPtVeVtj6y7huh8dFil4WNkIjb2pJLfEMy00FFQeT0HiEfrh/kLNmgsuol0W z2FuqDLgHJ3fyJaHy2a+D47H8pKQ4FhaSTANTF9YvTpoD6Q8Yx4/ueO/hnEN9jTM7iSl FzuQ== X-Gm-Message-State: AOAM531KZuXV69K3VoY1tfdh4lVPz9Zd0oBmwrMlBiS/W8V/wPnj2gAi /ZcEYRsEJjfdm/ipWLNE+6SaOWUq X-Google-Smtp-Source: ABdhPJwfLn2PSoa7IKI3InFb/J2/EJWG3raRWYuj2NQ+iq3BEtiFKXpkvGONOuORN+GCpKn2uDBKBA== X-Received: by 2002:a17:90a:2e08:: with SMTP id q8mr7971862pjd.153.1590364232097; Sun, 24 May 2020 16:50:32 -0700 (PDT) Received: from vpn2.localdomain ([161.117.202.209]) by smtp.gmail.com with ESMTPSA id e19sm11251525pfn.17.2020.05.24.16.50.30 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sun, 24 May 2020 16:50:31 -0700 (PDT) From: lance.lmwang@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Mon, 25 May 2020 07:50:24 +0800 Message-Id: <1590364226-11567-1-git-send-email-lance.lmwang@gmail.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1589900073-4183-1-git-send-email-lance.lmwang@gmail.com> References: <1589900073-4183-1-git-send-email-lance.lmwang@gmail.com> Subject: [FFmpeg-devel] [PATCH v7 1/3] avfilter/graphdump: support for the graph2dot function 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 Cc: Limin Wang MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Limin Wang Signed-off-by: Limin Wang --- libavfilter/Makefile | 1 - libavfilter/graphdump.c | 89 +++++++++++++++++++++ tools/graph2dot.c | 204 ------------------------------------------------ 3 files changed, 89 insertions(+), 205 deletions(-) delete mode 100644 tools/graph2dot.c diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 4d07bb6..291126e 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -526,7 +526,6 @@ SKIPHEADERS-$(CONFIG_VULKAN) += vulkan.h OBJS-$(CONFIG_LIBGLSLANG) += glslang.o -TOOLS = graph2dot TESTPROGS = drawutils filtfmts formats integral TOOLS-$(CONFIG_LIBZMQ) += zmqsend diff --git a/libavfilter/graphdump.c b/libavfilter/graphdump.c index 79ef1a7..97d4f39 100644 --- a/libavfilter/graphdump.c +++ b/libavfilter/graphdump.c @@ -151,15 +151,104 @@ static void avfilter_graph_dump_to_buf(AVBPrint *buf, AVFilterGraph *graph) } } +static void avfilter_graph2dot_to_buf(AVBPrint *buf, AVFilterGraph *graph) +{ + int i, j; + + av_bprintf(buf, "digraph G {\n"); + av_bprintf(buf, "node [shape=box]\n"); + av_bprintf(buf, "rankdir=LR\n"); + + for (i = 0; i < graph->nb_filters; i++) { + char filter_ctx_label[128]; + const AVFilterContext *filter_ctx = graph->filters[i]; + + snprintf(filter_ctx_label, sizeof(filter_ctx_label), "%s\\n(%s)", + filter_ctx->name, + filter_ctx->filter->name); + + for (j = 0; j < filter_ctx->nb_outputs; j++) { + AVFilterLink *link = filter_ctx->outputs[j]; + if (link) { + char dst_filter_ctx_label[128]; + const AVFilterContext *dst_filter_ctx = link->dst; + + snprintf(dst_filter_ctx_label, sizeof(dst_filter_ctx_label), + "%s\\n(%s)", + dst_filter_ctx->name, + dst_filter_ctx->filter->name); + + av_bprintf(buf, "\"%s\" -> \"%s\" [ label= \"inpad:%s -> outpad:%s\\n", + filter_ctx_label, dst_filter_ctx_label, + avfilter_pad_get_name(link->srcpad, 0), + avfilter_pad_get_name(link->dstpad, 0)); + + if (link->type == AVMEDIA_TYPE_VIDEO) { + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format); + av_bprintf(buf, + "fmt:%s w:%d h:%d tb:%d/%d", + desc->name, + link->w, link->h, + link->time_base.num, link->time_base.den); + } else if (link->type == AVMEDIA_TYPE_AUDIO) { + char audio_buf[255]; + av_get_channel_layout_string(audio_buf, sizeof(audio_buf), -1, + link->channel_layout); + av_bprintf(buf, + "fmt:%s sr:%d cl:%s tb:%d/%d", + av_get_sample_fmt_name(link->format), + link->sample_rate, audio_buf, + link->time_base.num, link->time_base.den); + } + av_bprintf(buf, "\" ];\n"); + } + } + } + av_bprintf(buf, "}\n"); +} + char *avfilter_graph_dump(AVFilterGraph *graph, const char *options) { AVBPrint buf; char *dump = NULL; + int ret; + AVDictionary *dict = NULL; + AVDictionaryEntry *format = NULL; + AVDictionaryEntry *filename = NULL; + + ret = av_dict_parse_string(&dict, options, "=", ":", 0); + if (ret < 0) { + av_dict_free(&dict); + return NULL; + } + format = av_dict_get(dict, "fmt", NULL, 0); + if (format && !av_strcasecmp(format->value, "DOT")) { + av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED); + avfilter_graph2dot_to_buf(&buf, graph); + av_bprint_finalize(&buf, &dump); + } else { av_bprint_init(&buf, 0, AV_BPRINT_SIZE_COUNT_ONLY); avfilter_graph_dump_to_buf(&buf, graph); av_bprint_init(&buf, buf.len + 1, buf.len + 1); avfilter_graph_dump_to_buf(&buf, graph); av_bprint_finalize(&buf, &dump); + } + + if (filename = av_dict_get(dict, "filename", NULL, 0)) { + FILE* file = fopen(filename->value, "w"); + if (!file) { + av_log(graph, AV_LOG_ERROR, "failed to open: %s \n", filename->value); + av_freep(&dump); + return NULL; + } + if (dump) { + fputs(dump, file); + fflush(file); + } + fclose(file); + } + + av_dict_free(&dict); return dump; } diff --git a/tools/graph2dot.c b/tools/graph2dot.c deleted file mode 100644 index d5c1e4e..0000000 --- a/tools/graph2dot.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2008-2010 Stefano Sabatini - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#if HAVE_UNISTD_H -#include /* getopt */ -#endif -#include -#include - -#include "libavutil/channel_layout.h" -#include "libavutil/mem.h" -#include "libavutil/pixdesc.h" -#include "libavfilter/avfilter.h" - -#if !HAVE_GETOPT -#include "compat/getopt.c" -#endif - -static void usage(void) -{ - printf("Convert a libavfilter graph to a dot file.\n"); - printf("Usage: graph2dot [OPTIONS]\n"); - printf("\n" - "Options:\n" - "-i INFILE set INFILE as input file, stdin if omitted\n" - "-o OUTFILE set OUTFILE as output file, stdout if omitted\n" - "-h print this help\n"); -} - -struct line { - char data[256]; - struct line *next; -}; - -static void print_digraph(FILE *outfile, AVFilterGraph *graph) -{ - int i, j; - - fprintf(outfile, "digraph G {\n"); - fprintf(outfile, "node [shape=box]\n"); - fprintf(outfile, "rankdir=LR\n"); - - for (i = 0; i < graph->nb_filters; i++) { - char filter_ctx_label[128]; - const AVFilterContext *filter_ctx = graph->filters[i]; - - snprintf(filter_ctx_label, sizeof(filter_ctx_label), "%s\\n(%s)", - filter_ctx->name, - filter_ctx->filter->name); - - for (j = 0; j < filter_ctx->nb_outputs; j++) { - AVFilterLink *link = filter_ctx->outputs[j]; - if (link) { - char dst_filter_ctx_label[128]; - const AVFilterContext *dst_filter_ctx = link->dst; - - snprintf(dst_filter_ctx_label, sizeof(dst_filter_ctx_label), - "%s\\n(%s)", - dst_filter_ctx->name, - dst_filter_ctx->filter->name); - - fprintf(outfile, "\"%s\" -> \"%s\" [ label= \"inpad:%s -> outpad:%s\\n", - filter_ctx_label, dst_filter_ctx_label, - avfilter_pad_get_name(link->srcpad, 0), - avfilter_pad_get_name(link->dstpad, 0)); - - if (link->type == AVMEDIA_TYPE_VIDEO) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format); - fprintf(outfile, - "fmt:%s w:%d h:%d tb:%d/%d", - desc->name, - link->w, link->h, - link->time_base.num, link->time_base.den); - } else if (link->type == AVMEDIA_TYPE_AUDIO) { - char buf[255]; - av_get_channel_layout_string(buf, sizeof(buf), -1, - link->channel_layout); - fprintf(outfile, - "fmt:%s sr:%d cl:%s tb:%d/%d", - av_get_sample_fmt_name(link->format), - link->sample_rate, buf, - link->time_base.num, link->time_base.den); - } - fprintf(outfile, "\" ];\n"); - } - } - } - fprintf(outfile, "}\n"); -} - -int main(int argc, char **argv) -{ - const char *outfilename = NULL; - const char *infilename = NULL; - FILE *outfile = NULL; - FILE *infile = NULL; - char *graph_string = NULL; - AVFilterGraph *graph = av_mallocz(sizeof(AVFilterGraph)); - char c; - - av_log_set_level(AV_LOG_DEBUG); - - while ((c = getopt(argc, argv, "hi:o:")) != -1) { - switch (c) { - case 'h': - usage(); - return 0; - case 'i': - infilename = optarg; - break; - case 'o': - outfilename = optarg; - break; - case '?': - return 1; - } - } - - if (!infilename || !strcmp(infilename, "-")) - infilename = "/dev/stdin"; - infile = fopen(infilename, "r"); - if (!infile) { - fprintf(stderr, "Failed to open input file '%s': %s\n", - infilename, strerror(errno)); - return 1; - } - - if (!outfilename || !strcmp(outfilename, "-")) - outfilename = "/dev/stdout"; - outfile = fopen(outfilename, "w"); - if (!outfile) { - fprintf(stderr, "Failed to open output file '%s': %s\n", - outfilename, strerror(errno)); - return 1; - } - - /* read from infile and put it in a buffer */ - { - int64_t count = 0; - struct line *line, *last_line, *first_line; - char *p; - last_line = first_line = av_malloc(sizeof(struct line)); - if (!last_line) { - fprintf(stderr, "Memory allocation failure\n"); - return 1; - } - - while (fgets(last_line->data, sizeof(last_line->data), infile)) { - struct line *new_line = av_malloc(sizeof(struct line)); - if (!new_line) { - fprintf(stderr, "Memory allocation failure\n"); - return 1; - } - count += strlen(last_line->data); - last_line->next = new_line; - last_line = new_line; - } - last_line->next = NULL; - - graph_string = av_malloc(count + 1); - if (!graph_string) { - fprintf(stderr, "Memory allocation failure\n"); - return 1; - } - p = graph_string; - for (line = first_line; line->next; line = line->next) { - size_t l = strlen(line->data); - memcpy(p, line->data, l); - p += l; - } - *p = '\0'; - } - - if (avfilter_graph_parse(graph, graph_string, NULL, NULL, NULL) < 0) { - fprintf(stderr, "Failed to parse the graph description\n"); - return 1; - } - - if (avfilter_graph_config(graph, NULL) < 0) - return 1; - - print_digraph(outfile, graph); - fflush(outfile); - - return 0; -} From patchwork Sun May 24 23:50:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lance Wang X-Patchwork-Id: 19840 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 776C144AF1D for ; Mon, 25 May 2020 02:50:42 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 5B53D6880DF; Mon, 25 May 2020 02:50:42 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pg1-f195.google.com (mail-pg1-f195.google.com [209.85.215.195]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 2B6D0687FCC for ; Mon, 25 May 2020 02:50:36 +0300 (EEST) Received: by mail-pg1-f195.google.com with SMTP id 124so1734903pgi.9 for ; Sun, 24 May 2020 16:50:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=OvHrOZNSPlTaTjm426YFrKKjkpdmus25LOGo0M9QFEY=; b=S1BzfOv6WASt5jqryN5obIWPQXOzpKMKrRhFIymqD2GJn388bqbneNhLdSEthtJMes o/FOQpYNZ9oTUtlLk68iB9UTzd/yNk1Rbr01RvVJEsXh1S4MuL58UG66BrVYDjs2l57N gXWNbn0PwrU0SmDLNA/MpwWBxtJQJDwVubcZO5xkPjbEj/r0VJLgih15R5pEOVgJSFEk aFmrSPe8dlv87K1UtH1upFcGt/jempkVAvKOaLGRlKhQxYzgLVkBmeuI/r2sQhTx0cwL 97yEIGTOiJrRIL6NmUzvYQWjnHHOsbk5SoAPrxqLEUj02AQur1a3YcJun5aU0Akl8OmN VuOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=OvHrOZNSPlTaTjm426YFrKKjkpdmus25LOGo0M9QFEY=; b=K0wdAK5p7T7BH/km0+/0oxnHAP+DiVAISOtjQy+gf9cJBxJ6u0/2aKFIDf300c0ev3 OdqdfaJ9sy9n9raR1x92Uwp/YBSF2iy8Qmi4LhwAMTyHEw4jLZgDJzqdD7GFRUfAxvG4 7Z7djY7NvQ8EBDyq1iQz1DrpLyP5HSGfFScPxP7RKmonpAW8f4FLinNedHTwSq9kI8ik qs4aFhmsYmAle0y0gHfjCRuPO8YuQH68Qmeuk+xpdfVsCtQ3eJbWNLo3KlJuj/vJ3Jp7 dxKcGE8kvFTaCkB/avC9gq/tAR98gyycsS9vct6uTkUDH49S1Y+ioOuaZ8C7z7ysQkVl tdgA== X-Gm-Message-State: AOAM532c8KpL4XUICoLFfjFL2Lr5BdydesNdPrOBCWp0v5zkXc0Wni6C vBTh9xL7SPFqSQPMcxvZ1GzleWVW X-Google-Smtp-Source: ABdhPJwncVId1mXIcYcr6a0NP8sg1xwF7V9WODifvLS7Pr6aZMy9nQrb/bJ9aZC17+FDwafkvclWrg== X-Received: by 2002:a63:1414:: with SMTP id u20mr24431327pgl.47.1590364233640; Sun, 24 May 2020 16:50:33 -0700 (PDT) Received: from vpn2.localdomain ([161.117.202.209]) by smtp.gmail.com with ESMTPSA id e19sm11251525pfn.17.2020.05.24.16.50.32 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sun, 24 May 2020 16:50:33 -0700 (PDT) From: lance.lmwang@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Mon, 25 May 2020 07:50:25 +0800 Message-Id: <1590364226-11567-2-git-send-email-lance.lmwang@gmail.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1590364226-11567-1-git-send-email-lance.lmwang@gmail.com> References: <1589900073-4183-1-git-send-email-lance.lmwang@gmail.com> <1590364226-11567-1-git-send-email-lance.lmwang@gmail.com> Subject: [FFmpeg-devel] [PATCH v7 2/3] avdevice/lavfi: support the dumpgraph with options 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 Cc: Limin Wang MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Limin Wang Signed-off-by: Limin Wang --- doc/indevs.texi | 19 +++++++++++++++++-- libavdevice/lavfi.c | 8 +++++--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/doc/indevs.texi b/doc/indevs.texi index 6f5afaf..b4dffc4 100644 --- a/doc/indevs.texi +++ b/doc/indevs.texi @@ -973,8 +973,17 @@ Set the filename of the filtergraph to be read and sent to the other filters. Syntax of the filtergraph is the same as the one specified by the option @var{graph}. -@item dumpgraph -Dump graph to stderr. +@item dumpgraph (@emph{bool}) +Dump filter graph with ASCII style to stderr default. +By default, it is disable. + +@item dumpgraph_opts @var{options} +Set the options of dump filter graph + +it is a ':'-separated list of @var{key=value} pairs. + +Set the graph with graphviz DOT format by @var{fmt=dot|DOT}, +set the filename of filtergraph to output by @var{filename=path}. @end table @@ -988,6 +997,12 @@ ffplay -f lavfi -graph "color=c=pink [out0]" dummy @end example @item +dump the filter graph with graphviz DOT output format to ./test.tmp +@example +ffplay -dumpgraph 1 -dumpgraph_opts fmt=dot:filename=./test.tmp -f lavfi color=c=pink +@end example + +@item As the previous example, but use filename for specifying the graph description, and omit the "out0" label: @example diff --git a/libavdevice/lavfi.c b/libavdevice/lavfi.c index c949ff7..9cdfbaa 100644 --- a/libavdevice/lavfi.c +++ b/libavdevice/lavfi.c @@ -47,7 +47,7 @@ typedef struct { AVClass *class; ///< class for private options char *graph_str; char *graph_filename; - char *dump_graph; + char *dump_graph_opts; AVFilterGraph *graph; AVFilterContext **sinks; int *sink_stream_map; @@ -57,6 +57,7 @@ typedef struct { AVFrame *decoded_frame; int nb_sinks; AVPacket subcc_packet; + int dump_graph; } LavfiContext; static int *create_all_formats(int n) @@ -301,7 +302,7 @@ av_cold static int lavfi_read_header(AVFormatContext *avctx) goto end; if (lavfi->dump_graph) { - char *dump = avfilter_graph_dump(lavfi->graph, lavfi->dump_graph); + char *dump = avfilter_graph_dump(lavfi->graph, lavfi->dump_graph_opts); if (dump != NULL) { fputs(dump, stderr); fflush(stderr); @@ -493,7 +494,8 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt) static const AVOption options[] = { { "graph", "set libavfilter graph", OFFSET(graph_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, { "graph_file","set libavfilter graph filename", OFFSET(graph_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC}, - { "dumpgraph", "dump graph to stderr", OFFSET(dump_graph), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, + { "dumpgraph", "dump graph to stderr", OFFSET(dump_graph), AV_OPT_TYPE_BOOL, {.str = 0}, 0, 1, DEC }, + { "dumpgraph_opts", "set the options of dump graph", OFFSET(dump_graph_opts), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, { NULL }, }; From patchwork Sun May 24 23:50:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lance Wang X-Patchwork-Id: 19841 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 A222C44AF1D for ; Mon, 25 May 2020 02:50:44 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 8DE5C689247; Mon, 25 May 2020 02:50:44 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pl1-f194.google.com (mail-pl1-f194.google.com [209.85.214.194]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id BA0F86891FF for ; Mon, 25 May 2020 02:50:37 +0300 (EEST) Received: by mail-pl1-f194.google.com with SMTP id x11so5836674plv.9 for ; Sun, 24 May 2020 16:50:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=+VbZdfG8Bm4OlOL9m5umwAE+zi5t/nX5Bzd2M15k5bk=; b=feujVuKq0Qf4VXvAcl6QYfQvO5KsF+k0uYUNe+LZrK/AfkkPeKek2OQtg7leljp3N1 2vd0TnO7exdsqvKJdNT/RNTw1gmYzlvDzA4Ep1CIWEjtTW+fGHnjYIIR9AqosJk4zpv2 fy8pA+jifzIEUxtj5Okyyd1MYXQLAdf0nxvTXLLPeboYWLBPZOZ0pUfjJDujtTDqGQIm JIxE2kVJuRmKnD1IWxtn2Y9apARI6T0K2m9WU6umkO2/rqLwQFPSc+waQQWN57MGW676 qYLwYKNwH+eFBaMwpQUFQ0olkaIZajEbt4d/hu/G9FkpBPnn6ddPMFeYKmtlNB/SY/QI AGYQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=+VbZdfG8Bm4OlOL9m5umwAE+zi5t/nX5Bzd2M15k5bk=; b=TxnMEnsDw1re6Q5LmA77kekI9aJyxKOI+Voxk6s0IBsgeIkDolVg3uI27EEc4RW1Ak Olbgt8piiAvVLJy5xJ8jSj0wXW+Kwvh0sAqlZRCqEo9jG7EILwMWIikhTshSXPWyP+6C 8GvvGOz5lDoov3llZqyL3Cb1tzuHM49LfXhvlyA447DJf3UKYtsceHBkgGdBdPLb+R4/ pitkvJxPnrG2aDKhxSGOD7kSvsvoybGk47V85mLbl1NdPHtCsvpY0PsFwhAYy+h8CTU8 Xa2C/5wapSl1awlG/Ct0ncZ0/gdKyXjrD/vVfddfb+5la9l9a17vYZJiH24dDp+gDEU9 vfsA== X-Gm-Message-State: AOAM533SqtcJvvDzvY9dopqpgZdCVEf7lMQq5bqHZkzIk8IoW7jFmpvY StGBhtPzDz891JAo3yfK8LxoORFh X-Google-Smtp-Source: ABdhPJz4VFHB7dqybYPkktXydf4OMbJvJSZyzq+YyA5n6HF+2G3xbdZtO0WRSSA/5h+l6tqqxuofEA== X-Received: by 2002:a17:90a:c385:: with SMTP id h5mr17862200pjt.147.1590364235371; Sun, 24 May 2020 16:50:35 -0700 (PDT) Received: from vpn2.localdomain ([161.117.202.209]) by smtp.gmail.com with ESMTPSA id e19sm11251525pfn.17.2020.05.24.16.50.33 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sun, 24 May 2020 16:50:34 -0700 (PDT) From: lance.lmwang@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Mon, 25 May 2020 07:50:26 +0800 Message-Id: <1590364226-11567-3-git-send-email-lance.lmwang@gmail.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1590364226-11567-1-git-send-email-lance.lmwang@gmail.com> References: <1589900073-4183-1-git-send-email-lance.lmwang@gmail.com> <1590364226-11567-1-git-send-email-lance.lmwang@gmail.com> Subject: [FFmpeg-devel] [PATCH v7 3/3] fftools: add options to dump filter graph 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 Cc: Limin Wang MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Limin Wang Signed-off-by: Limin Wang --- doc/ffmpeg.texi | 12 ++++++++++++ fftools/ffmpeg.c | 1 + fftools/ffmpeg.h | 1 + fftools/ffmpeg_filter.c | 11 +++++++++++ fftools/ffmpeg_opt.c | 10 ++++++++++ 5 files changed, 35 insertions(+) diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index ed437bb..c7dd73b 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -735,6 +735,18 @@ Technical note -- attachments are implemented as codec extradata, so this option can actually be used to extract extradata from any stream, not just attachments. +@item dump_filtergraph @var{options} (@emph{global}) +Dump graph to stderr with more options + +options is a ':'-separated list of @var{key=value} pairs. + +Set the graph with graphviz DOT format by @var{fmt=dot|DOT}, +set the filename of filtergraph to output by @var{filename=path}. + +@example +ffmpeg -dump_filtergraph fmt=dot:filename=./test.tmp -i INPUT +@end example + @item -noautorotate Disable automatically rotating video based on file metadata. diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index f697460..2c611a7 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -625,6 +625,7 @@ static void ffmpeg_cleanup(int ret) av_err2str(AVERROR(errno))); } av_freep(&vstats_filename); + av_freep(&dump_filtergraph); av_freep(&input_streams); av_freep(&input_files); diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 38205a1..000c682 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -578,6 +578,7 @@ extern int nb_filtergraphs; extern char *vstats_filename; extern char *sdp_filename; +extern char *dump_filtergraph; extern float audio_drift_threshold; extern float dts_delta_threshold; diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 8b5b157..c5adfae 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -1106,6 +1106,17 @@ int configure_filtergraph(FilterGraph *fg) if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0) goto fail; + if (dump_filtergraph) { + char *dump = avfilter_graph_dump(fg->graph, dump_filtergraph); + if (!dump) { + ret = AVERROR(ENOMEM); + goto fail; + } + fputs(dump, stderr); + fflush(stderr); + av_free(dump); + } + /* limit the lists of allowed formats to the ones selected, to * make sure they stay the same if the filtergraph is reconfigured later */ for (i = 0; i < fg->nb_outputs; i++) { diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index 60bb437..e4ebc88 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -143,6 +143,7 @@ HWDevice *filter_hw_device; char *vstats_filename; char *sdp_filename; +char *dump_filtergraph; float audio_drift_threshold = 0.1; float dts_delta_threshold = 10; @@ -2914,6 +2915,13 @@ static int opt_vstats_file(void *optctx, const char *opt, const char *arg) return 0; } +static int opt_dumpgraph(void *optctx, const char *opt, const char *arg) +{ + av_free (dump_filtergraph); + dump_filtergraph = av_strdup(arg); + return 0; +} + static int opt_vstats(void *optctx, const char *opt, const char *arg) { char filename[40]; @@ -3548,6 +3556,8 @@ const OptionDef options[] = { { "dump_attachment", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_EXPERT | OPT_INPUT, { .off = OFFSET(dump_attachment) }, "extract an attachment into a file", "filename" }, + { "dump_filtergraph",HAS_ARG | OPT_EXPERT, { .func_arg = opt_dumpgraph }, + "dump filter graph to stderr with options"}, { "stream_loop", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_INPUT | OPT_OFFSET, { .off = OFFSET(loop) }, "set number of times input stream shall be looped", "loop count" }, { "debug_ts", OPT_BOOL | OPT_EXPERT, { &debug_ts },