Commit 8411f7b352 for ffmpeg

commit 8411f7b352ffac53cd61097f87afc4ebea25b4df
Author: James Almer <jamrial@gmail.com>
Date:   Sat Oct 10 12:21:19 2026 -0300

    fftools/ffprobe: differentiate between stream/group_stream/program_stream side data

    And fully implement printing all their components.

    Signed-off-by: James Almer <jamrial@gmail.com>

diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c
index dc5fab949a..4213cb7b2c 100644
--- a/fftools/ffprobe.c
+++ b/fftools/ffprobe.c
@@ -42,6 +42,7 @@
 #include "libavutil/downmix_info.h"
 #include "libavutil/display.h"
 #include "libavutil/film_grain_params.h"
+#include "libavutil/gain_map.h"
 #include "libavutil/hdr_dynamic_metadata.h"
 #include "libavutil/iamf.h"
 #include "libavutil/mastering_display_metadata.h"
@@ -190,6 +191,8 @@ typedef enum {
     SECTION_ID_PACKETS_AND_FRAMES,
     SECTION_ID_PACKET_SIDE_DATA_LIST,
     SECTION_ID_PACKET_SIDE_DATA,
+    SECTION_ID_PACKET_SIDE_DATA_COMPONENT_LIST,
+    SECTION_ID_PACKET_SIDE_DATA_COMPONENT,
     SECTION_ID_PIXEL_FORMAT,
     SECTION_ID_PIXEL_FORMAT_FLAGS,
     SECTION_ID_PIXEL_FORMAT_COMPONENT,
@@ -197,6 +200,10 @@ typedef enum {
     SECTION_ID_PIXEL_FORMATS,
     SECTION_ID_PROGRAM_STREAM_DISPOSITION,
     SECTION_ID_PROGRAM_STREAM_TAGS,
+    SECTION_ID_PROGRAM_STREAM_SIDE_DATA_LIST,
+    SECTION_ID_PROGRAM_STREAM_SIDE_DATA,
+    SECTION_ID_PROGRAM_STREAM_SIDE_DATA_COMPONENT_LIST,
+    SECTION_ID_PROGRAM_STREAM_SIDE_DATA_COMPONENT,
     SECTION_ID_PROGRAM,
     SECTION_ID_PROGRAM_STREAMS,
     SECTION_ID_PROGRAM_STREAM,
@@ -205,6 +212,10 @@ typedef enum {
     SECTION_ID_PROGRAMS,
     SECTION_ID_STREAM_GROUP_STREAM_DISPOSITION,
     SECTION_ID_STREAM_GROUP_STREAM_TAGS,
+    SECTION_ID_STREAM_GROUP_STREAM_SIDE_DATA_LIST,
+    SECTION_ID_STREAM_GROUP_STREAM_SIDE_DATA,
+    SECTION_ID_STREAM_GROUP_STREAM_SIDE_DATA_COMPONENT_LIST,
+    SECTION_ID_STREAM_GROUP_STREAM_SIDE_DATA_COMPONENT,
     SECTION_ID_STREAM_GROUP_STREAM_GROUP_DISPOSITION,
     SECTION_ID_STREAM_GROUP_STREAM_GROUP_TAGS,
     SECTION_ID_STREAM_GROUP,
@@ -220,6 +231,8 @@ typedef enum {
     SECTION_ID_STREAM_GROUP_BLOCK,
     SECTION_ID_STREAM_GROUP_SIDE_DATA_LIST,
     SECTION_ID_STREAM_GROUP_SIDE_DATA,
+    SECTION_ID_STREAM_GROUP_SIDE_DATA_COMPONENT_LIST,
+    SECTION_ID_STREAM_GROUP_SIDE_DATA_COMPONENT,
     SECTION_ID_STREAM_GROUP_STREAMS,
     SECTION_ID_STREAM_GROUP_STREAM,
     SECTION_ID_STREAM_GROUP_STREAM_GROUPS,
@@ -234,6 +247,8 @@ typedef enum {
     SECTION_ID_STREAM_TAGS,
     SECTION_ID_STREAM_SIDE_DATA_LIST,
     SECTION_ID_STREAM_SIDE_DATA,
+    SECTION_ID_STREAM_SIDE_DATA_COMPONENT_LIST,
+    SECTION_ID_STREAM_SIDE_DATA_COMPONENT,
     SECTION_ID_SUBTITLE,
 } SectionID;

@@ -287,7 +302,9 @@ static const AVTextFormatSection sections[] = {
     [SECTION_ID_PACKET] =             { SECTION_ID_PACKET, "packet", 0, { SECTION_ID_PACKET_TAGS, SECTION_ID_PACKET_SIDE_DATA_LIST, -1 } },
     [SECTION_ID_PACKET_TAGS] =        { SECTION_ID_PACKET_TAGS, "tags", AV_TEXTFORMAT_SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "packet_tags" },
     [SECTION_ID_PACKET_SIDE_DATA_LIST] ={ SECTION_ID_PACKET_SIDE_DATA_LIST, "side_data_list", AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY, { SECTION_ID_PACKET_SIDE_DATA, -1 }, .element_name = "side_data", .unique_name = "packet_side_data_list" },
-    [SECTION_ID_PACKET_SIDE_DATA] =     { SECTION_ID_PACKET_SIDE_DATA, "side_data", AV_TEXTFORMAT_SECTION_FLAG_HAS_VARIABLE_FIELDS|AV_TEXTFORMAT_SECTION_FLAG_HAS_TYPE, { -1 }, .unique_name = "packet_side_data", .element_name = "side_datum", .get_type = get_packet_side_data_type },
+    [SECTION_ID_PACKET_SIDE_DATA] =     { SECTION_ID_PACKET_SIDE_DATA, "side_data", AV_TEXTFORMAT_SECTION_FLAG_HAS_VARIABLE_FIELDS|AV_TEXTFORMAT_SECTION_FLAG_HAS_TYPE, { SECTION_ID_PACKET_SIDE_DATA_COMPONENT_LIST, -1 }, .unique_name = "packet_side_data", .element_name = "side_datum", .get_type = get_packet_side_data_type },
+    [SECTION_ID_PACKET_SIDE_DATA_COMPONENT_LIST] = { SECTION_ID_PACKET_SIDE_DATA_COMPONENT_LIST, "components", AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY, { SECTION_ID_PACKET_SIDE_DATA_COMPONENT, -1 }, .element_name = "component", .unique_name = "packet_side_data_components" },
+    [SECTION_ID_PACKET_SIDE_DATA_COMPONENT] =      { SECTION_ID_PACKET_SIDE_DATA_COMPONENT, "component", AV_TEXTFORMAT_SECTION_FLAG_HAS_VARIABLE_FIELDS|AV_TEXTFORMAT_SECTION_FLAG_HAS_TYPE, { -1 }, .unique_name = "packet_side_data_component", .element_name = "component_entry", .get_type = get_raw_string_type },
     [SECTION_ID_PIXEL_FORMATS] =      { SECTION_ID_PIXEL_FORMATS, "pixel_formats", AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY, { SECTION_ID_PIXEL_FORMAT, -1 } },
     [SECTION_ID_PIXEL_FORMAT] =       { SECTION_ID_PIXEL_FORMAT, "pixel_format", 0, { SECTION_ID_PIXEL_FORMAT_FLAGS, SECTION_ID_PIXEL_FORMAT_COMPONENTS, -1 } },
     [SECTION_ID_PIXEL_FORMAT_FLAGS] = { SECTION_ID_PIXEL_FORMAT_FLAGS, "flags", 0, { -1 }, .unique_name = "pixel_format_flags" },
@@ -295,9 +312,13 @@ static const AVTextFormatSection sections[] = {
     [SECTION_ID_PIXEL_FORMAT_COMPONENT]  = { SECTION_ID_PIXEL_FORMAT_COMPONENT, "component", 0, { -1 } },
     [SECTION_ID_PROGRAM_STREAM_DISPOSITION] = { SECTION_ID_PROGRAM_STREAM_DISPOSITION, "disposition", 0, { -1 }, .unique_name = "program_stream_disposition" },
     [SECTION_ID_PROGRAM_STREAM_TAGS] =        { SECTION_ID_PROGRAM_STREAM_TAGS, "tags", AV_TEXTFORMAT_SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "program_stream_tags" },
+    [SECTION_ID_PROGRAM_STREAM_SIDE_DATA_LIST] = { SECTION_ID_PROGRAM_STREAM_SIDE_DATA_LIST, "side_data_list", AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY, { SECTION_ID_PROGRAM_STREAM_SIDE_DATA, -1 }, .element_name = "side_data", .unique_name = "program_stream_side_data_list" },
+    [SECTION_ID_PROGRAM_STREAM_SIDE_DATA] =      { SECTION_ID_PROGRAM_STREAM_SIDE_DATA, "side_data", AV_TEXTFORMAT_SECTION_FLAG_HAS_TYPE|AV_TEXTFORMAT_SECTION_FLAG_HAS_VARIABLE_FIELDS, { SECTION_ID_PROGRAM_STREAM_SIDE_DATA_COMPONENT_LIST, -1 }, .unique_name = "program_stream_side_data", .element_name = "side_datum", .get_type = get_packet_side_data_type },
+    [SECTION_ID_PROGRAM_STREAM_SIDE_DATA_COMPONENT_LIST] = { SECTION_ID_PROGRAM_STREAM_SIDE_DATA_COMPONENT_LIST, "components", AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY, { SECTION_ID_PROGRAM_STREAM_SIDE_DATA_COMPONENT, -1 }, .element_name = "component", .unique_name = "program_stream_side_data_components" },
+    [SECTION_ID_PROGRAM_STREAM_SIDE_DATA_COMPONENT] =      { SECTION_ID_PROGRAM_STREAM_SIDE_DATA_COMPONENT, "component", AV_TEXTFORMAT_SECTION_FLAG_HAS_VARIABLE_FIELDS|AV_TEXTFORMAT_SECTION_FLAG_HAS_TYPE, { -1 }, .unique_name = "program_stream_side_data_component", .element_name = "component_entry", .get_type = get_raw_string_type },
     [SECTION_ID_PROGRAM] =                    { SECTION_ID_PROGRAM, "program", 0, { SECTION_ID_PROGRAM_TAGS, SECTION_ID_PROGRAM_STREAMS, -1 } },
     [SECTION_ID_PROGRAM_STREAMS] =            { SECTION_ID_PROGRAM_STREAMS, "streams", AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY, { SECTION_ID_PROGRAM_STREAM, -1 }, .unique_name = "program_streams" },
-    [SECTION_ID_PROGRAM_STREAM] =             { SECTION_ID_PROGRAM_STREAM, "stream", 0, { SECTION_ID_PROGRAM_STREAM_DISPOSITION, SECTION_ID_PROGRAM_STREAM_TAGS, -1 }, .unique_name = "program_stream" },
+    [SECTION_ID_PROGRAM_STREAM] =             { SECTION_ID_PROGRAM_STREAM, "stream", 0, { SECTION_ID_PROGRAM_STREAM_DISPOSITION, SECTION_ID_PROGRAM_STREAM_TAGS, SECTION_ID_PROGRAM_STREAM_SIDE_DATA_LIST, -1 }, .unique_name = "program_stream" },
     [SECTION_ID_PROGRAM_TAGS] =               { SECTION_ID_PROGRAM_TAGS, "tags", AV_TEXTFORMAT_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", AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY, { SECTION_ID_PROGRAM, -1 } },
@@ -305,9 +326,13 @@ static const AVTextFormatSection sections[] = {
     [SECTION_ID_STREAM_GROUP_STREAM_GROUP_TAGS] =  { SECTION_ID_STREAM_GROUP_STREAM_GROUP_TAGS, "tags", AV_TEXTFORMAT_SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "stream_group_stream_group_tags" },
     [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", AV_TEXTFORMAT_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_COMPONENTS, SECTION_ID_STREAM_GROUP_STREAMS, SECTION_ID_STREAM_GROUP_STREAM_GROUPS, -1 } },
+    [SECTION_ID_STREAM_GROUP_STREAM_SIDE_DATA_LIST] = { SECTION_ID_STREAM_GROUP_STREAM_SIDE_DATA_LIST, "side_data_list", AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM_GROUP_STREAM_SIDE_DATA, -1 }, .element_name = "side_data", .unique_name = "stream_group_stream_side_data_list" },
+    [SECTION_ID_STREAM_GROUP_STREAM_SIDE_DATA] =      { SECTION_ID_STREAM_GROUP_STREAM_SIDE_DATA, "side_data", AV_TEXTFORMAT_SECTION_FLAG_HAS_TYPE|AV_TEXTFORMAT_SECTION_FLAG_HAS_VARIABLE_FIELDS, { SECTION_ID_STREAM_GROUP_STREAM_SIDE_DATA_COMPONENT_LIST, -1 }, .unique_name = "stream_group_stream_side_data", .element_name = "side_datum", .get_type = get_packet_side_data_type },
+    [SECTION_ID_STREAM_GROUP_STREAM_SIDE_DATA_COMPONENT_LIST] = { SECTION_ID_STREAM_GROUP_STREAM_SIDE_DATA_COMPONENT_LIST, "components", AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM_GROUP_STREAM_SIDE_DATA_COMPONENT, -1 }, .element_name = "component", .unique_name = "stream_group_stream_side_data_components" },
+    [SECTION_ID_STREAM_GROUP_STREAM_SIDE_DATA_COMPONENT] =      { SECTION_ID_STREAM_GROUP_STREAM_SIDE_DATA_COMPONENT, "component", AV_TEXTFORMAT_SECTION_FLAG_HAS_VARIABLE_FIELDS|AV_TEXTFORMAT_SECTION_FLAG_HAS_TYPE, { -1 }, .unique_name = "stream_group_stream_side_data_component", .element_name = "component_entry", .get_type = get_raw_string_type },
+    [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_SIDE_DATA_LIST, SECTION_ID_STREAM_GROUP_COMPONENTS, SECTION_ID_STREAM_GROUP_STREAMS, SECTION_ID_STREAM_GROUP_STREAM_GROUPS, -1 } },
     [SECTION_ID_STREAM_GROUP_COMPONENTS] =         { SECTION_ID_STREAM_GROUP_COMPONENTS, "components", AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM_GROUP_COMPONENT, -1 }, .element_name = "component", .unique_name = "stream_group_components" },
-    [SECTION_ID_STREAM_GROUP_COMPONENT] =          { SECTION_ID_STREAM_GROUP_COMPONENT, "component", AV_TEXTFORMAT_SECTION_FLAG_HAS_VARIABLE_FIELDS|AV_TEXTFORMAT_SECTION_FLAG_HAS_TYPE, { SECTION_ID_STREAM_GROUP_SIDE_DATA_LIST, SECTION_ID_STREAM_GROUP_SUBCOMPONENTS, -1 }, .unique_name = "stream_group_component", .element_name = "component_entry", .get_type = get_stream_group_type },
+    [SECTION_ID_STREAM_GROUP_COMPONENT] =          { SECTION_ID_STREAM_GROUP_COMPONENT, "component", AV_TEXTFORMAT_SECTION_FLAG_HAS_VARIABLE_FIELDS|AV_TEXTFORMAT_SECTION_FLAG_HAS_TYPE, { SECTION_ID_STREAM_GROUP_SUBCOMPONENTS, -1 }, .unique_name = "stream_group_component", .element_name = "component_entry", .get_type = get_stream_group_type },
     [SECTION_ID_STREAM_GROUP_SUBCOMPONENTS] =      { SECTION_ID_STREAM_GROUP_SUBCOMPONENTS, "subcomponents", AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM_GROUP_SUBCOMPONENT, -1 }, .element_name = "component" },
     [SECTION_ID_STREAM_GROUP_SUBCOMPONENT] =       { SECTION_ID_STREAM_GROUP_SUBCOMPONENT, "subcomponent", AV_TEXTFORMAT_SECTION_FLAG_HAS_VARIABLE_FIELDS|AV_TEXTFORMAT_SECTION_FLAG_HAS_TYPE, { SECTION_ID_STREAM_GROUP_PIECES, -1 }, .element_name = "subcomponent_entry", .get_type = get_raw_string_type },
     [SECTION_ID_STREAM_GROUP_PIECES] =             { SECTION_ID_STREAM_GROUP_PIECES, "pieces", AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM_GROUP_PIECE, -1 }, .element_name = "piece", .unique_name = "stream_group_pieces" },
@@ -317,9 +342,11 @@ static const AVTextFormatSection sections[] = {
     [SECTION_ID_STREAM_GROUP_BLOCKS] =             { SECTION_ID_STREAM_GROUP_BLOCKS, "blocks", AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM_GROUP_BLOCK, -1 }, .element_name = "block" },
     [SECTION_ID_STREAM_GROUP_BLOCK] =              { SECTION_ID_STREAM_GROUP_BLOCK, "block", AV_TEXTFORMAT_SECTION_FLAG_HAS_VARIABLE_FIELDS|AV_TEXTFORMAT_SECTION_FLAG_HAS_TYPE, { -1 }, .element_name = "block_entry", .get_type = get_raw_string_type },
     [SECTION_ID_STREAM_GROUP_SIDE_DATA_LIST] =     { SECTION_ID_STREAM_GROUP_SIDE_DATA_LIST, "side_data_list", AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM_GROUP_SIDE_DATA, -1 }, .element_name = "side_data", .unique_name = "stream_group_side_data_list" },
-    [SECTION_ID_STREAM_GROUP_SIDE_DATA] =          { SECTION_ID_STREAM_GROUP_SIDE_DATA, "side_data", AV_TEXTFORMAT_SECTION_FLAG_HAS_TYPE|AV_TEXTFORMAT_SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .unique_name = "stream_group_side_data", .element_name = "side_datum", .get_type = get_packet_side_data_type },
+    [SECTION_ID_STREAM_GROUP_SIDE_DATA] =          { SECTION_ID_STREAM_GROUP_SIDE_DATA, "side_data", AV_TEXTFORMAT_SECTION_FLAG_HAS_TYPE|AV_TEXTFORMAT_SECTION_FLAG_HAS_VARIABLE_FIELDS, { SECTION_ID_STREAM_GROUP_SIDE_DATA_COMPONENT_LIST, -1 }, .unique_name = "stream_group_side_data", .element_name = "side_datum", .get_type = get_packet_side_data_type },
+    [SECTION_ID_STREAM_GROUP_SIDE_DATA_COMPONENT_LIST] = { SECTION_ID_STREAM_GROUP_SIDE_DATA_COMPONENT_LIST, "components", AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM_GROUP_SIDE_DATA_COMPONENT, -1 }, .element_name = "component", .unique_name = "stream_group_side_data_components" },
+    [SECTION_ID_STREAM_GROUP_SIDE_DATA_COMPONENT] =      { SECTION_ID_STREAM_GROUP_SIDE_DATA_COMPONENT, "component", AV_TEXTFORMAT_SECTION_FLAG_HAS_VARIABLE_FIELDS|AV_TEXTFORMAT_SECTION_FLAG_HAS_TYPE, { -1 }, .unique_name = "stream_group_side_data_component", .element_name = "component_entry", .get_type = get_raw_string_type },
     [SECTION_ID_STREAM_GROUP_STREAMS] =            { SECTION_ID_STREAM_GROUP_STREAMS, "streams", AV_TEXTFORMAT_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_STREAM] =             { SECTION_ID_STREAM_GROUP_STREAM, "stream", 0, { SECTION_ID_STREAM_GROUP_STREAM_DISPOSITION, SECTION_ID_STREAM_GROUP_STREAM_TAGS, SECTION_ID_STREAM_GROUP_STREAM_SIDE_DATA_LIST, -1 }, .unique_name = "stream_group_stream" },
     [SECTION_ID_STREAM_GROUP_STREAM_GROUPS] =      { SECTION_ID_STREAM_GROUP_STREAM_GROUPS, "stream_groups", AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM_GROUP_STREAM_GROUP, -1 }, .unique_name = "stream_group_stream_groups" },
     [SECTION_ID_STREAM_GROUP_STREAM_GROUP] =       { SECTION_ID_STREAM_GROUP_STREAM_GROUP, "stream_group", 0, { SECTION_ID_STREAM_GROUP_STREAM_GROUP_DISPOSITION, SECTION_ID_STREAM_GROUP_STREAM_GROUP_TAGS, -1 }, .unique_name = "stream_group_stream_group" },
     [SECTION_ID_STREAM_GROUP_DISPOSITION] =        { SECTION_ID_STREAM_GROUP_DISPOSITION, "disposition", 0, { -1 }, .unique_name = "stream_group_disposition" },
