Im trying to scale video down. No matter what I do the colors are always washed up as a result.

original: original

After scaling:

enter image description here

Code I run for it

ffmpeg -i input.mkv -vf scale=1028:-1 output.mkv

log: log

Original file codec info

Original file codec info

New file codec info

enter image description here

ideally I would want to convert the video to h264 and scale down. I tried googling for x hours, tried a lot of random attemps, and in the end I tracked it down to scale filter. I have no idea how or why the filter messes up the colors.

I also tried some overkill commands(below) I found on the internet, and it is able to convert to h264 perfectly, but once I try to add scaling to that command it will also produce washed up colors like example above.

Overkill example:

ffmpeg -i "input" -c:v libx265 -preset fast -crf 21 -x265-params keyint=60:bframes=3:vbv-bufsize=75000:vbv-maxrate=75000:hdr-opt=1:repeat-headers=1:colorprim=bt2020:transfer=smpte-st-2084:colormatrix=bt2020nc:master-display="G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,500)" -c:a aac -vf colorspace=bt2020,transfer=smpte2084,scale=1280:-1 "small_output"
  • Run the command ffmpeg -hide_banner -pix_fmts and check if you have yuv420p10le in the list. If the source video is encoded using a 10-bit colorspace, this may be an issue with your build of FFmpeg being restricted to 8-bit colorspaces. Adding -pix_fmt + before your -vf filters will also reveal if this is the case, or possibly fix the issue. This answer may also shed more light on the issue. – Zach F. Oct 6 '20 at 20:56
  • -pix_fmts indeed shows IO... yuv420p10le 3 15. This means the ffmpeg is compiled with 10bit colorspaces in mind, right? Adding -pix_fmt + (or -pix_fmt yuv420p10le or yuv444p10le) produces the same output. Trough the link you provided I tried to add -profile:v main444-10, and get Error setting profile main444-10. Possible profiles: baseline main high high10 high422 high444 – Max Oct 7 '20 at 11:21
  • But if I understand correctly, shouldnt -pix_fmt + keep the same color/pix format? Because even with -pix_fmt + the produced file says "Decoded format: Planar 4:2:0 YUV 10-bit LE", while the original is prim:ITU-R BT.2020, trans:SMPTE ST2084 (PQ), space: ITU-R BT.2020 Range ?? – Max Oct 7 '20 at 11:48
  • If -pix_fmts returns 10-bit options, then yes, you've got 10-bit FFmpeg. The main444-10 profile is no longer used, the high444 profile includes 10-bit support now. You are correct in that -pix_fmt + maintains the input color format, so that eliminates that variable. The prim/trans/space parameters you see are related to but not the same as color format, but could definitely be the problem. Try using the -colorspace, -color_trc, and -color_primaries flags to set your output to the same values that the input is using. Also try setting the -color_range flag to either pc or tv. – Zach F. Oct 7 '20 at 17:33
  • If setting the output color parameters doesn't do anything, consider using the colorspace filter, as described here. You should try adding the filter both before and after the scaling filter. You should be able to convert the colorspace to something like bt709 or the same values as the input and immediately see an improvement if this is indeed the problem. Again, combine this with the -color_range flag (after your -i flag so that it applies to output) in your testing. – Zach F. Oct 7 '20 at 17:38

The video's color transfer characteristics (trc) and color primaries flags are not being set on the output video, which is causing the video player to use incorrect values for playback, resulting in washed out colors. When encoding, use the following FFmpeg flags to resolve this:

-color_trc smpte2084 -color_primaries bt2020

Note that these flags do not actually convert the the source material. These FFmpeg flags merely add flags to the output file that indicate to media players which values to use for these parameters. In this case, the question asker's media player chose incorrect values for these parameters since they were not set on the output video and displayed the video incorrectly.

For actually converting the video's content using specific transfer characteristics or primaries, see this wiki page on FFmpeg's colorspace filter.

  • 1
    I guess the question is then why isn't ffmpeg automatically populating those flags to output media, since input media clearly have them. – Max Oct 7 '20 at 19:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.