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

With automatic stats and `-loglevel panic`, ffplay writes `ESC[2K\r` to stderr 
even though the following format dump is suppressed. The same unconditional 
writes affect stream and demuxer metadata updates, including when stderr is 
redirected. Fixes #24234.

Introduce a shared helper that clears the line only when stderr is a terminal 
and the log level permits `AV_LOG_INFO` output. Use it at all three dump sites. 
Explicit `-stats` output at lower log levels remains available; the suppressed 
dumps no longer cause a clear. Platforms without `isatty` omit the escape 
sequence.

Verified the regression by building c75ada5040d1 and its parent 32f73138f593: a 
generated one-second PCM WAV produces five stderr bytes on the former and none 
on the latter. Master 1c767fe66452 and release/8.1 and release/9.0 also 
reproduce.

Validation on Linux AArch64 with SDL 2.30.0 and dummy audio/video drivers:

- Built ffplay and passed `git diff --check`.
- Passed 36 runtime combinations of quiet/panic/error/info, 
automatic/forced/disabled stats, and pipe/file/pseudo-terminal stderr.
- Tested stream metadata updates using the existing FATE sample 
`ogg-vorbis/chained-meta.ogg`.
- Tested demuxer metadata updates using a local HTTP/ICY server, including 
forced and disabled stats.
- Confirmed empty stderr at panic with automatic stats, retained explicitly 
requested statistics, retained visible metadata updates, and terminal clearing 
only for visible dumps on a terminal.

The minimal build used `--disable-everything --disable-autodetect --enable-sdl2 
--enable-ffplay --disable-ffmpeg --disable-ffprobe --disable-doc 
--enable-protocol=file,http,tcp --enable-demuxer=wav,mp3,ogg 
--enable-decoder=pcm_s16le,mp3float,vorbis --enable-filter=aresample,aformat 
--disable-debug`, followed by `make -j8 ffplay`. Runtime checks used 
`SDL_AUDIODRIVER=dummy SDL_VIDEODRIVER=dummy AV_LOG_FORCE_NOCOLOR=1`. Windows 
runtime behavior was not tested.


>From b48658feea99aed4a543a1b63bcf20a0581b5e10 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Tue, 20 Oct 2026 19:54:24 +0000
Subject: [PATCH] ffplay: guard terminal clearing before format and metadata
 dumps

The direct stderr writes introduced in c75ada5040d1 bypass the log level
and emit ESC[2K even with -loglevel panic or redirected stderr. The same
problem affects stream and demuxer metadata updates during playback.

Use a common helper that only clears a terminal when AV_LOG_INFO output
is enabled. Keep explicit -stats output at lower log levels, but do not
clear for format or metadata dumps that those levels suppress. On systems
without isatty, omit the terminal control sequence.

Fixes #24234.

Verified the regression by building c75ada5040d1 and its parent. Tested
36 combinations of quiet/panic/error/info, automatic/forced/disabled
stats, and pipe/file/PTY stderr on Linux AArch64 with SDL dummy audio.
Also tested chained Vorbis stream metadata and local HTTP/ICY demuxer
metadata updates, including visible terminal output and silent panic
output.

Assisted-by: Fairy
---
 fftools/ffplay.c | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/fftools/ffplay.c b/fftools/ffplay.c
index d17aa1c4224..1b564e3a224 100644
--- a/fftools/ffplay.c
+++ b/fftools/ffplay.c
@@ -25,6 +25,12 @@
 
 #include "config.h"
 #include "config_components.h"
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_IO_H
+#include <io.h>
+#endif
 #include <math.h>
 #include <limits.h>
 #include <signal.h>
@@ -3192,6 +3198,15 @@ static int do_bsf_flush(AVFormatContext *ic, VideoState 
*is)
     return 0;
 }
 
+static void clear_status_line(void)
+{
+#if HAVE_ISATTY
+    /* Only clear the terminal before a visible format or metadata dump. */
+    if (av_log_get_level() >= AV_LOG_INFO && isatty(2))
+        fprintf(stderr, "\x1b[2K\r");
+#endif
+}
+
 /* this thread gets the stream from the disk or the network */
 static int read_thread(void *arg)
 {
@@ -3321,7 +3336,7 @@ static int read_thread(void *arg)
     is->realtime = is_realtime(ic);
 
     if (show_status) {
-        fprintf(stderr, "\x1b[2K\r");
+        clear_status_line();
         av_dump_format(ic, 0, is->filename, 0);
     }
 
@@ -3573,13 +3588,13 @@ static int read_thread(void *arg)
 
         if (show_status) {
             if (ic->event_flags & AVFMT_EVENT_FLAG_METADATA_UPDATED) {
-                fprintf(stderr, "\x1b[2K\r");
+                clear_status_line();
                 dump_dictionary(NULL, ic->metadata,
                                 "\r  New metadata", "    ", AV_LOG_INFO);
             }
             if (ic->streams[pkt->stream_index]->event_flags &
                 AVSTREAM_EVENT_FLAG_METADATA_UPDATED) {
-                fprintf(stderr, "\x1b[2K\r");
+                clear_status_line();
                 snprintf(metadata_description,
                          sizeof(metadata_description),
                          "\r  New metadata for stream %d",
-- 
2.54.0

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

Reply via email to