Commit 6a4f712549 for ffmpeg
commit 6a4f7125498f6ba796d208e32087dc06dea50ee4
Author: James Almer <jamrial@gmail.com>
Date: Mon Oct 5 16:08:06 2026 -0300
avformat/dump: Support printing child groups within a group
Only for Layered Video of Gain Map type for now.
Signed-off-by: James Almer <jamrial@gmail.com>
diff --git a/libavformat/dump.c b/libavformat/dump.c
index 34f93e24a4..0f2eef33c9 100644
--- a/libavformat/dump.c
+++ b/libavformat/dump.c
@@ -684,34 +684,36 @@ static void dump_stream_format(const AVFormatContext *ic, int i,
}
static void dump_stream_group(const AVFormatContext *ic, uint8_t *printed,
- int i, int index, int is_output)
+ int i, int index, int is_output, int log_level)
{
const AVStreamGroup *stg = ic->stream_groups[i];
+ const char *group_indent = log_level != AV_LOG_INFO ? " " : "";
+ const char *extra_indent = log_level != AV_LOG_INFO ? " " : " ";
int flags = (is_output ? ic->oformat->flags : ic->iformat->flags);
char buf[512];
int ret;
- av_log(NULL, AV_LOG_INFO, " Stream group #%d:%d", index, i);
+ av_log(NULL, log_level, "%s Stream group #%d:%d", group_indent, index, i);
if (flags & AVFMT_SHOW_IDS)
- av_log(NULL, AV_LOG_INFO, "[0x%"PRIx64"]", stg->id);
- av_log(NULL, AV_LOG_INFO, ":");
+ av_log(NULL, log_level, "[0x%"PRIx64"]", stg->id);
+ av_log(NULL, log_level, ":");
switch (stg->type) {
case AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT: {
const AVIAMFAudioElement *audio_element = stg->params.iamf_audio_element;
- av_log(NULL, AV_LOG_INFO, " IAMF Audio Element:");
- dump_disposition(stg->disposition, AV_LOG_INFO);
- av_log(NULL, AV_LOG_INFO, "\n");
- dump_metadata(NULL, stg->metadata, " ", AV_LOG_INFO);
+ av_log(NULL, log_level, " IAMF Audio Element:");
+ dump_disposition(stg->disposition, log_level);
+ av_log(NULL, log_level, "\n");
+ dump_metadata(NULL, stg->metadata, " ", log_level);
for (int j = 0; j < audio_element->nb_layers; j++) {
const AVIAMFLayer *layer = audio_element->layers[j];
int channel_count = layer->ch_layout.nb_channels;
- av_log(NULL, AV_LOG_INFO, " Layer %d:", j);
+ av_log(NULL, log_level, " Layer %d:", j);
ret = av_channel_layout_describe(&layer->ch_layout, buf, sizeof(buf));
if (ret >= 0)
- av_log(NULL, AV_LOG_INFO, " %s", buf);
- av_log(NULL, AV_LOG_INFO, "\n");
- for (int k = 0; channel_count > 0 && k < stg->nb_entries; k++) {
+ av_log(NULL, log_level, " %s", buf);
+ av_log(NULL, log_level, "\n");
+ for (int k = 0; log_level == AV_LOG_INFO && channel_count > 0 && k < stg->nb_entries; k++) {
const AVStreamGroupEntry *entry = stg->entries[k];
if (entry->type != AV_STREAM_GROUP_ENTRY_STREAM)
continue;
@@ -727,14 +729,14 @@ static void dump_stream_group(const AVFormatContext *ic, uint8_t *printed,
}
case AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION: {
const AVIAMFMixPresentation *mix_presentation = stg->params.iamf_mix_presentation;
- av_log(NULL, AV_LOG_INFO, " IAMF Mix Presentation:");
- dump_disposition(stg->disposition, AV_LOG_INFO);
- av_log(NULL, AV_LOG_INFO, "\n");
- dump_metadata(NULL, stg->metadata, " ", AV_LOG_INFO);
- dump_dictionary(NULL, mix_presentation->annotations, "Annotations", " ", AV_LOG_INFO);
+ av_log(NULL, log_level, " IAMF Mix Presentation:");
+ dump_disposition(stg->disposition, log_level);
+ av_log(NULL, log_level, "\n");
+ dump_metadata(NULL, stg->metadata, " ", log_level);
+ dump_dictionary(NULL, mix_presentation->annotations, "Annotations", " ", log_level);
for (int j = 0; j < mix_presentation->nb_submixes; j++) {
AVIAMFSubmix *sub_mix = mix_presentation->submixes[j];
- av_log(NULL, AV_LOG_INFO, " Submix %d:\n", j);
+ av_log(NULL, log_level, " Submix %d:\n", j);
for (int k = 0; k < sub_mix->nb_elements; k++) {
const AVIAMFSubmixElement *submix_element = sub_mix->elements[k];
const AVStreamGroup *audio_element = NULL;
@@ -745,24 +747,24 @@ static void dump_stream_group(const AVFormatContext *ic, uint8_t *printed,
break;
}
if (audio_element) {
- av_log(NULL, AV_LOG_INFO, " IAMF Audio Element #%d:%d",
+ av_log(NULL, log_level, " IAMF Audio Element #%d:%d",
index, audio_element->index);
if (flags & AVFMT_SHOW_IDS)
- av_log(NULL, AV_LOG_INFO, "[0x%"PRIx64"]", audio_element->id);
- av_log(NULL, AV_LOG_INFO, "\n");
- dump_dictionary(NULL, submix_element->annotations, "Annotations", " ", AV_LOG_INFO);
+ av_log(NULL, log_level, "[0x%"PRIx64"]", audio_element->id);
+ av_log(NULL, log_level, "\n");
+ dump_dictionary(NULL, submix_element->annotations, "Annotations", " ", log_level);
}
}
for (int k = 0; k < sub_mix->nb_layouts; k++) {
const AVIAMFSubmixLayout *submix_layout = sub_mix->layouts[k];
- av_log(NULL, AV_LOG_INFO, " Layout #%d:", k);
+ av_log(NULL, log_level, " Layout #%d:", k);
if (submix_layout->layout_type == 2 ||
submix_layout->layout_type == 3) {
ret = av_channel_layout_describe(&submix_layout->sound_system, buf, sizeof(buf));
if (ret >= 0)
- av_log(NULL, AV_LOG_INFO, " %s", buf);
+ av_log(NULL, log_level, " %s", buf);
}
- av_log(NULL, AV_LOG_INFO, "\n");
+ av_log(NULL, log_level, "\n");
}
}
break;
@@ -771,7 +773,7 @@ static void dump_stream_group(const AVFormatContext *ic, uint8_t *printed,
const AVStreamGroupTileGrid *tile_grid = stg->params.tile_grid;
AVCodecContext *avctx = avcodec_alloc_context3(NULL);
const char *ptr = NULL;
- av_log(NULL, AV_LOG_INFO, " Tile Grid:");
+ av_log(NULL, log_level, " Tile Grid:");
if (avctx && stg->nb_entries && stg->entries[0]->type == AV_STREAM_GROUP_ENTRY_STREAM) {
const AVStream *st = stg->entries[0]->stream;
if (!avcodec_parameters_to_context(avctx, st->codecpar)) {
@@ -788,13 +790,13 @@ static void dump_stream_group(const AVFormatContext *ic, uint8_t *printed,
}
avcodec_free_context(&avctx);
if (ptr)
- av_log(NULL, AV_LOG_INFO, "%s", ptr);
- dump_disposition(stg->disposition, AV_LOG_INFO);
- av_log(NULL, AV_LOG_INFO, "\n");
- dump_metadata(NULL, stg->metadata, " ", AV_LOG_INFO);
+ av_log(NULL, log_level, "%s", ptr);
+ dump_disposition(stg->disposition, log_level);
+ av_log(NULL, log_level, "\n");
+ dump_metadata(NULL, stg->metadata, extra_indent, log_level);
dump_sidedata(NULL, stg->coded_side_data, stg->nb_coded_side_data,
tile_grid->width, tile_grid->height, (AVRational) {0,1},
- " ", AV_LOG_INFO);
+ extra_indent, log_level);
for (int i = 0; i < tile_grid->nb_tiles; i++) {
const AVStream *st = NULL;
if (tile_grid->offsets[i].idx < stg->nb_entries) {
@@ -814,7 +816,7 @@ static void dump_stream_group(const AVFormatContext *ic, uint8_t *printed,
continue;
const AVStream *st = entry->stream;
if (!printed[st->index]) {
- dump_stream_format(ic, st->index, i, index, is_output, AV_LOG_INFO);
+ dump_stream_format(ic, st->index, i, index, is_output, log_level);
printed[st->index] = 1;
}
}
@@ -844,8 +846,13 @@ static void dump_stream_group(const AVFormatContext *ic, uint8_t *printed,
}
avcodec_free_context(&avctx);
if (ptr)
- av_log(NULL, AV_LOG_INFO, "%s", ptr);
- av_log(NULL, AV_LOG_INFO, "\n");
+ av_log(NULL, log_level, "%s", ptr);
+ dump_disposition(stg->disposition, log_level);
+ av_log(NULL, log_level, "\n");
+ dump_metadata(NULL, stg->metadata, extra_indent, log_level);
+ dump_sidedata(NULL, stg->coded_side_data, stg->nb_coded_side_data,
+ layered_video->width, layered_video->height, (AVRational) {0,1},
+ extra_indent, log_level);
for (int i = 0; i < stg->nb_entries; i++) {
const AVStreamGroupEntry *entry = stg->entries[i];
if (entry->type != AV_STREAM_GROUP_ENTRY_STREAM)
@@ -857,26 +864,41 @@ static void dump_stream_group(const AVFormatContext *ic, uint8_t *printed,
break;
}
case AV_STREAM_GROUP_PARAMS_TREF: {
- av_log(NULL, AV_LOG_INFO, " Track Reference:\n");
+ av_log(NULL, log_level, " Track Reference:\n");
for (int i = 0; i < stg->nb_entries; i++) {
const AVStreamGroupEntry *entry = stg->entries[i];
if (entry->type != AV_STREAM_GROUP_ENTRY_STREAM)
continue;
const AVStream *st = entry->stream;
- dump_stream_format(ic, st->index, i, index, is_output, AV_LOG_INFO);
+ dump_stream_format(ic, st->index, i, index, is_output, log_level);
printed[st->index] = 1;
}
break;
}
case AV_STREAM_GROUP_PARAMS_GAIN_MAP: {
- av_log(NULL, AV_LOG_INFO, " Gain Map:\n");
+ const AVStreamGroupLayeredVideo *layered_video = stg->params.layered_video;
+ const char *ptr = NULL;
+ av_log(NULL, AV_LOG_INFO, " Gain Map:");
+ buf[0] = 0;
+ av_strlcatf(buf, sizeof(buf), " %dx%d", layered_video->width, layered_video->height);
+ ptr = av_stristr(buf, " ");
+ if (ptr)
+ av_log(NULL, log_level, "%s", ptr);
+ dump_disposition(stg->disposition, log_level);
+ av_log(NULL, log_level, "\n");
+ dump_metadata(NULL, stg->metadata, extra_indent, log_level);
+ dump_sidedata(NULL, stg->coded_side_data, stg->nb_coded_side_data,
+ layered_video->width, layered_video->height, (AVRational) {0,1},
+ extra_indent, log_level);
for (int i = 0; i < stg->nb_entries; i++) {
const AVStreamGroupEntry *entry = stg->entries[i];
- if (entry->type != AV_STREAM_GROUP_ENTRY_STREAM)
- continue;
- const AVStream *st = entry->stream;
- dump_stream_format(ic, st->index, i, index, is_output, AV_LOG_INFO);
- printed[st->index] = 1;
+ if (entry->type == AV_STREAM_GROUP_ENTRY_STREAM) {
+ const AVStream *st = entry->stream;
+ dump_stream_format(ic, st->index, i, index, is_output, log_level);
+ printed[st->index] = 1;
+ } else if (entry->type == AV_STREAM_GROUP_ENTRY_STREAM_GROUP)
+ dump_stream_group(ic, printed, entry->stream_group->index, index,
+ is_output, AV_LOG_VERBOSE);
}
break;
}
@@ -968,7 +990,7 @@ void av_dump_format(AVFormatContext *ic, int index,
}
for (i = 0; i < ic->nb_stream_groups; i++)
- dump_stream_group(ic, printed, i, index, is_output);
+ dump_stream_group(ic, printed, i, index, is_output, AV_LOG_INFO);
for (i = 0; i < ic->nb_streams; i++)
if (!printed[i])