PR #24467 opened by Cuptu
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24467
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24467.patch

`-show_entries stream=...` also matches streams inside groups, enabling
group output even when it was not requested. With the MOV timecode groups
in `fcp_export8-236.mov`, the selected video stream is printed four times.

Require an explicit selection to enable groups through their stream
sections. Shared stream names still filter fields when groups are enabled
with `-show_stream_groups` or a group section name.

Add three FATE tests and update the affected MOV references.

Fixes: https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/24352

Tested with MSYS2/Clang on Windows: all 5,791 local FATE tests pass after
rerunning failures with LF source files and relative sample paths. The
build uses default components and the external libraries available here.


>From 116e96e4319dfac1b32515e8da5a1efd93819f82 Mon Sep 17 00:00:00 2001
From: cuptu <[email protected]>
Date: Sun, 13 Sep 2026 10:14:21 +0800
Subject: [PATCH] fftools/ffprobe: avoid implicitly enabling groups for stream
 entries

-show_entries stream=... also matches streams inside groups, enabling
group output even when it was not requested. With the MOV timecode groups
in fcp_export8-236.mov, the selected video stream is printed four times.

Require an explicit selection to enable groups through their stream
sections. Shared stream names still filter fields when groups are enabled
with -show_stream_groups or a group section name.

Add three FATE tests and update the affected MOV references.

Fixes: https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/24352
Signed-off-by: cuptu <[email protected]>
---
 doc/ffprobe.texi                              |  6 ++++
 fftools/ffprobe.c                             | 30 ++++++++++++-------
 tests/fate/mov.mak                            | 12 ++++++++
 .../fate/ffprobe-group-stream-entries-tmcd    |  6 ++++
 tests/ref/fate/ffprobe-show-groups-tmcd       |  7 +++++
 tests/ref/fate/ffprobe-stream-entries-tmcd    |  1 +
 .../ref/fate/mov-mp4-disposition-mpegts-remux |  3 --
 tests/ref/fate/mov-mp4-ttml-dfxp              |  3 --
 tests/ref/fate/mov-mp4-ttml-stpp              |  3 --
 tests/ref/fate/mov-mp4-with-mov-in24-ver      |  5 ----
 10 files changed, 52 insertions(+), 24 deletions(-)
 create mode 100644 tests/ref/fate/ffprobe-group-stream-entries-tmcd
 create mode 100644 tests/ref/fate/ffprobe-show-groups-tmcd
 create mode 100644 tests/ref/fate/ffprobe-stream-entries-tmcd

diff --git a/doc/ffprobe.texi b/doc/ffprobe.texi
index 41dbba4656..9b95b82938 100644
--- a/doc/ffprobe.texi
+++ b/doc/ffprobe.texi
@@ -196,6 +196,12 @@ sections:
 stream_tags=title
 @end example
 
+Selecting @code{stream} or @code{streams} does not by itself enable stream
+group output. To also show streams within groups, use
+@code{-show_stream_groups} or select their unique section name, for example
+@code{-show_entries stream_group_stream=index}. The shared names still
+select fields within stream groups when group output is enabled.
+
 @item -show_packets
 Show information about each packet contained in the input multimedia
 stream.
diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c
index e918d98cab..8d65586742 100644
--- a/fftools/ffprobe.c
+++ b/fftools/ffprobe.c
@@ -332,6 +332,7 @@ static const AVTextFormatSection sections[] = {
 
 typedef struct EntrySelection {
     int show_all_entries;
+    int explicitly_selected; ///< Selected by unique name or through a 
selected parent.
     AVDictionary *entries_to_show;
 } EntrySelection;
 
@@ -2908,15 +2909,17 @@ static int opt_format(void *optctx, const char *opt, 
const char *arg)
 }
 
 static inline void mark_section_show_entries(SectionID section_id,
-                                             int show_all_entries, 
AVDictionary *entries)
+                                             int show_all_entries, 
AVDictionary *entries,
+                                             int explicitly_selected)
 {
     EntrySelection *selection = &selected_entries[section_id];
 
     selection->show_all_entries = show_all_entries;
+    selection->explicitly_selected |= explicitly_selected;
     if (show_all_entries) {
         const AVTextFormatSection *section = &sections[section_id];
         for (const int *id = section->children_ids; *id != -1; id++)
-            mark_section_show_entries(*id, show_all_entries, entries);
+            mark_section_show_entries(*id, show_all_entries, entries, 
explicitly_selected);
     } else {
         av_dict_copy(&selection->entries_to_show, entries, 0);
     }
@@ -2935,7 +2938,9 @@ static int match_section(const char *section_name,
                    "'%s' matches section with unique name '%s'\n", 
section_name,
                    (char *)av_x_if_null(section->unique_name, section->name));
             ret++;
-            mark_section_show_entries(section->id, show_all_entries, entries);
+            mark_section_show_entries(section->id, show_all_entries, entries,
+                                      !section->unique_name ||
+                                      !strcmp(section_name, 
section->unique_name));
         }
     }
     return ret;
@@ -3261,15 +3266,15 @@ static int opt_codec(void *optctx, const char *opt, 
const char *arg)
 
 static int opt_show_versions(void *optctx, const char *opt, const char *arg)
 {
-    mark_section_show_entries(SECTION_ID_PROGRAM_VERSION, 1, NULL);
-    mark_section_show_entries(SECTION_ID_LIBRARY_VERSION, 1, NULL);
+    mark_section_show_entries(SECTION_ID_PROGRAM_VERSION, 1, NULL, 1);
+    mark_section_show_entries(SECTION_ID_LIBRARY_VERSION, 1, NULL, 1);
     return 0;
 }
 
 #define DEFINE_OPT_SHOW_SECTION(section, target_section_id)             \
     static int opt_show_##section(void *optctx, const char *opt, const char 
