From patchwork Sat Mar 2 19:03:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 46705 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:a919:b0:19e:cdac:8cce with SMTP id cd25csp1992509pzb; Sat, 2 Mar 2024 11:03:39 -0800 (PST) X-Forwarded-Encrypted: i=2; AJvYcCXnLixB4oLOcXYSubg8qNXU6PwhMDyT/uapKgeGgkyjfJhuOG6OetG+6MPkRIj8ax6W+jgSznL284YNI7+dOZFBjkY3TlGfAEtPNw== X-Google-Smtp-Source: AGHT+IGpKJ4Kti19ZiSKY76uPRRX1lhZO4+BigmjP64gfJbrc5yshNB6Cgsd9DCyeGLhg12Fm88b X-Received: by 2002:a2e:9d03:0:b0:2d2:50bc:99d6 with SMTP id t3-20020a2e9d03000000b002d250bc99d6mr3344456lji.35.1709406219049; Sat, 02 Mar 2024 11:03:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1709406219; cv=none; d=google.com; s=arc-20160816; b=dzxdrB6mZxqUGHB3PnwCcbBGfQHIda32hw22Ey2H5RuRBTCWL99vzR9hEOP8DjqVAZ IWfjYQ+h2EF5IJo61YpEVlb+EcI/i+Ifhx9NCpkXzYPI61vXxD+k+rS23mtPXEP6jyiO ywR3TmoLVSlGCA2gEIRsgKE9IeDM/6yK6tyfZvPqg2mIvtIvSdpolsRleEGcWAGrG/zf 0geDw+eSqk91jxGUZX44l7sWgerLIeO9s/PGrVAAYYTfFRtjnYhI8j4MZ6AfjDnO4VWG lxN77UJJUplvoC95M7ayBjbysMI9QCOj2rYW8vgj/3LIDJqrzM5DafgDq7xM4pDRZkxH T0FQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:message-id:date:to:from :dkim-signature:delivered-to; bh=FvveZq8jIwDgnWnHsIVnIHejNSYX90PFgoeIUPq01Uw=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=Mnm3RNjtWXX/L5QehfShHbPcDQd02+nn6CVRBB+pKX8Ig/bZR1JqvOXznhxuibJz70 +3hqhJwZ5LuvS2IoaoIAf4YBpbRi2xuoLcofvw/e3DJgMorI0lp3GNXhSgVqhm5wiQWO 3yP2ubVLIOuxxGjM12PFQZM3u5EFP8r4RbQ1TgtNOqFimPtOGr9oJ2gDmFyyKhI7RV8a vrTkpHq4RtuwzSWhcZOl76vNKGtWUlxCMVd1KHa0+D+jW1MJ8jc5EMJcSBPSxSGKu22z VCAb6nqgV8FrLzf7p4jHO0MvFqroUapnKu8pJiFYz7IZxy2NDgM9D/9QZFdrJFds2uoT LGqw==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20230601 header.b=itTBLK8u; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id j17-20020a508a91000000b00566fad920bcsi994889edj.592.2024.03.02.11.03.38; Sat, 02 Mar 2024 11:03:39 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20230601 header.b=itTBLK8u; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 5509E68D2F3; Sat, 2 Mar 2024 21:03:36 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pl1-f175.google.com (mail-pl1-f175.google.com [209.85.214.175]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 14C2B68CFEF for ; Sat, 2 Mar 2024 21:03:30 +0200 (EET) Received: by mail-pl1-f175.google.com with SMTP id d9443c01a7336-1dc29f1956cso27591825ad.0 for ; Sat, 02 Mar 2024 11:03:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1709406207; x=1710011007; darn=ffmpeg.org; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:from:to:cc:subject:date:message-id:reply-to; bh=rMiUpNpBjjfcGWTDUryd2CBnHUp2qojRETEBPrqRJoc=; b=itTBLK8ueIk4Q400ia+Eq/9GZXWwDofkmM09S++7JbfZATMP5S0KY5Kj/TufWtL9yL 3ERTIlxPLUHtcVehSP3XRlukxQo/B5oMA5gL20O9DlA2ezYOd+pmR/xHfE3D5aijJgGm efTD6yJlJCPXxfJ18pU+hCBW4cpfy0QuDtfhxWLt0xlj4TstQs4B4++RoM5WO+oJ9UDR oIiKjdn4RcBZ5rBqf+t++p1KbznlRmfofMDpmIdQiMsch+r03vd1kE8Hr0ZaOl3kG1yT 4oZC2AA27xHDFgCIfAN1hXLI1aN8R9YO+psIXBNe5y8ege/CaAazIis5Qq14JEmRezun 6qqw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709406207; x=1710011007; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=rMiUpNpBjjfcGWTDUryd2CBnHUp2qojRETEBPrqRJoc=; b=E4RIxgzEvxVVUv9ZVHnarCfmdiedsb+wyM5K7QZ2I3xIaZPVSTXA45w9ShEZUlzaOb vRdncrLWTe2cTk8k6tag35z3cTifSszgXC9V/112AUHHLs+3i80ri7X3m7FlaxGttTUs eb70wHhTVDdhyMc1Jn+EMJ4cxme/x4SX+D/OE2Auk6Cs7FSlTIX2oEorUkxJP+pcfBGK m/LeTmPcCUK1TzEbBHNPfNMyl9eagwUjvFvzshQ35AUXPnZ1XAPkec/d/3fBnv7Eh3sO cjEfPzlRZmLtw/aIZqsWjHG+Ol6xnHR4Xp6XdOotHTC9tM2ZSQdpb4VncdpkGeGC64zj PU9w== X-Gm-Message-State: AOJu0YzlEJpwd/Vk+h1YVF9/uKgN+3eDVGUEutFiyPDpwlEl522xCVU7 rq3PTC+y2q4xN0uAg4doOHXfxHejp/NWjif2C1JrTpFVu1e7s0tf5Vj7bi91 X-Received: by 2002:a17:903:2444:b0:1db:55cc:d226 with SMTP id l4-20020a170903244400b001db55ccd226mr6446230pls.66.1709406207150; Sat, 02 Mar 2024 11:03:27 -0800 (PST) Received: from localhost.localdomain ([190.194.169.124]) by smtp.gmail.com with ESMTPSA id w22-20020a1709026f1600b001dcdfb6184asm4886303plk.79.2024.03.02.11.03.25 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 02 Mar 2024 11:03:26 -0800 (PST) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Sat, 2 Mar 2024 16:03:20 -0300 Message-ID: <20240302190321.1851-1-jamrial@gmail.com> X-Mailer: git-send-email 2.44.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/2] 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: PLBJ4j7nH3/a Signed-off-by: James Almer --- fftools/ffprobe.c | 186 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 157 insertions(+), 29 deletions(-) diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index ea225f14ab..ec3c713849 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, @@ -210,6 +213,14 @@ typedef enum { SECTION_ID_STREAM_TAGS, SECTION_ID_STREAM_SIDE_DATA_LIST, SECTION_ID_STREAM_SIDE_DATA, + 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_SUBTITLE, } SectionID; @@ -286,7 +297,7 @@ static struct section sections[] = { [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_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 } }, @@ -295,6 +306,14 @@ static struct section sections[] = { [SECTION_ID_STREAM_TAGS] = { SECTION_ID_STREAM_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "stream_tags" }, [SECTION_ID_STREAM_SIDE_DATA_LIST] ={ SECTION_ID_STREAM_SIDE_DATA_LIST, "side_data_list", SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM_SIDE_DATA, -1 }, .element_name = "side_data", .unique_name = "stream_side_data_list" }, [SECTION_ID_STREAM_SIDE_DATA] = { SECTION_ID_STREAM_SIDE_DATA, "side_data", SECTION_FLAG_HAS_TYPE|SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .unique_name = "stream_side_data", .element_name = "side_datum", .get_type = get_packet_side_data_type }, + [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", 0, { SECTION_ID_STREAM_GROUP_TAGS, SECTION_ID_STREAM_GROUP_DISPOSITION, SECTION_ID_STREAM_GROUP_STREAMS, -1 } }, + [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_SUBTITLE] = { SECTION_ID_SUBTITLE, "subtitle", 0, { -1 } }, }; @@ -3039,7 +3058,8 @@ static int read_packets(WriterContext *w, InputFile *ifile) return ret; } -static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_idx, InputStream *ist, int in_program) +static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_idx, InputStream *ist, + int in_program, int in_group) { AVStream *stream = ist->st; AVCodecParameters *par; @@ -3049,12 +3069,18 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id AVRational sar, dar; AVBPrint pbuf; const AVCodecDescriptor *cd; + SectionID section_header = in_program ? SECTION_ID_PROGRAM_STREAM : + (in_group ? SECTION_ID_STREAM_GROUP_STREAM : SECTION_ID_STREAM); + SectionID section_disposition = in_program ? SECTION_ID_PROGRAM_STREAM_DISPOSITION : + (in_group ? SECTION_ID_STREAM_GROUP_STREAM_DISPOSITION : SECTION_ID_STREAM_DISPOSITION); + SectionID section_tags = in_program ? SECTION_ID_PROGRAM_STREAM_TAGS : + (in_group ? SECTION_ID_STREAM_GROUP_STREAM_TAGS : SECTION_ID_STREAM_TAGS); int ret = 0; const char *profile = NULL; 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); print_int("index", stream->index); @@ -3215,35 +3241,35 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id } /* Print disposition information */ -#define PRINT_DISPOSITION(flagname, name) do { \ - print_int(name, !!(stream->disposition & AV_DISPOSITION_##flagname)); \ +#define PRINT_DISPOSITION(flagname, ctx, name) do { \ + print_int(name, !!(ctx->disposition & AV_DISPOSITION_##flagname)); \ } while (0) if (do_show_stream_disposition) { - writer_print_section_header(w, NULL, in_program ? SECTION_ID_PROGRAM_STREAM_DISPOSITION : SECTION_ID_STREAM_DISPOSITION); - PRINT_DISPOSITION(DEFAULT, "default"); - PRINT_DISPOSITION(DUB, "dub"); - PRINT_DISPOSITION(ORIGINAL, "original"); - PRINT_DISPOSITION(COMMENT, "comment"); - PRINT_DISPOSITION(LYRICS, "lyrics"); - PRINT_DISPOSITION(KARAOKE, "karaoke"); - PRINT_DISPOSITION(FORCED, "forced"); - PRINT_DISPOSITION(HEARING_IMPAIRED, "hearing_impaired"); - PRINT_DISPOSITION(VISUAL_IMPAIRED, "visual_impaired"); - PRINT_DISPOSITION(CLEAN_EFFECTS, "clean_effects"); - PRINT_DISPOSITION(ATTACHED_PIC, "attached_pic"); - PRINT_DISPOSITION(TIMED_THUMBNAILS, "timed_thumbnails"); - PRINT_DISPOSITION(NON_DIEGETIC, "non_diegetic"); - PRINT_DISPOSITION(CAPTIONS, "captions"); - PRINT_DISPOSITION(DESCRIPTIONS, "descriptions"); - PRINT_DISPOSITION(METADATA, "metadata"); - PRINT_DISPOSITION(DEPENDENT, "dependent"); - PRINT_DISPOSITION(STILL_IMAGE, "still_image"); + writer_print_section_header(w, NULL, section_disposition); + PRINT_DISPOSITION(DEFAULT, stream, "default"); + PRINT_DISPOSITION(DUB, stream, "dub"); + PRINT_DISPOSITION(ORIGINAL, stream, "original"); + PRINT_DISPOSITION(COMMENT, stream, "comment"); + PRINT_DISPOSITION(LYRICS, stream, "lyrics"); + PRINT_DISPOSITION(KARAOKE, stream, "karaoke"); + PRINT_DISPOSITION(FORCED, stream, "forced"); + PRINT_DISPOSITION(HEARING_IMPAIRED, stream, "hearing_impaired"); + PRINT_DISPOSITION(VISUAL_IMPAIRED, stream, "visual_impaired"); + PRINT_DISPOSITION(CLEAN_EFFECTS, stream, "clean_effects"); + PRINT_DISPOSITION(ATTACHED_PIC, stream, "attached_pic"); + PRINT_DISPOSITION(TIMED_THUMBNAILS, stream, "timed_thumbnails"); + PRINT_DISPOSITION(NON_DIEGETIC, stream, "non_diegetic"); + PRINT_DISPOSITION(CAPTIONS, stream, "captions"); + PRINT_DISPOSITION(DESCRIPTIONS, stream, "descriptions"); + PRINT_DISPOSITION(METADATA, stream, "metadata"); + PRINT_DISPOSITION(DEPENDENT, stream, "dependent"); + PRINT_DISPOSITION(STILL_IMAGE, stream, "still_image"); writer_print_section_footer(w); } if (do_show_stream_tags) - ret = show_tags(w, stream->metadata, in_program ? SECTION_ID_PROGRAM_STREAM_TAGS : SECTION_ID_STREAM_TAGS); + ret = show_tags(w, stream->metadata, section_tags); if (stream->codecpar->nb_coded_side_data) { writer_print_section_header(w, NULL, SECTION_ID_STREAM_SIDE_DATA_LIST); @@ -3270,7 +3296,7 @@ static int show_streams(WriterContext *w, InputFile *ifile) writer_print_section_header(w, NULL, SECTION_ID_STREAMS); for (i = 0; i < ifile->nb_streams; i++) if (selected_streams[i]) { - ret = show_stream(w, fmt_ctx, i, &ifile->streams[i], 0); + ret = show_stream(w, fmt_ctx, i, &ifile->streams[i], 0, 0); if (ret < 0) break; } @@ -3298,7 +3324,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]], 1, 0); if (ret < 0) break; } @@ -3328,6 +3354,95 @@ static int show_programs(WriterContext *w, InputFile *ifile) return ret; } + +static void print_stream_group_params(WriterContext *w, AVStreamGroup *stg) +{ + if (stg->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT) + print_str("type", "IAMF Audio Element"); + else if (stg->type == AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION) + print_str("type", "IAMF Mix Presentation"); + else if (stg->type == AV_STREAM_GROUP_PARAMS_TILE_GRID) { + print_str("type", "Tile Grid"); + } 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, NULL, 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); + + if (do_show_stream_group_disposition) { + writer_print_section_header(w, NULL, SECTION_ID_STREAM_GROUP_DISPOSITION); + PRINT_DISPOSITION(DEFAULT, stg, "default"); + PRINT_DISPOSITION(DUB, stg, "dub"); + PRINT_DISPOSITION(ORIGINAL, stg, "original"); + PRINT_DISPOSITION(COMMENT, stg, "comment"); + PRINT_DISPOSITION(LYRICS, stg, "lyrics"); + PRINT_DISPOSITION(KARAOKE, stg, "karaoke"); + PRINT_DISPOSITION(FORCED, stg, "forced"); + PRINT_DISPOSITION(HEARING_IMPAIRED, stg, "hearing_impaired"); + PRINT_DISPOSITION(VISUAL_IMPAIRED, stg, "visual_impaired"); + PRINT_DISPOSITION(CLEAN_EFFECTS, stg, "clean_effects"); + PRINT_DISPOSITION(ATTACHED_PIC, stg, "attached_pic"); + PRINT_DISPOSITION(TIMED_THUMBNAILS, stg, "timed_thumbnails"); + PRINT_DISPOSITION(NON_DIEGETIC, stg, "non_diegetic"); + PRINT_DISPOSITION(CAPTIONS, stg, "captions"); + PRINT_DISPOSITION(DESCRIPTIONS, stg, "descriptions"); + PRINT_DISPOSITION(METADATA, stg, "metadata"); + PRINT_DISPOSITION(DEPENDENT, stg, "dependent"); + PRINT_DISPOSITION(STILL_IMAGE, stg, "still_image"); + writer_print_section_footer(w); + } + + 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], 0, 1); + 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; + ret = show_stream_group(w, ifile, stg); + if (ret < 0) + break; + } + writer_print_section_footer(w); + return ret; +} + static int show_chapters(WriterContext *w, InputFile *ifile) { AVFormatContext *fmt_ctx = ifile->fmt_ctx; @@ -3364,6 +3479,7 @@ static int show_format(WriterContext *w, InputFile *ifile) print_str_validate("filename", fmt_ctx->url); print_int("nb_streams", fmt_ctx->nb_streams); print_int("nb_programs", fmt_ctx->nb_programs); + print_int("nb_stream_groups", fmt_ctx->nb_stream_groups); print_str("format_name", fmt_ctx->iformat->name); if (!do_bitexact) { if (fmt_ctx->iformat->long_name) print_str ("format_long_name", fmt_ctx->iformat->long_name); @@ -3589,6 +3705,11 @@ static int probe_file(WriterContext *wctx, const char *filename, CHECK_END; } + if (do_show_stream_groups) { + ret = show_stream_groups(wctx, &ifile); + CHECK_END; + } + if (do_show_streams) { ret = show_streams(wctx, &ifile); CHECK_END; @@ -4087,6 +4208,7 @@ DEFINE_OPT_SHOW_SECTION(pixel_formats, PIXEL_FORMATS) DEFINE_OPT_SHOW_SECTION(program_version, PROGRAM_VERSION) DEFINE_OPT_SHOW_SECTION(streams, STREAMS) DEFINE_OPT_SHOW_SECTION(programs, PROGRAMS) +DEFINE_OPT_SHOW_SECTION(stream_groups, STREAM_GROUPS) static const OptionDef real_options[] = { CMDUTILS_COMMON_OPTIONS @@ -4117,6 +4239,7 @@ static const OptionDef real_options[] = { #endif { "show_packets", OPT_TYPE_FUNC, 0, { .func_arg = &opt_show_packets }, "show packets info" }, { "show_programs", OPT_TYPE_FUNC, 0, { .func_arg = &opt_show_programs }, "show programs info" }, + { "show_stream_groups", OPT_TYPE_FUNC, 0, { .func_arg = &opt_show_stream_groups }, "show stream groups info" }, { "show_streams", OPT_TYPE_FUNC, 0, { .func_arg = &opt_show_streams }, "show streams info" }, { "show_chapters", OPT_TYPE_FUNC, 0, { .func_arg = &opt_show_chapters }, "show chapters info" }, { "count_frames", OPT_TYPE_BOOL, 0, { &do_count_frames }, "count the number of frames per stream" }, @@ -4201,15 +4324,20 @@ int main(int argc, char **argv) SET_DO_SHOW(PIXEL_FORMAT_COMPONENTS, pixel_format_components); SET_DO_SHOW(PROGRAM_VERSION, program_version); SET_DO_SHOW(PROGRAMS, programs); + SET_DO_SHOW(STREAM_GROUPS, stream_groups); + SET_DO_SHOW(STREAM_GROUP_DISPOSITION, stream_group_disposition); SET_DO_SHOW(STREAMS, streams); SET_DO_SHOW(STREAM_DISPOSITION, stream_disposition); SET_DO_SHOW(PROGRAM_STREAM_DISPOSITION, stream_disposition); + SET_DO_SHOW(STREAM_GROUP_STREAM_DISPOSITION, stream_disposition); SET_DO_SHOW(CHAPTER_TAGS, chapter_tags); SET_DO_SHOW(FORMAT_TAGS, format_tags); SET_DO_SHOW(FRAME_TAGS, frame_tags); SET_DO_SHOW(PROGRAM_TAGS, program_tags); + SET_DO_SHOW(STREAM_GROUP_TAGS, stream_group_tags); SET_DO_SHOW(STREAM_TAGS, stream_tags); + SET_DO_SHOW(STREAM_GROUP_STREAM_TAGS, stream_tags); SET_DO_SHOW(PROGRAM_STREAM_TAGS, stream_tags); SET_DO_SHOW(PACKET_TAGS, packet_tags); @@ -4275,7 +4403,7 @@ int main(int argc, char **argv) ffprobe_show_pixel_formats(wctx); if (!input_filename && - ((do_show_format || do_show_programs || do_show_streams || do_show_chapters || do_show_packets || do_show_error) || + ((do_show_format || do_show_programs || do_show_stream_groups || do_show_streams || do_show_chapters || do_show_packets || do_show_error) || (!do_show_program_version && !do_show_library_versions && !do_show_pixel_formats))) { show_usage(); av_log(NULL, AV_LOG_ERROR, "You have to specify one input file.\n");