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]