*arg) \
     {                                                                   \
-        mark_section_show_entries(SECTION_ID_##target_section_id, 1, NULL); \
+        mark_section_show_entries(SECTION_ID_##target_section_id, 1, NULL, 1); 
\
         return 0;                                                       \
     }
 
@@ -3340,22 +3345,27 @@ static const OptionDef real_options[] = {
     { NULL, },
 };
 
-static inline int check_section_show_entries(int section_id)
+static inline int check_section_show_entries(int section_id, int 
require_explicit)
 {
     const EntrySelection *selection = &selected_entries[section_id];
 
-    if (selection->show_all_entries || selection->entries_to_show)
+    /* Selecting a shared stream section must not implicitly enable groups. */
+    if (section_id == SECTION_ID_STREAM_GROUP_STREAMS)
+        require_explicit = 1;
+
+    if ((!require_explicit || selection->explicitly_selected) &&
+        (selection->show_all_entries || selection->entries_to_show))
         return 1;
 
     const AVTextFormatSection *section = &sections[section_id];
     for (const int *id = section->children_ids; *id != -1; id++)
-        if (check_section_show_entries(*id))
+        if (check_section_show_entries(*id, require_explicit))
             return 1;
     return 0;
 }
 
 #define SET_DO_SHOW(id, varname) do {                                   \
-        if (check_section_show_entries(SECTION_ID_##id))                \
+        if (check_section_show_entries(SECTION_ID_##id, 0))             \
             do_show_##varname = 1;                                      \
     } while (0)
 
diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak
index 3c0ac3ec13..ecbf686814 100644
--- a/tests/fate/mov.mak
+++ b/tests/fate/mov.mak
@@ -47,6 +47,18 @@ FATE_MOV_FFPROBE-$(call DEMDEC, MOV, HEVC) += 
fate-mov-dovi-hvce-mp4-read
 
 FATE_MOV_FFPROBE-$(call DEMDEC, MOV, H264) += fate-mov-vfr-bframes-duration
 
+FATE_MOV_FFPROBE-$(CONFIG_MOV_DEMUXER) += fate-ffprobe-stream-entries-tmcd \
+                                       fate-ffprobe-group-stream-entries-tmcd \
+                                       fate-ffprobe-show-groups-tmcd
+
+fate-ffprobe-stream-entries-tmcd: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -v 
error -select_streams v:0 \
+    -show_entries stream=index -of compact 
$(TARGET_SAMPLES)/mov/fcp_export8-236.mov
+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
 \
+    -of compact $(TARGET_SAMPLES)/mov/fcp_export8-236.mov
+
 FATE_MOV_FASTSTART = fate-mov-faststart-4gb-overflow \
 
 FATE_SAMPLES_FFMPEG += $(FATE_MOV-yes) $(FATE_MOV_REMUX-yes)
diff --git a/tests/ref/fate/ffprobe-group-stream-entries-tmcd 
b/tests/ref/fate/ffprobe-group-stream-entries-tmcd
new file mode 100644
index 0000000000..6ba54f4200
--- /dev/null
+++ b/tests/ref/fate/ffprobe-group-stream-entries-tmcd
@@ -0,0 +1,6 @@
+stream_group|
+stream|index=0|
+stream_group|
+stream|index=0|
+stream_group|
+stream|index=0|
diff --git a/tests/ref/fate/ffprobe-show-groups-tmcd 
b/tests/ref/fate/ffprobe-show-groups-tmcd
new file mode 100644
index 0000000000..64b32fe905
--- /dev/null
+++ b/tests/ref/fate/ffprobe-show-groups-tmcd
@@ -0,0 +1,7 @@
+stream_group|
+stream|index=0|
+stream_group|
+stream|index=0|
+stream_group|
+stream|index=0|
+stream|index=0|
diff --git a/tests/ref/fate/ffprobe-stream-entries-tmcd 
b/tests/ref/fate/ffprobe-stream-entries-tmcd
new file mode 100644
index 0000000000..64b0ce91b9
--- /dev/null
+++ b/tests/ref/fate/ffprobe-stream-entries-tmcd
@@ -0,0 +1 @@
+stream|index=0|
diff --git a/tests/ref/fate/mov-mp4-disposition-mpegts-remux 
b/tests/ref/fate/mov-mp4-disposition-mpegts-remux
index bbd9c89fa7..7107bf4497 100644
--- a/tests/ref/fate/mov-mp4-disposition-mpegts-remux
+++ b/tests/ref/fate/mov-mp4-disposition-mpegts-remux
@@ -19,9 +19,6 @@
 {
     "programs": [
 
-    ],
-    "stream_groups": [
-
     ],
     "streams": [
         {
diff --git a/tests/ref/fate/mov-mp4-ttml-dfxp b/tests/ref/fate/mov-mp4-ttml-dfxp
index b019b3f6cc..2d60f3d964 100644
--- a/tests/ref/fate/mov-mp4-ttml-dfxp
+++ b/tests/ref/fate/mov-mp4-ttml-dfxp
@@ -22,9 +22,6 @@
     ],
     "programs": [
 
-    ],
-    "stream_groups": [
-
     ],
     "streams": [
         {
diff --git a/tests/ref/fate/mov-mp4-ttml-stpp b/tests/ref/fate/mov-mp4-ttml-stpp
index 827296253e..0a8e423449 100644
--- a/tests/ref/fate/mov-mp4-ttml-stpp
+++ b/tests/ref/fate/mov-mp4-ttml-stpp
@@ -23,9 +23,6 @@ cbd2c7ff864a663b0d893deac5a0caec 
*tests/data/fate/mov-mp4-ttml-stpp.mp4
     ],
     "programs": [
 
-    ],
-    "stream_groups": [
-
     ],
     "streams": [
         {
diff --git a/tests/ref/fate/mov-mp4-with-mov-in24-ver 
b/tests/ref/fate/mov-mp4-with-mov-in24-ver
index 450560b149..b5522454df 100644
--- a/tests/ref/fate/mov-mp4-with-mov-in24-ver
+++ b/tests/ref/fate/mov-mp4-with-mov-in24-ver
@@ -1,8 +1,3 @@
-[STREAM_GROUP]
-[STREAM]
-codec_name=pcm_s24le
-[/STREAM]
-[/STREAM_GROUP]
 [STREAM]
 codec_name=pcm_s24le
 [/STREAM]
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to