Opened 14 months ago

Closed 9 months ago

#11646 closed defect (fixed)

Full range RGB to YUV conversion using swscale has a slight green tint.

Reported by: Jorn Owned by:
Priority: normal Component: swscale
Version: git-master Keywords:
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Summary of the bug:
Converting full range RGB to YUV using swscale causes the output to have a slight green tint.

How to reproduce:

% ffmpeg -loop 1 -t 10 -i gradient.png -sws_flags spline+accurate_rnd+full_chroma_int+full_chroma_inp+bitexact -vf "setparams=colorspace=bt709:range=pc,scale,format=yuv444p" -crf 0 output.mp4
ffmpeg version N-120037-g36c8eef42c-20250625 Copyright (c) 2000-2025 the FFmpeg developers
  built with gcc 15.1.0 (crosstool-NG 1.27.0.42_35c1e72)
  configuration: --prefix=/ffbuild/prefix --pkg-config-flags=--static --pkg-config=pkg-config --cross-prefix=x86_64-w64-mingw32- --arch=x86_64 --target-os=mingw32 --enable-gpl --enable-version3 --disable-debug --disable-w32threads --enable-pthreads --enable-iconv --enable-zlib --enable-libfribidi --enable-gmp --enable-libxml2 --enable-lzma --enable-fontconfig --enable-libharfbuzz --enable-libfreetype --enable-libvorbis --enable-opencl --disable-libpulse --enable-libvmaf --disable-libxcb --disable-xlib --enable-amf --enable-libaom --enable-libaribb24 --enable-avisynth --enable-chromaprint --enable-libdav1d --enable-libdavs2 --enable-libdvdread --enable-libdvdnav --disable-libfdk-aac --enable-ffnvcodec --enable-cuda-llvm --enable-frei0r --enable-libgme --enable-libkvazaar --enable-libaribcaption --enable-libass --enable-libbluray --enable-libjxl --enable-libmp3lame --enable-libopus --enable-librist --enable-libssh --enable-libtheora --enable-libvpx --enable-libwebp --enable-libzmq --enable-lv2 --enable-libvpl --enable-openal --enable-liboapv --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopenmpt --enable-librav1e --enable-librubberband --enable-schannel --enable-sdl2 --enable-libsnappy --enable-libsoxr --enable-libsrt --enable-libsvtav1 --enable-libtwolame --enable-libuavs3d --disable-libdrm --enable-vaapi --enable-libvidstab --enable-vulkan --enable-libshaderc --enable-libplacebo --enable-libvvenc --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libzimg --enable-libzvbi --extra-cflags=-DLIBTWOLAME_STATIC --extra-cxxflags= --extra-libs=-lgomp --extra-ldflags=-pthread --extra-ldexeflags= --cc=x86_64-w64-mingw32-gcc --cxx=x86_64-w64-mingw32-g++ --ar=x86_64-w64-mingw32-gcc-ar --ranlib=x86_64-w64-mingw32-gcc-ranlib --nm=x86_64-w64-mingw32-gcc-nm --extra-version=20250625
  libavutil      60.  3.100 / 60.  3.100
  libavcodec     62.  4.100 / 62.  4.100
  libavformat    62.  1.100 / 62.  1.100
  libavdevice    62.  0.100 / 62.  0.100
  libavfilter    11.  0.100 / 11.  0.100
  libswscale      9.  0.100 /  9.  0.100
  libswresample   6.  0.100 /  6.  0.100
Input #0, png_pipe, from 'gradient.png':
  Duration: N/A, bitrate: N/A
  Stream #0:0: Video: png, rgb24(pc, gbr/unknown/unknown), 1024x256 [SAR 1:1 DAR 4:1], 25 fps, 25 tbr, 25 tbn
Stream mapping:
  Stream #0:0 -> #0:0 (png (native) -> h264 (libx264))
