Browse Source

fftools/ffprobe: add support for Stream Groups

Reviewed-by: Stefano Sabatini <stefasab@gmail.com>
Signed-off-by: James Almer <jamrial@gmail.com>
James Almer 1 year ago
parent
commit
7e4334e16a

+ 1 - 0
Changelog

@@ -30,6 +30,7 @@ version <next>:
 - 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:

+ 12 - 4
doc/ffprobe.texi

@@ -48,8 +48,8 @@ name (which may be shared by other sections), and an unique
 name. See the output of @option{sections}.
 
 Metadata tags stored in the container or in the streams are recognized
-and printed in the corresponding "FORMAT", "STREAM" or "PROGRAM_STREAM"
-section.
+and printed in the corresponding "FORMAT", "STREAM", "STREAM_GROUP_STREAM"
+or "PROGRAM_STREAM" section.
 
 @c man end
 
@@ -232,6 +232,13 @@ multimedia stream.
 Each media stream information is printed within a dedicated section
 with name "PROGRAM_STREAM".
 
+@item -show_stream_groups
+Show information about stream groups and their streams contained in the
+input multimedia stream.
+
+Each media stream information is printed within a dedicated section
+with name "STREAM_GROUP_STREAM".
+
 @item -show_chapters
 Show information about chapters stored in the format.
 
@@ -415,8 +422,9 @@ keyN=valN
 [/SECTION]
 @end example
 
-Metadata tags are printed as a line in the corresponding FORMAT, STREAM or
-PROGRAM_STREAM section, and are prefixed by the string "TAG:".
+Metadata tags are printed as a line in the corresponding FORMAT, STREAM,
+STREAM_GROUP_STREAM or PROGRAM_STREAM section, and are prefixed by the
+string "TAG:".
 
 A description of the accepted options follows.
 

+ 1 - 0
doc/ffprobe.xsd

@@ -337,6 +337,7 @@
     <xsd:attribute name="filename"         type="xsd:string" use="required"/>
     <xsd:attribute name="nb_streams"       type="xsd:int"    use="required"/>
     <xsd:attribute name="nb_programs"      type="xsd:int"    use="required"/>
+    <xsd:attribute name="nb_stream_groups" type="xsd:int"    use="required"/>
     <xsd:attribute name="format_name"      type="xsd:string" use="required"/>
     <xsd:attribute name="format_long_name" type="xsd:string"/>
     <xsd:attribute name="start_time"       type="xsd:float"/>

+ 135 - 11
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,71 @@ 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];
+
+        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;
@@ -3375,6 +3486,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);
@@ -3600,6 +3712,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;
@@ -4098,6 +4215,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
@@ -4128,6 +4246,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" },
@@ -4212,16 +4331,21 @@ 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_GROUP_DISPOSITION, stream_group_disposition);
+    SET_DO_SHOW(STREAM_GROUPS, stream_groups);
     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(PROGRAM_STREAM_TAGS, stream_tags);