@@ -334,7 +361,9 @@ static const AVTextFormatSection sections[] = {
     [SECTION_ID_STREAM_DISPOSITION] = { SECTION_ID_STREAM_DISPOSITION, "disposition", 0, { -1 }, .unique_name = "stream_disposition" },
     [SECTION_ID_STREAM_TAGS] =        { SECTION_ID_STREAM_TAGS, "tags", AV_TEXTFORMAT_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", AV_TEXTFORMAT_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", AV_TEXTFORMAT_SECTION_FLAG_HAS_TYPE|AV_TEXTFORMAT_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_SIDE_DATA] =     { SECTION_ID_STREAM_SIDE_DATA, "side_data", AV_TEXTFORMAT_SECTION_FLAG_HAS_TYPE|AV_TEXTFORMAT_SECTION_FLAG_HAS_VARIABLE_FIELDS, { SECTION_ID_STREAM_SIDE_DATA_COMPONENT_LIST, -1 }, .unique_name = "stream_side_data", .element_name = "side_datum", .get_type = get_packet_side_data_type },
+    [SECTION_ID_STREAM_SIDE_DATA_COMPONENT_LIST] = { SECTION_ID_STREAM_SIDE_DATA_COMPONENT_LIST, "components", AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM_SIDE_DATA_COMPONENT, -1 }, .element_name = "component", .unique_name = "stream_side_data_components" },
+    [SECTION_ID_STREAM_SIDE_DATA_COMPONENT] =      { SECTION_ID_STREAM_SIDE_DATA_COMPONENT, "component", AV_TEXTFORMAT_SECTION_FLAG_HAS_VARIABLE_FIELDS|AV_TEXTFORMAT_SECTION_FLAG_HAS_TYPE, { -1 }, .unique_name = "stream_side_data_component", .element_name = "component_entry", .get_type = get_raw_string_type },
     [SECTION_ID_SUBTITLE] =           { SECTION_ID_SUBTITLE, "subtitle", 0, { -1 } },
 };

