Answers.Body: <p>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:</p>
  <pre><code>-color_trc smpte2084 -color_primaries bt2020
  </code></pre>
  <p>Note that these flags do not actually <em>convert</em> 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.</p>
  <p>For actually <em>converting</em> the video's content using specific transfer characteristics or primaries, <a href="https://trac.ffmpeg.org/wiki/colorspace" rel="noreferrer">see this wiki page on FFmpeg's colorspace filter</a>.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-10-07T19:14:32.370Z
Answers.Text: I guess the question is then why isn't ffmpeg automatically populating those flags to output media, since input media clearly have them.
Answers.UserDisplayName: Max
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-05-06T02:50:34.617Z
Answers.Text: @Max Precisely. It's ridiculous that so much work needs to be done just to get FFmpeg to *pass through* color characteristics from the input.
Answers.UserDisplayName: Hashim Aziz
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-10-07T19:06:03.897Z
Answers.LastActivityDate: 2020-10-07T19:06:03.897Z
Answers.UserDisplayName: Zach F.
Body: <p>Im trying to scale video down. No matter what I do the colors are always washed up as a result.</p>
  <p>original:
  <a href="https://i.sstatic.net/tXvhr.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/tXvhr.png" alt="original" /></a></p>
  <p>After scaling:</p>
  <p><a href="https://i.sstatic.net/zR1vS.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/zR1vS.png" alt="enter image description here" /></a></p>
  <p>Code I run for it</p>
  <pre><code>ffmpeg -i input.mkv -vf scale=1028:-1 output.mkv
  </code></pre>
  <p>log: <a href="https://pastebin.com/gj75geU9" rel="nofollow noreferrer">log</a></p>
  <p>Original file codec info</p>
  <p><a href="https://i.sstatic.net/u9FFU.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/u9FFU.png" alt="Original file codec info" /></a></p>
  <p>New file codec info</p>
  <p><a href="https://i.sstatic.net/gsesY.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/gsesY.png" alt="enter image description here" /></a></p>
  <p>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.</p>
  <p>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.</p>
  <p>Overkill example:</p>
  <pre><code>ffmpeg -i &quot;input&quot; -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=&quot;G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,500)&quot; -c:a aac -vf colorspace=bt2020,transfer=smpte2084,scale=1280:-1 &quot;small_output&quot;
  </code></pre>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-10-06T20:56:39.387Z
