From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id E98DC49C47 for ; Tue, 5 Mar 2024 15:06:49 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id EC07D68D03D; Tue, 5 Mar 2024 17:06:46 +0200 (EET) Received: from mail-lf1-f43.google.com (mail-lf1-f43.google.com [209.85.167.43]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4832F68D024 for ; Tue, 5 Mar 2024 17:06:41 +0200 (EET) Received: by mail-lf1-f43.google.com with SMTP id 2adb3069b0e04-5101cd91017so7949137e87.2 for ; Tue, 05 Mar 2024 07:06:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1709651199; x=1710255999; darn=ffmpeg.org; h=user-agent:in-reply-to:content-disposition:mime-version:references :mail-followup-to:message-id:subject:to:from:date:from:to:cc:subject :date:message-id:reply-to; bh=8ivD3Mu1qo9nthEFCez3ARY+VWorwapypAiJ3LQe3Dc=; b=knFOelmEPhIt2/nRcH87cBXgd7BF+0RwRULYyTfTcppAQ+wyZhU4qZHK6y0srk9JqA WjLF0vOJ4PRqwYX3r2fvwE+C38eMCkdNxhupdyASikGqK1e2eKlY0qjSDnJMuyYyFj6k apsXQUcgQnY/9SnfRtIcLllNaq5nuE4G0lHy+6W4iphtdHWL3aUnCXGj6K2nWaYh6ULX 4hn5wFS47qrlslRNPZe5CZE8HHIWmwwu0Lb0YW3oxKmGbUT85cXL35tg5TWmGqqupRZl Xo2pIRLVfBVOmhBIvvVrb0EfZwSN7+TfbBdcAmFM0r/+0CR3tzjm7wacOmfLnJg0PnP7 CcCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709651199; x=1710255999; h=user-agent:in-reply-to:content-disposition:mime-version:references :mail-followup-to:message-id:subject:to:from:date:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=8ivD3Mu1qo9nthEFCez3ARY+VWorwapypAiJ3LQe3Dc=; b=EOESC65A7YXXIeEZjbngrGqss5KtktmwIY4DbBLKv83ZNFDrhfWqncSfF+75uwbJ4z dZWgn5Gmw4T5NS9jLsrAL7rweZWahKh4zkazzmXgIS7gCtlavzeVOVJS3K9uDLVK5U+i /eYZBGgvZN+BGZ2Ieus92b6xZ8mU1h1uNQ3K/mAke23VOTVmE8cuhBxhGO+vNJlXks4n tspMBTi5EQtA95zyLZKt9SZZ/WkOKi6W+40EuWKR2V65hqOr/VAX4LC+zEzkebYrY7Cj gH5Mkm7hER6VWnSFtNmWN8ch9maQcfYobvzPPjnSYC1VEannXHbb3SM9eQGbLaBT9Tdz PhXA== X-Gm-Message-State: AOJu0Yy0h5t7eix7P6hbRiHO2VU7e97VUNe0pIRjHvnO5qLItODrRVFX UWFaTJKDIGV6vWobRBgdUiF/je+c/gUeq8DWKZjqzn9oJ3iGgZSyxCtW2NTq X-Google-Smtp-Source: AGHT+IEVcsPiRuvL5bvmikx0id0iadoFZ6YVarFayjjyUpT8tlylqJX3NjBWqOYaq4FzWr7D7zrPRw== X-Received: by 2002:a05:6512:1594:b0:512:e535:d692 with SMTP id bp20-20020a056512159400b00512e535d692mr2030387lfb.0.1709651199256; Tue, 05 Mar 2024 07:06:39 -0800 (PST) Received: from mariano ([188.210.239.69]) by smtp.gmail.com with ESMTPSA id fj6-20020a1709069c8600b00a43af1ea069sm6087975ejc.118.2024.03.05.07.06.38 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Mar 2024 07:06:38 -0800 (PST) Received: by mariano (Postfix, from userid 1000) id A7831BFCDC; Tue, 5 Mar 2024 16:06:37 +0100 (CET) Date: Tue, 5 Mar 2024 16:06:37 +0100 From: Stefano Sabatini To: FFmpeg development discussions and patches Message-ID: Mail-Followup-To: FFmpeg development discussions and patches References: <20240305000033.10379-1-jamrial@gmail.com> <20240305000033.10379-3-jamrial@gmail.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20240305000033.10379-3-jamrial@gmail.com> User-Agent: Mutt/2.1.4 (2021-12-11) Subject: Re: [FFmpeg-devel] [PATCH 3/9 v3] fftools/ffprobe: add support for Stream Groups X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: On date Monday 2024-03-04 21:00:23 -0300, James Almer wrote: > Signed-off-by: James Almer > --- > Changelog | 1 + > doc/ffprobe.xsd | 1 + > fftools/ffprobe.c | 147 ++++++++++++++++-- > tests/ref/fate/cavs-demux | 2 +- > tests/ref/fate/ffprobe_compact | 2 +- > tests/ref/fate/ffprobe_csv | 2 +- > tests/ref/fate/ffprobe_default | 1 + > tests/ref/fate/ffprobe_flat | 1 + > tests/ref/fate/ffprobe_ini | 1 + > tests/ref/fate/ffprobe_json | 1 + > tests/ref/fate/ffprobe_xml | 2 +- > tests/ref/fate/ffprobe_xsd | 2 +- > tests/ref/fate/flv-demux | 2 +- > tests/ref/fate/gapless-mp3-side-data | 2 +- > .../ref/fate/mov-mp4-disposition-mpegts-remux | 3 + > tests/ref/fate/mov-mp4-ttml-dfxp | 3 + > tests/ref/fate/mov-mp4-ttml-stpp | 3 + > tests/ref/fate/oggopus-demux | 2 +- > tests/ref/fate/ts-demux | 2 +- > tests/ref/fate/ts-opus-demux | 2 +- > tests/ref/fate/ts-small-demux | 2 +- > tests/ref/fate/ts-timed-id3-demux | 2 +- still missing doc/ffprobe.texi updates > 22 files changed, 163 insertions(+), 23 deletions(-) > > diff --git a/Changelog b/Changelog > index f388d41b02..0ba3a77c08 100644 > --- a/Changelog > +++ b/Changelog > @@ -30,6 +30,7 @@ version : > - Change the default bitrate control method from VBR to CQP for QSV encoders. > - removed deprecated ffmpeg CLI options -psnr and -map_channel > - DVD-Video demuxer, powered by libdvdnav and libdvdread > +- ffprobe -show_stream_groups option > > > version 6.1: > diff --git a/doc/ffprobe.xsd b/doc/ffprobe.xsd > index 9490a20ce8..dc04ce7142 100644 > --- a/doc/ffprobe.xsd > +++ b/doc/ffprobe.xsd > @@ -337,6 +337,7 @@ > > > > + > > > > diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c > index 8390377159..ff05c4c1db 100644 > --- a/fftools/ffprobe.c > +++ b/fftools/ffprobe.c > @@ -112,8 +112,10 @@ static int do_show_format = 0; > static int do_show_frames = 0; > static int do_show_packets = 0; > static int do_show_programs = 0; > +static int do_show_stream_groups = 0; > static int do_show_streams = 0; > static int do_show_stream_disposition = 0; > +static int do_show_stream_group_disposition = 0; > static int do_show_data = 0; > static int do_show_program_version = 0; > static int do_show_library_versions = 0; > @@ -126,6 +128,7 @@ static int do_show_chapter_tags = 0; > static int do_show_format_tags = 0; > static int do_show_frame_tags = 0; > static int do_show_program_tags = 0; > +static int do_show_stream_group_tags = 0; > static int do_show_stream_tags = 0; > static int do_show_packet_tags = 0; > > @@ -159,7 +162,7 @@ static int find_stream_info = 1; > > /* section structure definition */ > > -#define SECTION_MAX_NB_CHILDREN 10 > +#define SECTION_MAX_NB_CHILDREN 11 > > typedef enum { > SECTION_ID_NONE = -1, > @@ -203,6 +206,14 @@ typedef enum { > SECTION_ID_PROGRAM_TAGS, > SECTION_ID_PROGRAM_VERSION, > SECTION_ID_PROGRAMS, > + SECTION_ID_STREAM_GROUP_STREAM_DISPOSITION, > + SECTION_ID_STREAM_GROUP_STREAM_TAGS, > + SECTION_ID_STREAM_GROUP, > + SECTION_ID_STREAM_GROUP_STREAMS, > + SECTION_ID_STREAM_GROUP_STREAM, > + SECTION_ID_STREAM_GROUP_DISPOSITION, > + SECTION_ID_STREAM_GROUP_TAGS, > + SECTION_ID_STREAM_GROUPS, > SECTION_ID_ROOT, > SECTION_ID_STREAM, > SECTION_ID_STREAM_DISPOSITION, > @@ -249,6 +260,12 @@ static const char *get_raw_string_type(const void *data) > return data; > } > > +static const char *get_stream_group_type(const void *data) > +{ > + const AVStreamGroup *stg = (const AVStreamGroup *)data; > + return av_x_if_null(avformat_stream_group_name(stg->type), "unknown"); > +} > + > static struct section sections[] = { > [SECTION_ID_CHAPTERS] = { SECTION_ID_CHAPTERS, "chapters", SECTION_FLAG_IS_ARRAY, { SECTION_ID_CHAPTER, -1 } }, > [SECTION_ID_CHAPTER] = { SECTION_ID_CHAPTER, "chapter", 0, { SECTION_ID_CHAPTER_TAGS, -1 } }, > @@ -290,8 +307,16 @@ static struct section sections[] = { > [SECTION_ID_PROGRAM_TAGS] = { SECTION_ID_PROGRAM_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "program_tags" }, > [SECTION_ID_PROGRAM_VERSION] = { SECTION_ID_PROGRAM_VERSION, "program_version", 0, { -1 } }, > [SECTION_ID_PROGRAMS] = { SECTION_ID_PROGRAMS, "programs", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PROGRAM, -1 } }, > + [SECTION_ID_STREAM_GROUP_STREAM_DISPOSITION] = { SECTION_ID_STREAM_GROUP_STREAM_DISPOSITION, "disposition", 0, { -1 }, .unique_name = "stream_group_stream_disposition" }, > + [SECTION_ID_STREAM_GROUP_STREAM_TAGS] = { SECTION_ID_STREAM_GROUP_STREAM_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "stream_group_stream_tags" }, > + [SECTION_ID_STREAM_GROUP] = { SECTION_ID_STREAM_GROUP, "stream_group", SECTION_FLAG_HAS_TYPE, { SECTION_ID_STREAM_GROUP_TAGS, SECTION_ID_STREAM_GROUP_DISPOSITION, SECTION_ID_STREAM_GROUP_STREAMS, -1 }, .get_type = get_stream_group_type }, > + [SECTION_ID_STREAM_GROUP_STREAMS] = { SECTION_ID_STREAM_GROUP_STREAMS, "streams", SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM_GROUP_STREAM, -1 }, .unique_name = "stream_group_streams" }, > + [SECTION_ID_STREAM_GROUP_STREAM] = { SECTION_ID_STREAM_GROUP_STREAM, "stream", 0, { SECTION_ID_STREAM_GROUP_STREAM_DISPOSITION, SECTION_ID_STREAM_GROUP_STREAM_TAGS, -1 }, .unique_name = "stream_group_stream" }, > + [SECTION_ID_STREAM_GROUP_DISPOSITION] = { SECTION_ID_STREAM_GROUP_DISPOSITION, "disposition", 0, { -1 }, .unique_name = "stream_group_disposition" }, > + [SECTION_ID_STREAM_GROUP_TAGS] = { SECTION_ID_STREAM_GROUP_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "stream_group_tags" }, > + [SECTION_ID_STREAM_GROUPS] = { SECTION_ID_STREAM_GROUPS, "stream_groups", SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM_GROUP, -1 } }, > [SECTION_ID_ROOT] = { SECTION_ID_ROOT, "root", SECTION_FLAG_IS_WRAPPER, > - { SECTION_ID_CHAPTERS, SECTION_ID_FORMAT, SECTION_ID_FRAMES, SECTION_ID_PROGRAMS, SECTION_ID_STREAMS, > + { SECTION_ID_CHAPTERS, SECTION_ID_FORMAT, SECTION_ID_FRAMES, SECTION_ID_PROGRAMS, SECTION_ID_STREAM_GROUPS, SECTION_ID_STREAMS, > SECTION_ID_PACKETS, SECTION_ID_ERROR, SECTION_ID_PROGRAM_VERSION, SECTION_ID_LIBRARY_VERSIONS, > SECTION_ID_PIXEL_FORMATS, -1} }, > [SECTION_ID_STREAMS] = { SECTION_ID_STREAMS, "streams", SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM, -1 } }, > @@ -3071,7 +3096,10 @@ static void print_dispositions(WriterContext *w, uint32_t disposition, SectionID > writer_print_section_footer(w); > } > > -static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_idx, InputStream *ist, int in_program) > +#define IN_PROGRAM 1 > +#define IN_STREAM_GROUP 2 > + > +static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_idx, InputStream *ist, int container) > { > AVStream *stream = ist->st; > AVCodecParameters *par; > @@ -3081,12 +3109,29 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id > AVRational sar, dar; > AVBPrint pbuf; > const AVCodecDescriptor *cd; > + const SectionID section_header[] = { > + SECTION_ID_STREAM, > + SECTION_ID_PROGRAM_STREAM, > + SECTION_ID_STREAM_GROUP_STREAM, > + }; > + const SectionID section_disposition[] = { > + SECTION_ID_STREAM_DISPOSITION, > + SECTION_ID_PROGRAM_STREAM_DISPOSITION, > + SECTION_ID_STREAM_GROUP_STREAM_DISPOSITION, > + }; > + const SectionID section_tags[] = { > + SECTION_ID_STREAM_TAGS, > + SECTION_ID_PROGRAM_STREAM_TAGS, > + SECTION_ID_STREAM_GROUP_STREAM_TAGS, > + }; > int ret = 0; > const char *profile = NULL; > > + av_assert0(container < FF_ARRAY_ELEMS(section_header)); > + > av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED); > > - writer_print_section_header(w, NULL, in_program ? SECTION_ID_PROGRAM_STREAM : SECTION_ID_STREAM); > + writer_print_section_header(w, NULL, section_header[container]); > > print_int("index", stream->index); > > @@ -3248,13 +3293,14 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id > > /* Print disposition information */ > if (do_show_stream_disposition) { > - print_dispositions(w, stream->disposition, > - in_program ? SECTION_ID_PROGRAM_STREAM_DISPOSITION > - : SECTION_ID_STREAM_DISPOSITION); > + av_assert0(container < FF_ARRAY_ELEMS(section_disposition)); > + print_dispositions(w, stream->disposition, section_disposition[container]); > } > > - if (do_show_stream_tags) > - ret = show_tags(w, stream->metadata, in_program ? SECTION_ID_PROGRAM_STREAM_TAGS : SECTION_ID_STREAM_TAGS); > + if (do_show_stream_tags) { > + av_assert0(container < FF_ARRAY_ELEMS(section_tags)); > + ret = show_tags(w, stream->metadata, section_tags[container]); > + } > > if (stream->codecpar->nb_coded_side_data) { > writer_print_section_header(w, NULL, SECTION_ID_STREAM_SIDE_DATA_LIST); > @@ -3309,7 +3355,7 @@ static int show_program(WriterContext *w, InputFile *ifile, AVProgram *program) > writer_print_section_header(w, NULL, SECTION_ID_PROGRAM_STREAMS); > for (i = 0; i < program->nb_stream_indexes; i++) { > if (selected_streams[program->stream_index[i]]) { > - ret = show_stream(w, fmt_ctx, program->stream_index[i], &ifile->streams[program->stream_index[i]], 1); > + ret = show_stream(w, fmt_ctx, program->stream_index[i], &ifile->streams[program->stream_index[i]], IN_PROGRAM); > if (ret < 0) > break; > } > @@ -3339,6 +3385,72 @@ static int show_programs(WriterContext *w, InputFile *ifile) > return ret; > } > > +static void print_stream_group_params(WriterContext *w, AVStreamGroup *stg) > +{ > + const char *unknown = "unknown"; > + if (stg->type != AV_STREAM_GROUP_PARAMS_NONE) > + print_str("type", av_x_if_null(avformat_stream_group_name(stg->type), unknown)); > + else > + print_str_opt("type", unknown); > +} > + > +static int show_stream_group(WriterContext *w, InputFile *ifile, AVStreamGroup *stg) > +{ > + AVFormatContext *fmt_ctx = ifile->fmt_ctx; > + AVBPrint pbuf; > + int i, ret = 0; > + > + av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED); > + writer_print_section_header(w, stg, SECTION_ID_STREAM_GROUP); > + print_int("index", stg->index); > + if (fmt_ctx->iformat->flags & AVFMT_SHOW_IDS) print_fmt ("id", "0x%"PRIx64, stg->id); > + else print_str_opt("id", "N/A"); > + print_int("nb_streams", stg->nb_streams); > + print_stream_group_params(w, stg); > + > + /* Print disposition information */ > + if (do_show_stream_group_disposition) > + print_dispositions(w, stg->disposition, SECTION_ID_STREAM_GROUP_DISPOSITION); > + > + if (do_show_stream_group_tags) > + ret = show_tags(w, stg->metadata, SECTION_ID_STREAM_GROUP_TAGS); > + if (ret < 0) > + goto end; > + > + writer_print_section_header(w, NULL, SECTION_ID_STREAM_GROUP_STREAMS); > + for (i = 0; i < stg->nb_streams; i++) { > + if (selected_streams[stg->streams[i]->index]) { > + ret = show_stream(w, fmt_ctx, stg->streams[i]->index, &ifile->streams[stg->streams[i]->index], IN_STREAM_GROUP); > + if (ret < 0) > + break; > + } > + } > + writer_print_section_footer(w); > + > +end: > + av_bprint_finalize(&pbuf, NULL); > + writer_print_section_footer(w); > + return ret; > +} > + > +static int show_stream_groups(WriterContext *w, InputFile *ifile) > +{ > + AVFormatContext *fmt_ctx = ifile->fmt_ctx; > + int i, ret = 0; > + > + writer_print_section_header(w, NULL, SECTION_ID_STREAM_GROUPS); > + for (i = 0; i < fmt_ctx->nb_stream_groups; i++) { > + AVStreamGroup *stg = fmt_ctx->stream_groups[i]; > + if (!stg) > + continue; why can this be NULL? (this sounds a bit unexpected to me) [...] LGTM otherwise, thanks. _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".