@@ -1100,15 +1129,29 @@ static void print_film_grain_params(AVTextFormatContext *tfc,
     av_bprint_finalize(&pbuf, NULL);
 }

+#define PKT_SIDE_DATA_IN_STREAM 1
+#define PKT_SIDE_DATA_IN_STREAM_GROUP 2
+#define PKT_SIDE_DATA_IN_STREAM_GROUP_STREAM 3
+#define PKT_SIDE_DATA_IN_PROGRAM_STREAM 4
+
 static void print_pkt_side_data(AVTextFormatContext *tfc,
                                 int width,
                                 int height,
                                 const AVPacketSideData *sd,
-                                SectionID id_data)
+                                int container)
 {
     const char *name = av_packet_side_data_name(sd->type);
+    const SectionID section_header[] = {
+        SECTION_ID_PACKET_SIDE_DATA,
+        SECTION_ID_STREAM_SIDE_DATA,
+        SECTION_ID_STREAM_GROUP_SIDE_DATA,
+        SECTION_ID_STREAM_GROUP_STREAM_SIDE_DATA,
+        SECTION_ID_PROGRAM_STREAM_SIDE_DATA,
+    };
+
+    av_assert0(container < FF_ARRAY_ELEMS(section_header));

-    avtext_print_section_header(tfc, sd, id_data);
+    avtext_print_section_header(tfc, sd, section_header[container]);
     print_str("side_data_type", name ? name : "unknown");
     if (sd->type == AV_PKT_DATA_DISPLAYMATRIX && sd->size >= 9*4) {
         print_displaymatrix(tfc, (const int32_t*)sd->data);
@@ -1204,6 +1247,7 @@ static void print_pkt_side_data(AVTextFormatContext *tfc,
         if (do_show_data)
             avtext_print_data(tfc, "block_additional_data", sd->data + 8, sd->size - 8);
     }
+    avtext_print_section_footer(tfc);
 }

 static void print_private_data(AVTextFormatContext *tfc, void *priv_data)
@@ -1399,9 +1443,7 @@ static void show_packet(AVTextFormatContext *tfc, InputFile *ifile, AVPacket *pk

         avtext_print_section_header(tfc, NULL, SECTION_ID_PACKET_SIDE_DATA_LIST);
         for (int i = 0; i < pkt->side_data_elems; i++) {
-            print_pkt_side_data(tfc, st->codecpar->width, st->codecpar->height, &pkt->side_data[i],
-                                SECTION_ID_PACKET_SIDE_DATA);
-            avtext_print_section_footer(tfc);
+            print_pkt_side_data(tfc, st->codecpar->width, st->codecpar->height, &pkt->side_data[i], 0);
         }
         avtext_print_section_footer(tfc);
     }
@@ -1896,6 +1938,16 @@ static int show_stream(AVTextFormatContext *tfc, AVFormatContext *fmt_ctx, int s
         SECTION_ID_PROGRAM_STREAM_TAGS,
         SECTION_ID_STREAM_GROUP_STREAM_TAGS,
     };
+    const SectionID section_side_data[] = {
+        SECTION_ID_STREAM_SIDE_DATA_LIST,
+        SECTION_ID_PROGRAM_STREAM_SIDE_DATA_LIST,
+        SECTION_ID_STREAM_GROUP_STREAM_SIDE_DATA_LIST,
+    };
+    const SectionID container_side_data[] = {
+        PKT_SIDE_DATA_IN_STREAM,
+        PKT_SIDE_DATA_IN_PROGRAM_STREAM,
+        PKT_SIDE_DATA_IN_STREAM_GROUP_STREAM,
+    };
     int ret = 0;
     const char *profile = NULL;

@@ -2083,11 +2135,12 @@ static int show_stream(AVTextFormatContext *tfc, AVFormatContext *fmt_ctx, int s
     }

     if (stream->codecpar->nb_coded_side_data) {
-        avtext_print_section_header(tfc, NULL, SECTION_ID_STREAM_SIDE_DATA_LIST);
+        av_assert0(container < FF_ARRAY_ELEMS(section_tags) &&
+                   container < FF_ARRAY_ELEMS(container_side_data));
+        avtext_print_section_header(tfc, NULL, section_side_data[container]);
         for (int i = 0; i < stream->codecpar->nb_coded_side_data; i++) {
             print_pkt_side_data(tfc, stream->codecpar->width, stream->codecpar->height, &stream->codecpar->coded_side_data[i],
-                                SECTION_ID_STREAM_SIDE_DATA);
-            avtext_print_section_footer(tfc);
+                                container_side_data[container]);
         }
         avtext_print_section_footer(tfc);
     }