Press [q] to stop, [?] for help
[libx264 @ 0000016e93513600] using SAR=1/1
[libx264 @ 0000016e93513600] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[libx264 @ 0000016e93513600] profile High 4:4:4 Predictive, level 3.0, 4:4:4, 8-bit
[libx264 @ 0000016e93513600] 64 - core 165 - H.264/MPEG-4 AVC codec - Copyleft 2003-2025 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=0 mixed_ref=1 me_range=16 chroma_me=1 trellis=0 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=0 chroma_qp_offset=0 threads=8 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc=cqp mbtree=0 qp=0
Output #0, mp4, to 'output.mp4':
  Metadata:
    encoder         : Lavf62.1.100
  Stream #0:0: Video: h264 (avc1 / 0x31637661), yuv444p(pc, bt709/unknown/unknown, progressive), 1024x256 [SAR 1:1 DAR 4:1], q=2-31, 25 fps, 12800 tbn
    Metadata:
      encoder         : Lavc62.4.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
[out#0/mp4 @ 0000016e934c7f80] video:38KiB audio:0KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: 4.803696%
frame=  250 fps=0.0 q=-1.0 Lsize=      40KiB time=00:00:10.00 bitrate=  32.5kbits/s speed=  25x elapsed=0:00:00.40    
[libx264 @ 0000016e93513600] frame I:1     Avg QP: 0.00  size: 31759
[libx264 @ 0000016e93513600] frame P:249   Avg QP: 0.00  size:    26
[libx264 @ 0000016e93513600] mb I  I16..4: 79.7% 20.2%  0.1%
[libx264 @ 0000016e93513600] mb P  I16..4:  0.0%  0.0%  0.0%  P16..4:  0.0%  0.0%  0.0%  0.0%  0.0%    skip:100.0%
[libx264 @ 0000016e93513600] 8x8 transform intra:20.2%
[libx264 @ 0000016e93513600] coded y,u,v intra: 99.0% 0.0% 0.0% inter: 0.0% 0.0% 0.0%
[libx264 @ 0000016e93513600] i16 v,h,dc,p: 26%  0% 10% 64%
[libx264 @ 0000016e93513600] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 36% 11% 37%  0%  1% 14%  0%  0%  0%
[libx264 @ 0000016e93513600] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu:  0%  0% 100%  0%  0%  0%  0%  0%  0%
[libx264 @ 0000016e93513600] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 0000016e93513600] kb/s:30.58

This produces a slightly greenish gradient in the output when using ffmpeg version N-120037-g36c8eef42c-20250625, using ffmpeg version n7.1.1-54-g6400860b9d-20250625 produces the correct gradient matching gradient.png, as does using zscale instead of scale.

Seems to have broken between ffmpeg version N-117967-g4de67e8746-20241130 and ffmpeg version N-118197-gbb85423142-20241231.

Attachments (1)

gradient.png (59.5 KB ) - added by Jorn 14 months ago.

Download all attachments as: .zip

Change History (8)

by Jorn, 14 months ago

Attachment: gradient.png added

comment:1 by Balling, 14 months ago

Status: newopen

Yes, it somehow writes 127 values into U and V where it should write 128 instead.

Maybe one needs to set transfer function into BT.709? Haasn?

comment:3 by Balling, 14 months ago

Well, it says there

NOTE2: the same issue still exists in rgb2yuv conversions, which is not

addressed in this commit.

Last edited 14 months ago by Balling (previous) (diff)

in reply to:  3 comment:4 by kasper93, 14 months ago

Replying to Balling:

Well, it says there

NOTE2: the same issue still exists in rgb2yuv conversions, which is not

addressed in this commit.

Well, the regression is after this commit, so it clearly affects rgb2yuv and in wrong way too.

comment:5 by Balling, 14 months ago

Well, the regression is after this commit, so it clearly affects rgb2yuv and in wrong way too.

It disabled more accurate SIMD, so that broke rgb2yuv. Here the issue is in rgb2yuv, not yuv2rgb. I remember that when that commit was done someone cerified that it is closer to what H.273 wants. Probably just this thing: https://github.com/AviSynth/AviSynthPlus/commit/ac84b4796efdf3fae2cedb072976e179195286ed

Last edited 14 months ago by Balling (previous) (diff)

comment:7 by Balling, 9 months ago

Resolution: fixed
Status: openclosed

Fixed indeed in 4bee01084475169fe26e859446b3833ad2804a52

Now we need to test some other bugs where this is probably fixing issues on top of this. dunno?

Note: See TracTickets for help on using tickets.