How to pass colours through with FFmpeg

I've noticed that the videos I've been encoding over the last few months are slightly more yellow compared to their original sources. This is very annoying because I would have expected the default behaviour to pass through colour information. Is this not the case?

I'm transcoding from libvpx to libx264. Here is the output from the last command I ran in which this problem occurred:

ffmpeg -i "source.mkv" -preset ultrafast -to 6:53 -c:v libx264 -crf 15 -c:a copy -vf "crop=320:160:0:40,scale=-2:1080" "test.mp4"
ffmpeg version N-100422-gff6f8c272e-g1eb751955e+1 Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 10.2.0 (Rev6, Built by MSYS2 project)
  configuration:  --pkg-config=pkgconf --cc='ccache gcc' --cxx='ccache g++' --disable-autodetect --enable
-amf --enable-bzlib --enable-cuda --enable-cuvid --enable-d3d11va --enable-dxva2 --enable-iconv --enable-
lzma --enable-nvenc --enable-zlib --enable-sdl2 --enable-ffnvcodec --enable-nvdec --enable-cuda-llvm --en
able-libmp3lame --enable-libopus --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --e
nable-libdav1d --enable-libaom --disable-debug --enable-libfdk-aac --enable-openssl --extra-libs=-liconv
--enable-gpl --enable-nonfree
  libavutil      56. 62.100 / 56. 62.100
  libavcodec     58.115.102 / 58.115.102
  libavformat    58. 65.100 / 58. 65.100
  libavdevice    58. 11.103 / 58. 11.103
  libavfilter     7. 93.100 /  7. 93.100
  libswscale      5.  8.100 /  5.  8.100
  libswresample   3.  8.100 /  3.  8.100
  libpostproc    55.  8.100 / 55.  8.100
Input #0, matroska,webm, from 'source.mkv':
  Metadata:
    ENCODER         : Lavf58.65.100
  Duration: 00:07:49.28, start: 0.000000, bitrate: 240 kb/s
    Stream #0:0(eng): Video: vp9 (Profile 0), yuv420p(tv), 320x240, SAR 1:1 DAR 4:3, 18 fps, 18 tbr, 1k t
bn, 1k tbc (default)
    Metadata:
      DURATION        : 00:07:49.221000000
    Stream #0:1: Audio: aac (LC), 44100 Hz, stereo, fltp (default)
    Metadata:
      HANDLER_NAME    : ISO Media file produced by Google Inc. Created on: 05/11/2019.
      VENDOR_ID       : [0][0][0][0]
      DURATION        : 00:07:49.275000000
Stream mapping:
  Stream #0:0 -> #0:0 (vp9 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
[libx264 @ 000002575cffe040] using SAR=1/1
[libx264 @ 000002575cffe040] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
[libx264 @ 000002575cffe040] profile Constrained Baseline, level 5.0, 4:2:0, 8-bit
[libx264 @ 000002575cffe040] 264 - core 161 r3027 4121277 - H.264/MPEG-4 AVC codec - Copyleft 2003-2020 -
 http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=0:0:0 analyse=0:0 me=dia subme=0 psy=
1 psy_rd=1.00:0.00 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip
=1 chroma_qp_offset=0 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_
compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=250 keyint_min=18 scenecut=0 intra_refresh=0 rc=c
rf mbtree=0 crf=15.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=0
Output #0, mp4, to 'test.mp4':
  Metadata:
    encoder         : Lavf58.65.100
    Stream #0:0(eng): Video: h264 (avc1 / 0x31637661), yuv420p(tv, progressive), 2160x1080 [SAR 1:1 DAR 2
:1], q=2-31, 18 fps, 18432 tbn (default)
    Metadata:
      DURATION        : 00:07:49.221000000
      encoder         : Lavc58.115.102 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
    Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp (default)
    Metadata:
      HANDLER_NAME    : ISO Media file produced by Google Inc. Created on: 05/11/2019.
      VENDOR_ID       : [0][0][0][0]
      DURATION        : 00:07:49.275000000
frame= 7434 fps= 47 q=-1.0 Lsize=  748614kB time=00:06:52.99 bitrate=14849.4kbits/s speed=2.62x
video:741826kB audio:6454kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.044636%
[libx264 @ 000002575cffe040] frame I:30    Avg QP:10.10  size:284105
[libx264 @ 000002575cffe040] frame P:7404  Avg QP:12.51  size:101446
[libx264 @ 000002575cffe040] mb I  I16..4: 100.0%  0.0%  0.0%
[libx264 @ 000002575cffe040] mb P  I16..4: 14.4%  0.0%  0.0%  P16..4: 71.5%  0.0%  0.0%  0.0%  0.0%    sk
ip:14.1%
[libx264 @ 000002575cffe040] coded y,uvDC,uvAC intra: 45.1% 37.2% 14.8% inter: 53.1% 32.5% 0.9%
[libx264 @ 000002575cffe040] i16 v,h,dc,p: 45% 20% 10% 25%
[libx264 @ 000002575cffe040] i8c dc,h,v,p: 47% 17% 21% 15%
[libx264 @ 000002575cffe040] kb/s:14714.37

How do I pass through the colour information of my source so that the colour of the output is always the same as that of my source?


Solution 1:

Since Oct 2020, ffmpeg relays colorimetry properties detected in the source onto the destination, so make sure your ffmpeg is more current than that. 4.4 is the oldest release that has the change.