@@ -2185,15 +2238,6 @@ static void print_tile_grid_params(AVTextFormatContext *tfc, const AVStreamGroup
         avtext_print_section_footer(tfc);
     }
     avtext_print_section_footer(tfc);
-    if (stg->nb_coded_side_data) {
-        avtext_print_section_header(tfc, NULL, SECTION_ID_STREAM_GROUP_SIDE_DATA_LIST);
-        for (int i = 0; i < stg->nb_coded_side_data; i++) {
-            print_pkt_side_data(tfc, tile_grid->width, tile_grid->height, &stg->coded_side_data[i],
-                                SECTION_ID_STREAM_GROUP_SIDE_DATA);
-            avtext_print_section_footer(tfc);
-        }
-        avtext_print_section_footer(tfc);
-    }
     avtext_print_section_footer(tfc);
 }

@@ -2435,6 +2479,27 @@ static int show_stream_group(AVTextFormatContext *tfc, InputFile *ifile, AVStrea
     if (ret < 0)
         goto end;

+    if (stg->nb_coded_side_data) {
+        int width = 0, height = 0;
+        avtext_print_section_header(tfc, NULL, SECTION_ID_STREAM_GROUP_SIDE_DATA_LIST);
+
+        switch (stg->type) {
+        case AV_STREAM_GROUP_PARAMS_TILE_GRID: {
+            const AVStreamGroupTileGrid *tile_grid = stg->params.tile_grid;
+            width = tile_grid->width;
+            height = tile_grid->height;
+            break;
+        }
+        default:
+            break;
+        }
+        for (int i = 0; i < stg->nb_coded_side_data; i++) {
+            print_pkt_side_data(tfc, width, height, &stg->coded_side_data[i],
+                                PKT_SIDE_DATA_IN_STREAM_GROUP);
+        }
+        avtext_print_section_footer(tfc);
+    }
+
     avtext_print_section_header(tfc, NULL, SECTION_ID_STREAM_GROUP_STREAM_GROUPS);
     for (unsigned i = 0; i < stg->nb_entries; i++) {
         AVStreamGroupEntry *entry = stg->entries[i];
diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak
index 979d8533e9..3827f65ead 100644
--- a/tests/fate/mov.mak
+++ b/tests/fate/mov.mak
@@ -56,7 +56,7 @@ fate-ffprobe-stream-entries-tmcd: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -v error
 fate-ffprobe-group-stream-entries-tmcd: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -v error -select_streams v:0 \
     -show_entries stream_group_stream=index -of compact $(TARGET_SAMPLES)/mov/fcp_export8-236.mov
 fate-ffprobe-show-groups-tmcd: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -v error -select_streams v:0 -show_stream_groups \
-    -show_entries stream_group=:stream_group_disposition=:stream_group_tags=:stream_group_components=:stream_group_stream_disposition=:stream_group_stream_tags=:stream=index \
+    -show_entries stream_group=:stream_group_disposition=:stream_group_tags=:stream_group_components=:stream_group_stream_disposition=:stream_group_stream_tags=:stream_group_stream_side_data=:stream=index \
     -of compact $(TARGET_SAMPLES)/mov/fcp_export8-236.mov

 FATE_MOV_FASTSTART = fate-mov-faststart-4gb-overflow \