Comments.Text: 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](https://video.stackexchange.com/questions/28889/ffmpeg-does-not-preserve-colors-after-resizing?rq=1) may also shed more light on the issue.
Comments.UserDisplayName: Zach F.
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-10-07T11:21:50.933Z
Comments.Text: -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`
Comments.UserDisplayName: Max
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-10-07T11:48:13.333Z
Comments.Text: 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 ??
Comments.UserDisplayName: Max
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-10-07T17:33:36.830Z
Comments.Text: 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`.
Comments.UserDisplayName: Zach F.
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-10-07T17:38:43.250Z
Comments.Text: If setting the output color parameters doesn't do anything, consider using the `colorspace` filter, [as described here](https://trac.ffmpeg.org/wiki/colorspace). 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.
Comments.UserDisplayName: Zach F.
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-10-07T18:34:39.303Z
Comments.Text: Thank you very much!!! Setting `-color_trc smpte2084` and `-color_primaries bt2020` was enough to do it. If I omit either one, the colors are washed out, albeit differently based on which parameter I leave out. But those two combined made the colors right!
  suprisingly, I tried adding more parameters to it and adding -pix_fmt yuv444p10le makes colors much deeper and darker than original, while yuv444p (which is 8 bit) makes output same as input. I would guess using 10 bit pixel format would only help, but here it seems to cause more harm?
Comments.UserDisplayName: Max
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-10-07T18:54:51.167Z
Comments.Text: Glad to hear it worked! I'm going to convert my comment to an answer per site guidelines. It's hard to say why using the `yuv444p10le` format could be causing color issues in this case. I can only hazard a guess here, but since `-pix_fmt +` returns an encoded video with 4:2:0 subsampling, outputting using a color format with 4:4:4 subsampling is technically an upscaling conversion, which might factor into why the colors get messed up when changing between 8-bit and 10-bit formats.
Comments.UserDisplayName: Zach F.
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-10-07T19:10:04.833Z
Comments.Text: interestingly, using yuv444p produces good results, but using yuv444p10le produces darker colors, exact opposite of the washed up colors I had trouble with originally. Have to say, setting pix_fmt to yuv444p10le I tried before even creating this question, and it didnt help the colors at all, it was still washed up, so I dont think its a cumulative effect.
Comments.UserDisplayName: Max
Tags: <ffmpeg><h.264><color-correction><scale><hevc>
Title: ffmpeg vf scale shifts colors to washed out
UserDisplayName: Max
ThreadText: # ffmpeg vf scale shifts colors to washed out
  
  (Asked by: username_0 on 2020-10-06)
  
  Im trying to scale video down. No matter what I do the colors are always washed up as a result.
  
  original:
  [![original](https://i.sstatic.net/tXvhr.png)](https://i.sstatic.net/tXvhr.png)
  
  After scaling:
  
  [![enter image description here](https://i.sstatic.net/zR1vS.png)](https://i.sstatic.net/zR1vS.png)
  
  Code I run for it
  
  ```
  ffmpeg -i input.mkv -vf scale=1028:-1 output.mkv
  
  ```
  
  log: [log](https://pastebin.com/gj75geU9)
  
  Original file codec info
  
  [![Original file codec info](https://i.sstatic.net/u9FFU.png)](https://i.sstatic.net/u9FFU.png)
  
  New file codec info
  
  [![enter image description here](https://i.sstatic.net/gsesY.png)](https://i.sstatic.net/gsesY.png)
  
  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"
  
  ```
  
  **Tags:** ffmpeg, h.264, color-correction, scale, hevc
  
  > **Comments:**
  > **username_1**: 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](https://video.stackexchange.com/questions/28889/ffmpeg-does-not-preserve-colors-after-resizing?rq=1) may also shed more light on the issue.  
  > **username_0**: -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`  
  > **username_0**: 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 ??  
  > **username_1**: 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`.  
  > **username_1**: If setting the output color parameters doesn't do anything, consider using the `colorspace` filter, [as described here](https://trac.ffmpeg.org/wiki/colorspace). 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.  
  > **username_0**: Thank you very much!!! Setting `-color_trc smpte2084` and `-color_primaries bt2020` was enough to do it. If I omit either one, the colors are washed out, albeit differently based on which parameter I leave out. But those two combined made the colors right! suprisingly, I tried adding more parameters to it and adding -pix_fmt yuv444p10le makes colors much deeper and darker than original, while yuv444p (which is 8 bit) makes output same as input. I would guess using 10 bit pixel format would only help, but here it seems to cause more harm?  
  > **username_1**: Glad to hear it worked! I'm going to convert my comment to an answer per site guidelines. It's hard to say why using the `yuv444p10le` format could be causing color issues in this case. I can only hazard a guess here, but since `-pix_fmt +` returns an encoded video with 4:2:0 subsampling, outputting using a color format with 4:4:4 subsampling is technically an upscaling conversion, which might factor into why the colors get messed up when changing between 8-bit and 10-bit formats.  
  > **username_0**: interestingly, using yuv444p produces good results, but using yuv444p10le produces darker colors, exact opposite of the washed up colors I had trouble with originally. Have to say, setting pix_fmt to yuv444p10le I tried before even creating this question, and it didnt help the colors at all, it was still washed up, so I dont think its a cumulative effect.  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2020-10-07. Score: 5 | Accepted answer
  
  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](https://trac.ffmpeg.org/wiki/colorspace).
  
  > **Comments:**
  > **username_0**: I guess the question is then why isn't ffmpeg automatically populating those flags to output media, since input media clearly have them.  
  > **username_2**: @username_0 Precisely. It's ridiculous that so much work needs to be done just to get FFmpeg to *pass through* color characteristics from the input.  
  
  ---
  
  