Message ID | 20240305000033.10379-6-jamrial@gmail.com |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel,1/9,v2] fftools/ffprobe: fix printing side data components and pieces | expand |
Context | Check | Description |
---|---|---|
andriy/make_x86 | success | Make finished |
andriy/make_fate_x86 | success | Make fate finished |
On 3/4/2024 9:00 PM, James Almer wrote: > Signed-off-by: James Almer <jamrial@gmail.com> > --- > fftools/ffprobe.c | 41 ++++++++++++++++++++++++++++++++++++----- > 1 file changed, 36 insertions(+), 5 deletions(-) > > diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c > index ff05c4c1db..e736023bcd 100644 > --- a/fftools/ffprobe.c > +++ b/fftools/ffprobe.c > @@ -209,6 +209,10 @@ typedef enum { > SECTION_ID_STREAM_GROUP_STREAM_DISPOSITION, > SECTION_ID_STREAM_GROUP_STREAM_TAGS, > SECTION_ID_STREAM_GROUP, > + SECTION_ID_STREAM_GROUP_COMPONENTS, > + SECTION_ID_STREAM_GROUP_COMPONENT, > + SECTION_ID_STREAM_GROUP_PIECES, > + SECTION_ID_STREAM_GROUP_PIECE, > SECTION_ID_STREAM_GROUP_STREAMS, > SECTION_ID_STREAM_GROUP_STREAM, > SECTION_ID_STREAM_GROUP_DISPOSITION, > @@ -282,8 +286,8 @@ static struct section sections[] = { > [SECTION_ID_FRAME_SIDE_DATA_TIMECODE] = { SECTION_ID_FRAME_SIDE_DATA_TIMECODE, "timecode", 0, { -1 } }, > [SECTION_ID_FRAME_SIDE_DATA_COMPONENT_LIST] = { SECTION_ID_FRAME_SIDE_DATA_COMPONENT_LIST, "components", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME_SIDE_DATA_COMPONENT, -1 }, .element_name = "component", .unique_name = "frame_side_data_components" }, > [SECTION_ID_FRAME_SIDE_DATA_COMPONENT] = { SECTION_ID_FRAME_SIDE_DATA_COMPONENT, "component", SECTION_FLAG_HAS_VARIABLE_FIELDS|SECTION_FLAG_HAS_TYPE, { SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST, -1 }, .unique_name = "frame_side_data_component", .element_name = "component_entry", .get_type = get_raw_string_type }, > - [SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST] = { SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST, "pieces", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME_SIDE_DATA_PIECE, -1 }, .element_name = "piece" }, > - [SECTION_ID_FRAME_SIDE_DATA_PIECE] = { SECTION_ID_FRAME_SIDE_DATA_PIECE, "piece", SECTION_FLAG_HAS_VARIABLE_FIELDS|SECTION_FLAG_HAS_TYPE, { -1 }, .element_name = "piece_entry", .get_type = get_raw_string_type }, > + [SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST] = { SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST, "pieces", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME_SIDE_DATA_PIECE, -1 }, .element_name = "piece", .unique_name = "frame_side_data_pieces" }, > + [SECTION_ID_FRAME_SIDE_DATA_PIECE] = { SECTION_ID_FRAME_SIDE_DATA_PIECE, "piece", SECTION_FLAG_HAS_VARIABLE_FIELDS|SECTION_FLAG_HAS_TYPE, { -1 }, .element_name = "piece_entry", .unique_name = "frame_side_data_piece", .get_type = get_raw_string_type }, > [SECTION_ID_FRAME_LOGS] = { SECTION_ID_FRAME_LOGS, "logs", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME_LOG, -1 } }, > [SECTION_ID_FRAME_LOG] = { SECTION_ID_FRAME_LOG, "log", 0, { -1 }, }, > [SECTION_ID_LIBRARY_VERSIONS] = { SECTION_ID_LIBRARY_VERSIONS, "library_versions", SECTION_FLAG_IS_ARRAY, { SECTION_ID_LIBRARY_VERSION, -1 } }, > @@ -309,7 +313,11 @@ static struct section sections[] = { > [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] = { SECTION_ID_STREAM_GROUP, "stream_group", SECTION_FLAG_HAS_TYPE, { SECTION_ID_STREAM_GROUP_TAGS, SECTION_ID_STREAM_GROUP_DISPOSITION, SECTION_ID_STREAM_GROUP_COMPONENTS, SECTION_ID_STREAM_GROUP_STREAMS, -1 }, .get_type = get_stream_group_type }, > + [SECTION_ID_STREAM_GROUP_COMPONENTS] = { SECTION_ID_STREAM_GROUP_COMPONENTS, "components", 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", SECTION_FLAG_HAS_VARIABLE_FIELDS|SECTION_FLAG_HAS_TYPE, { SECTION_ID_STREAM_GROUP_PIECES, -1 }, .unique_name = "stream_group_component", .element_name = "component_entry", .get_type = get_raw_string_type }, > + [SECTION_ID_STREAM_GROUP_PIECES] = { SECTION_ID_STREAM_GROUP_PIECES, "pieces", SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM_GROUP_PIECE, -1 }, .element_name = "piece", .unique_name = "stream_group_pieces" }, > + [SECTION_ID_STREAM_GROUP_PIECE] = { SECTION_ID_STREAM_GROUP_PIECE, "piece", SECTION_FLAG_HAS_VARIABLE_FIELDS|SECTION_FLAG_HAS_TYPE, { -1 }, .element_name = "piece_entry", .unique_name = "stream_group_piece", .get_type = get_raw_string_type }, I think I'll withdraw this patch for now. Some stream group types have several layers of data, so components and pieces would not be enough. This is the case for IAMF Audio Elements and Mix Presentation, for example. A generic way to add N amount of layers would be needed.
On date Monday 2024-03-04 21:00:26 -0300, James Almer wrote: > Signed-off-by: James Almer <jamrial@gmail.com> > --- > fftools/ffprobe.c | 41 ++++++++++++++++++++++++++++++++++++----- > 1 file changed, 36 insertions(+), 5 deletions(-) > > diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c > index ff05c4c1db..e736023bcd 100644 > --- a/fftools/ffprobe.c > +++ b/fftools/ffprobe.c > @@ -209,6 +209,10 @@ typedef enum { > SECTION_ID_STREAM_GROUP_STREAM_DISPOSITION, > SECTION_ID_STREAM_GROUP_STREAM_TAGS, > SECTION_ID_STREAM_GROUP, > + SECTION_ID_STREAM_GROUP_COMPONENTS, > + SECTION_ID_STREAM_GROUP_COMPONENT, > + SECTION_ID_STREAM_GROUP_PIECES, > + SECTION_ID_STREAM_GROUP_PIECE, > SECTION_ID_STREAM_GROUP_STREAMS, > SECTION_ID_STREAM_GROUP_STREAM, > SECTION_ID_STREAM_GROUP_DISPOSITION, > @@ -282,8 +286,8 @@ static struct section sections[] = { > [SECTION_ID_FRAME_SIDE_DATA_TIMECODE] = { SECTION_ID_FRAME_SIDE_DATA_TIMECODE, "timecode", 0, { -1 } }, > [SECTION_ID_FRAME_SIDE_DATA_COMPONENT_LIST] = { SECTION_ID_FRAME_SIDE_DATA_COMPONENT_LIST, "components", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME_SIDE_DATA_COMPONENT, -1 }, .element_name = "component", .unique_name = "frame_side_data_components" }, > [SECTION_ID_FRAME_SIDE_DATA_COMPONENT] = { SECTION_ID_FRAME_SIDE_DATA_COMPONENT, "component", SECTION_FLAG_HAS_VARIABLE_FIELDS|SECTION_FLAG_HAS_TYPE, { SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST, -1 }, .unique_name = "frame_side_data_component", .element_name = "component_entry", .get_type = get_raw_string_type }, > - [SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST] = { SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST, "pieces", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME_SIDE_DATA_PIECE, -1 }, .element_name = "piece" }, > - [SECTION_ID_FRAME_SIDE_DATA_PIECE] = { SECTION_ID_FRAME_SIDE_DATA_PIECE, "piece", SECTION_FLAG_HAS_VARIABLE_FIELDS|SECTION_FLAG_HAS_TYPE, { -1 }, .element_name = "piece_entry", .get_type = get_raw_string_type }, > + [SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST] = { SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST, "pieces", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME_SIDE_DATA_PIECE, -1 }, .element_name = "piece", .unique_name = "frame_side_data_pieces" }, > + [SECTION_ID_FRAME_SIDE_DATA_PIECE] = { SECTION_ID_FRAME_SIDE_DATA_PIECE, "piece", SECTION_FLAG_HAS_VARIABLE_FIELDS|SECTION_FLAG_HAS_TYPE, { -1 }, .element_name = "piece_entry", .unique_name = "frame_side_data_piece", .get_type = get_raw_string_type }, > [SECTION_ID_FRAME_LOGS] = { SECTION_ID_FRAME_LOGS, "logs", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME_LOG, -1 } }, > [SECTION_ID_FRAME_LOG] = { SECTION_ID_FRAME_LOG, "log", 0, { -1 }, }, > [SECTION_ID_LIBRARY_VERSIONS] = { SECTION_ID_LIBRARY_VERSIONS, "library_versions", SECTION_FLAG_IS_ARRAY, { SECTION_ID_LIBRARY_VERSION, -1 } }, > @@ -309,7 +313,11 @@ static struct section sections[] = { > [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] = { SECTION_ID_STREAM_GROUP, "stream_group", SECTION_FLAG_HAS_TYPE, { SECTION_ID_STREAM_GROUP_TAGS, SECTION_ID_STREAM_GROUP_DISPOSITION, SECTION_ID_STREAM_GROUP_COMPONENTS, SECTION_ID_STREAM_GROUP_STREAMS, -1 }, .get_type = get_stream_group_type }, > + [SECTION_ID_STREAM_GROUP_COMPONENTS] = { SECTION_ID_STREAM_GROUP_COMPONENTS, "components", 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", SECTION_FLAG_HAS_VARIABLE_FIELDS|SECTION_FLAG_HAS_TYPE, { SECTION_ID_STREAM_GROUP_PIECES, -1 }, .unique_name = "stream_group_component", .element_name = "component_entry", .get_type = get_raw_string_type }, > + [SECTION_ID_STREAM_GROUP_PIECES] = { SECTION_ID_STREAM_GROUP_PIECES, "pieces", SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM_GROUP_PIECE, -1 }, .element_name = "piece", .unique_name = "stream_group_pieces" }, > + [SECTION_ID_STREAM_GROUP_PIECE] = { SECTION_ID_STREAM_GROUP_PIECE, "piece", SECTION_FLAG_HAS_VARIABLE_FIELDS|SECTION_FLAG_HAS_TYPE, { -1 }, .element_name = "piece_entry", .unique_name = "stream_group_piece", .get_type = get_raw_string_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" }, > @@ -3388,9 +3396,32 @@ static int show_programs(WriterContext *w, InputFile *ifile) > static void print_stream_group_params(WriterContext *w, AVStreamGroup *stg) > { > const char *unknown = "unknown"; > - if (stg->type != AV_STREAM_GROUP_PARAMS_NONE) > + if (stg->type != AV_STREAM_GROUP_PARAMS_NONE) { > print_str("type", av_x_if_null(avformat_stream_group_name(stg->type), unknown)); nit: you can avoid the indent if you check the NONE case and return immediately in that case > - else > + if (stg->type == AV_STREAM_GROUP_PARAMS_TILE_GRID) { > + AVStreamGroupTileGrid *tile_grid = stg->params.tile_grid; > + writer_print_section_header(w, NULL, SECTION_ID_STREAM_GROUP_COMPONENTS); > + writer_print_section_header(w, "parameters", SECTION_ID_STREAM_GROUP_COMPONENT); > + print_int("nb_tiles", tile_grid->nb_tiles); > + print_int("coded_width", tile_grid->coded_width); > + print_int("coded_height", tile_grid->coded_height); > + print_int("horizontal_offset", tile_grid->horizontal_offset); > + print_int("vertical_offset", tile_grid->vertical_offset); > + print_int("width", tile_grid->width); > + print_int("height", tile_grid->height); > + writer_print_section_header(w, NULL, SECTION_ID_STREAM_GROUP_PIECES); > + for (int i = 0; i < tile_grid->nb_tiles; i++) { > + writer_print_section_header(w, "tile_offset", SECTION_ID_STREAM_GROUP_PIECE); > + print_int("stream_index", tile_grid->offsets[i].idx); > + print_int("tile_horizontal_offset", tile_grid->offsets[i].horizontal); > + print_int("tile_vertical_offset", tile_grid->offsets[i].vertical); > + writer_print_section_footer(w); > + } > + writer_print_section_footer(w); > + writer_print_section_footer(w); > + writer_print_section_footer(w); > + } > + } else > print_str_opt("type", unknown); > } LGTM, thanks.
On date Tuesday 2024-03-05 12:14:53 -0300, James Almer wrote: > On 3/4/2024 9:00 PM, James Almer wrote: > > Signed-off-by: James Almer <jamrial@gmail.com> > > --- > > fftools/ffprobe.c | 41 ++++++++++++++++++++++++++++++++++++----- > > 1 file changed, 36 insertions(+), 5 deletions(-) [...] > I think I'll withdraw this patch for now. Some stream group types have > several layers of data, so components and pieces would not be enough. This > is the case for IAMF Audio Elements and Mix Presentation, for example. > A generic way to add N amount of layers would be needed. I see. Does it mean that the nesting level is greater than 3 (side_data, components, pieces)? Probably the best we can do is some kind of flattening (ffprobe is not designed for generic level of nesting, as we need to define the structure of the layout, at least for some formats (e.g. XML)).
On 3/5/2024 12:24 PM, Stefano Sabatini wrote: > On date Tuesday 2024-03-05 12:14:53 -0300, James Almer wrote: >> On 3/4/2024 9:00 PM, James Almer wrote: >>> Signed-off-by: James Almer <jamrial@gmail.com> >>> --- >>> fftools/ffprobe.c | 41 ++++++++++++++++++++++++++++++++++++----- >>> 1 file changed, 36 insertions(+), 5 deletions(-) > [...] > >> I think I'll withdraw this patch for now. Some stream group types have >> several layers of data, so components and pieces would not be enough. This >> is the case for IAMF Audio Elements and Mix Presentation, for example. >> A generic way to add N amount of layers would be needed. > > I see. > > Does it mean that the nesting level is greater than 3 (side_data, > components, pieces)? Yes. Look at AVIAMFMixPresentation, which has an array of AVIAMFSubmix, which in turn have an array of AVIAMFSubmixLayout plus an array of AVIAMFSubmixElement per submix, the latter which has a AVIAMFParamDefinition per element. If the AVIAMFMixPresentation is the component, the AVIAMFSubmix would be the piece, and then we ran out of levels. > > Probably the best we can do is some kind of flattening (ffprobe is not > designed for generic level of nesting, as we need to define the > structure of the layout, at least for some formats (e.g. XML)). > _______________________________________________ > 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".
On date Tuesday 2024-03-05 12:50:09 -0300, James Almer wrote: > On 3/5/2024 12:24 PM, Stefano Sabatini wrote: > > On date Tuesday 2024-03-05 12:14:53 -0300, James Almer wrote: > > > On 3/4/2024 9:00 PM, James Almer wrote: > > > > Signed-off-by: James Almer <jamrial@gmail.com> > > > > --- > > > > fftools/ffprobe.c | 41 ++++++++++++++++++++++++++++++++++++----- > > > > 1 file changed, 36 insertions(+), 5 deletions(-) > > [...] > > > > > I think I'll withdraw this patch for now. Some stream group types have > > > several layers of data, so components and pieces would not be enough. This > > > is the case for IAMF Audio Elements and Mix Presentation, for example. > > > A generic way to add N amount of layers would be needed. > > > > I see. > > > > Does it mean that the nesting level is greater than 3 (side_data, > > components, pieces)? > > Yes. Look at AVIAMFMixPresentation, which has an array of AVIAMFSubmix, > which in turn have an array of AVIAMFSubmixLayout plus an array of > AVIAMFSubmixElement per submix, the latter which has a AVIAMFParamDefinition > per element. > If the AVIAMFMixPresentation is the component, the AVIAMFSubmix would be the > piece, and then we ran out of levels. Well, the simplemst approach is to add more levels to the layout (side_data, components, pieces, subpieces?, ...).
diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index ff05c4c1db..e736023bcd 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -209,6 +209,10 @@ typedef enum { SECTION_ID_STREAM_GROUP_STREAM_DISPOSITION, SECTION_ID_STREAM_GROUP_STREAM_TAGS, SECTION_ID_STREAM_GROUP, + SECTION_ID_STREAM_GROUP_COMPONENTS, + SECTION_ID_STREAM_GROUP_COMPONENT, + SECTION_ID_STREAM_GROUP_PIECES, + SECTION_ID_STREAM_GROUP_PIECE, SECTION_ID_STREAM_GROUP_STREAMS, SECTION_ID_STREAM_GROUP_STREAM, SECTION_ID_STREAM_GROUP_DISPOSITION, @@ -282,8 +286,8 @@ static struct section sections[] = { [SECTION_ID_FRAME_SIDE_DATA_TIMECODE] = { SECTION_ID_FRAME_SIDE_DATA_TIMECODE, "timecode", 0, { -1 } }, [SECTION_ID_FRAME_SIDE_DATA_COMPONENT_LIST] = { SECTION_ID_FRAME_SIDE_DATA_COMPONENT_LIST, "components", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME_SIDE_DATA_COMPONENT, -1 }, .element_name = "component", .unique_name = "frame_side_data_components" }, [SECTION_ID_FRAME_SIDE_DATA_COMPONENT] = { SECTION_ID_FRAME_SIDE_DATA_COMPONENT, "component", SECTION_FLAG_HAS_VARIABLE_FIELDS|SECTION_FLAG_HAS_TYPE, { SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST, -1 }, .unique_name = "frame_side_data_component", .element_name = "component_entry", .get_type = get_raw_string_type }, - [SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST] = { SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST, "pieces", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME_SIDE_DATA_PIECE, -1 }, .element_name = "piece" }, - [SECTION_ID_FRAME_SIDE_DATA_PIECE] = { SECTION_ID_FRAME_SIDE_DATA_PIECE, "piece", SECTION_FLAG_HAS_VARIABLE_FIELDS|SECTION_FLAG_HAS_TYPE, { -1 }, .element_name = "piece_entry", .get_type = get_raw_string_type }, + [SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST] = { SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST, "pieces", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME_SIDE_DATA_PIECE, -1 }, .element_name = "piece", .unique_name = "frame_side_data_pieces" }, + [SECTION_ID_FRAME_SIDE_DATA_PIECE] = { SECTION_ID_FRAME_SIDE_DATA_PIECE, "piece", SECTION_FLAG_HAS_VARIABLE_FIELDS|SECTION_FLAG_HAS_TYPE, { -1 }, .element_name = "piece_entry", .unique_name = "frame_side_data_piece", .get_type = get_raw_string_type }, [SECTION_ID_FRAME_LOGS] = { SECTION_ID_FRAME_LOGS, "logs", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME_LOG, -1 } }, [SECTION_ID_FRAME_LOG] = { SECTION_ID_FRAME_LOG, "log", 0, { -1 }, }, [SECTION_ID_LIBRARY_VERSIONS] = { SECTION_ID_LIBRARY_VERSIONS, "library_versions", SECTION_FLAG_IS_ARRAY, { SECTION_ID_LIBRARY_VERSION, -1 } }, @@ -309,7 +313,11 @@ static struct section sections[] = { [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] = { SECTION_ID_STREAM_GROUP, "stream_group", SECTION_FLAG_HAS_TYPE, { SECTION_ID_STREAM_GROUP_TAGS, SECTION_ID_STREAM_GROUP_DISPOSITION, SECTION_ID_STREAM_GROUP_COMPONENTS, SECTION_ID_STREAM_GROUP_STREAMS, -1 }, .get_type = get_stream_group_type }, + [SECTION_ID_STREAM_GROUP_COMPONENTS] = { SECTION_ID_STREAM_GROUP_COMPONENTS, "components", 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", SECTION_FLAG_HAS_VARIABLE_FIELDS|SECTION_FLAG_HAS_TYPE, { SECTION_ID_STREAM_GROUP_PIECES, -1 }, .unique_name = "stream_group_component", .element_name = "component_entry", .get_type = get_raw_string_type }, + [SECTION_ID_STREAM_GROUP_PIECES] = { SECTION_ID_STREAM_GROUP_PIECES, "pieces", SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM_GROUP_PIECE, -1 }, .element_name = "piece", .unique_name = "stream_group_pieces" }, + [SECTION_ID_STREAM_GROUP_PIECE] = { SECTION_ID_STREAM_GROUP_PIECE, "piece", SECTION_FLAG_HAS_VARIABLE_FIELDS|SECTION_FLAG_HAS_TYPE, { -1 }, .element_name = "piece_entry", .unique_name = "stream_group_piece", .get_type = get_raw_string_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" }, @@ -3388,9 +3396,32 @@ static int show_programs(WriterContext *w, InputFile *ifile) static void print_stream_group_params(WriterContext *w, AVStreamGroup *stg) { const char *unknown = "unknown"; - if (stg->type != AV_STREAM_GROUP_PARAMS_NONE) + if (stg->type != AV_STREAM_GROUP_PARAMS_NONE) { print_str("type", av_x_if_null(avformat_stream_group_name(stg->type), unknown)); - else + if (stg->type == AV_STREAM_GROUP_PARAMS_TILE_GRID) { + AVStreamGroupTileGrid *tile_grid = stg->params.tile_grid; + writer_print_section_header(w, NULL, SECTION_ID_STREAM_GROUP_COMPONENTS); + writer_print_section_header(w, "parameters", SECTION_ID_STREAM_GROUP_COMPONENT); + print_int("nb_tiles", tile_grid->nb_tiles); + print_int("coded_width", tile_grid->coded_width); + print_int("coded_height", tile_grid->coded_height); + print_int("horizontal_offset", tile_grid->horizontal_offset); + print_int("vertical_offset", tile_grid->vertical_offset); + print_int("width", tile_grid->width); + print_int("height", tile_grid->height); + writer_print_section_header(w, NULL, SECTION_ID_STREAM_GROUP_PIECES); + for (int i = 0; i < tile_grid->nb_tiles; i++) { + writer_print_section_header(w, "tile_offset", SECTION_ID_STREAM_GROUP_PIECE); + print_int("stream_index", tile_grid->offsets[i].idx); + print_int("tile_horizontal_offset", tile_grid->offsets[i].horizontal); + print_int("tile_vertical_offset", tile_grid->offsets[i].vertical); + writer_print_section_footer(w); + } + writer_print_section_footer(w); + writer_print_section_footer(w); + writer_print_section_footer(w); + } + } else print_str_opt("type", unknown); }
Signed-off-by: James Almer <jamrial@gmail.com> --- fftools/ffprobe.c | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-)