+    SET_DO_SHOW(STREAM_GROUP_STREAM_TAGS, stream_tags);
     SET_DO_SHOW(PACKET_TAGS, packet_tags);
 
     if (do_bitexact && (do_show_program_version || do_show_library_versions)) {
@@ -4286,7 +4410,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");

+ 1 - 1
tests/ref/fate/cavs-demux

@@ -59,4 +59,4 @@ packet|codec_type=video|stream_index=0|pts=2320000|pts_time=1.933333|dts=2320000
 packet|codec_type=video|stream_index=0|pts=2360000|pts_time=1.966667|dts=2360000|dts_time=1.966667|duration=40000|duration_time=0.033333|size=83|pos=172252|flags=K__|data_hash=CRC32:a941bdf0
 packet|codec_type=video|stream_index=0|pts=2400000|pts_time=2.000000|dts=2400000|dts_time=2.000000|duration=40000|duration_time=0.033333|size=5417|pos=172335|flags=K__|data_hash=CRC32:9d0d503b
 stream|index=0|codec_name=cavs|profile=unknown|codec_type=video|codec_tag_string=[0][0][0][0]|codec_tag=0x0000|width=1280|height=720|coded_width=1280|coded_height=720|closed_captions=0|film_grain=0|has_b_frames=0|sample_aspect_ratio=N/A|display_aspect_ratio=N/A|pix_fmt=yuv420p|level=-99|color_range=unknown|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=unspecified|field_order=unknown|refs=1|id=N/A|r_frame_rate=30/1|avg_frame_rate=25/1|time_base=1/1200000|start_pts=N/A|start_time=N/A|duration_ts=N/A|duration=N/A|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=N/A|nb_read_packets=60|extradata_size=18|extradata_hash=CRC32:1255d52e|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|disposition:non_diegetic=0|disposition:captions=0|disposition:descriptions=0|disposition:metadata=0|disposition:dependent=0|disposition:still_image=0
-format|filename=bunny.mp4|nb_streams=1|nb_programs=0|format_name=cavsvideo|start_time=N/A|duration=N/A|size=177752|bit_rate=N/A|probe_score=51
+format|filename=bunny.mp4|nb_streams=1|nb_programs=0|nb_stream_groups=0|format_name=cavsvideo|start_time=N/A|duration=N/A|size=177752|bit_rate=N/A|probe_score=51

+ 1 - 1
tests/ref/fate/ffprobe_compact

@@ -29,4 +29,4 @@ frame|media_type=video|stream_index=2|key_frame=1|pts=6144|pts_time=0.120000|pkt
 stream|index=0|codec_name=pcm_s16le|profile=unknown|codec_type=audio|codec_tag_string=PSD[16]|codec_tag=0x10445350|sample_fmt=s16|sample_rate=44100|channels=1|channel_layout=unknown|bits_per_sample=16|initial_padding=0|id=N/A|r_frame_rate=0/0|avg_frame_rate=0/0|time_base=1/44100|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=705600|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=6|nb_read_packets=6|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|disposition:non_diegetic=0|disposition:captions=0|disposition:descriptions=0|disposition:metadata=0|disposition:dependent=0|disposition:still_image=0|tag:E=mc²|tag:encoder=Lavc pcm_s16le
 stream|index=1|codec_name=rawvideo|profile=unknown|codec_type=video|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=320|height=240|coded_width=320|coded_height=240|closed_captions=0|film_grain=0|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=4:3|pix_fmt=rgb24|level=-99|color_range=unknown|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=unspecified|field_order=unknown|refs=1|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=1|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|disposition:non_diegetic=0|disposition:captions=0|disposition:descriptions=0|disposition:metadata=0|disposition:dependent=0|disposition:still_image=0|tag:title=foobar|tag:duration_ts=field-and-tags-conflict-attempt|tag:encoder=Lavc rawvideo
 stream|index=2|codec_name=rawvideo|profile=unknown|codec_type=video|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=100|height=100|coded_width=100|coded_height=100|closed_captions=0|film_grain=0|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=1:1|pix_fmt=rgb24|level=-99|color_range=unknown|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=unspecified|field_order=unknown|refs=1|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|disposition:non_diegetic=0|disposition:captions=0|disposition:descriptions=0|disposition:metadata=0|disposition:dependent=0|disposition:still_image=0|tag:encoder=Lavc rawvideo
-format|filename=tests/data/ffprobe-test.nut|nb_streams=3|nb_programs=0|format_name=nut|start_time=0.000000|duration=0.120000|size=1053646|bit_rate=70243066|probe_score=100|tag:title=ffprobe test file|tag:comment='A comment with CSV, XML & JSON special chars': <tag value="x">|tag:comment2=I ♥ Üñîçød€
+format|filename=tests/data/ffprobe-test.nut|nb_streams=3|nb_programs=0|nb_stream_groups=0|format_name=nut|start_time=0.000000|duration=0.120000|size=1053646|bit_rate=70243066|probe_score=100|tag:title=ffprobe test file|tag:comment='A comment with CSV, XML & JSON special chars': <tag value="x">|tag:comment2=I ♥ Üñîçød€

+ 1 - 1
tests/ref/fate/ffprobe_csv

@@ -29,4 +29,4 @@ frame,video,2,1,6144,0.120000,6144,0.120000,6144,0.120000,2048,0.040000,2048,0.0
 stream,0,pcm_s16le,unknown,audio,PSD[16],0x10445350,s16,44100,1,unknown,16,0,N/A,0/0,0/0,1/44100,0,0.000000,N/A,N/A,705600,N/A,N/A,N/A,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,mc²,Lavc pcm_s16le
 stream,1,rawvideo,unknown,video,RGB[24],0x18424752,320,240,320,240,0,0,0,1:1,4:3,rgb24,-99,unknown,unknown,unknown,unknown,unspecified,unknown,1,N/A,25/1,25/1,1/51200,0,0.000000,N/A,N/A,N/A,N/A,N/A,N/A,4,4,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,foobar,field-and-tags-conflict-attempt,Lavc rawvideo
 stream,2,rawvideo,unknown,video,RGB[24],0x18424752,100,100,100,100,0,0,0,1:1,1:1,rgb24,-99,unknown,unknown,unknown,unknown,unspecified,unknown,1,N/A,25/1,25/1,1/51200,0,0.000000,N/A,N/A,N/A,N/A,N/A,N/A,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,Lavc rawvideo
-format,tests/data/ffprobe-test.nut,3,0,nut,0.000000,0.120000,1053646,70243066,100,ffprobe test file,"'A comment with CSV, XML & JSON special chars': <tag value=""x"">",I ♥ Üñîçød€
+format,tests/data/ffprobe-test.nut,3,0,0,nut,0.000000,0.120000,1053646,70243066,100,ffprobe test file,"'A comment with CSV, XML & JSON special chars': <tag value=""x"">",I ♥ Üñîçød€

+ 1 - 0
tests/ref/fate/ffprobe_default

@@ -766,6 +766,7 @@ TAG:encoder=Lavc rawvideo
 filename=tests/data/ffprobe-test.nut
 nb_streams=3
 nb_programs=0
+nb_stream_groups=0
 format_name=nut
 start_time=0.000000
 duration=0.120000

+ 1 - 0
tests/ref/fate/ffprobe_flat

@@ -703,6 +703,7 @@ streams.stream.2.tags.encoder="Lavc rawvideo"
 format.filename="tests/data/ffprobe-test.nut"
 format.nb_streams=3
 format.nb_programs=0
+format.nb_stream_groups=0
 format.format_name="nut"
 format.start_time="0.000000"
 format.duration="0.120000"

+ 1 - 0
tests/ref/fate/ffprobe_ini

@@ -780,6 +780,7 @@ encoder=Lavc rawvideo
 filename=tests/data/ffprobe-test.nut
 nb_streams=3
 nb_programs=0
+nb_stream_groups=0
 format_name=nut
 start_time=0.000000
 duration=0.120000

Some files were not shown because too many files changed in this diff