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

This is 1/9 in the GoPro Max review order. It applies on current master by 
itself.

Piped stderr is fully buffered, so a reader that draws a progress line from 
another pipe sees that line move before Input #0 arrives. Flush after each log 
write. On Windows the console paints warnings with attribute 14 (bright 
yellow). The 8-color ANSI path used for a pipe emitted 0;33. Use intensity 1 
for AV_LOG_WARNING on Windows so the piped color matches the console.

Preferred review order, each request on its own:

1/9 avutil/log: flush stderr and match Windows warning yellow
2/9 avfilter: add yuvrgb_cuda
3/9 avfilter: add gopromax2_cuda GoPro Max 2 EAC stitch
4/9 avcodec: add mjpeg_nvjpeg NVIDIA JPEG encoder
5/9 avcodec/bsf: add jpegapp to inject JPEG APP segments
6/9 avfilter: add gopromax2 GoPro Max 2 EAC stitch
7/9 avfilter: add gopromax2_opencl GoPro Max 2 EAC stitch
8/9 avfilter: add gopromax_opencl GoPro Max 1 stitch
9/9 avcodec/mjpegenc: encode packed RGB via YUV conversion

After 1-5, mapillary_tools processes GoPro Max 2 files GPU-only in my setup: 
scale_cuda=yuv444p10, yuvrgb_cuda=rgb0, gopromax2_cuda, mjpeg_nvjpeg. jpegapp 
inserts the APP1 segment while encoding, so the JPEG ffmpeg writes needs no 
postprocessing.

After 6, the Max 2 CPU fallback works. After 7, Max 2 via OpenCL works. After 
8, original GoPro Max (Max 1) via OpenCL works.

9/9 is needed when 4/9 cannot be used, for example because no nvjpeg library is 
present, and encoding falls back to the software mjpeg encoder. That encoder 
then receives packed RGB (rgb24). Upstream mjpegenc does not accept it; this 
change converts it to YUV first.

The six patches I sent to ffmpeg-devel on 20 September are obsolete. Once the 
filter requests are merged, I will send one short documentation request that 
only adds the cross-references between these sections.


From 1bda2c975e7bbe51d0726c7671c2d0c305507d3c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Reinhard=20Ni=C3=9Fl?= <[email protected]>
Date: Fri, 25 Sep 2026 23:45:47 +0200
Subject: [PATCH] avutil/log: flush stderr and match Windows warning yellow
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Piped stderr is fully buffered, so a reader that draws a progress line
from another pipe sees that line move before Input #0 arrives. Flush
after each log write.

On Windows the console paints warnings with attribute 14 (bright yellow).
The 8-color ANSI path used for a pipe emitted 0;33. Use intensity 1 for
AV_LOG_WARNING on Windows so the piped color matches the console.

Co-authored-by: Cursor <[email protected]>
Signed-off-by: Reinhard Nißl <[email protected]>
---
 libavutil/log.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/libavutil/log.c b/libavutil/log.c
index 966522b013..c7b0617ad5 100644
--- a/libavutil/log.c
+++ b/libavutil/log.c
@@ -189,11 +189,17 @@ static void check_color_terminal(void)
 static void ansi_fputs(int level, int tint, const char *str, int 
local_use_color)
 {
     if (local_use_color == 1) {
+        uint32_t intensity = (color[level] >> 4) & 15;
+        uint32_t fg       = color[level] & 15;
+#if defined(_WIN32)
+        /* Piped stderr is 8-color ANSI. Linux keeps 0;33m; Windows console
+         * already uses win_color 14 (bright yellow), so match that here. */
+        if (level == AV_LOG_WARNING / 8)
+            intensity = 1;
+#endif
         fprintf(stderr,
                 "\033[%"PRIu32";3%"PRIu32"m%s\033[0m",
-                (color[level] >> 4) & 15,
-                color[level] & 15,
-                str);
+                intensity, fg, str);
     } else if (tint && use_color == 256) {
         fprintf(stderr,
                 "\033[48;5;%"PRIu32"m\033[38;5;%dm%s\033[0m",
@@ -428,6 +434,11 @@ void av_log_default_callback(void* ptr, int level, const 
char* fmt, va_list vl)
     sanitize(part[3].str);
     colored_fputs(av_clip(level >> 3, 0, NB_LEVELS - 1), tint >> 8, 
part[3].str);
 
+    /* Piped stderr is fully buffered; mapillary_tools reads it for the
+     * progress bar. Without a flush, Input #0 sits until the encode has
+     * already moved the bar. */
+    fflush(stderr);
+
 #if CONFIG_VALGRIND_BACKTRACE
     if (level <= BACKTRACE_LOGLEVEL)
         VALGRIND_PRINTF_BACKTRACE("%s", "");
-- 
2.52.0

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

Reply via email to