Answers.Body: <p>You cannot go from BGR to YUV420p without having a shift in colors, a bug with a known workaround (accurate_rnd). <a href="https://trac.ffmpeg.org/ticket/979" rel="nofollow noreferrer">https://trac.ffmpeg.org/ticket/979</a></p>
  <p>You also did not tag the output.</p>
  <pre><code>ffmpeg -f gdigrab -offset_x 1600 -offset_y 0 -video_size 1600x1200 -i desktop \
      -vf scale=flags=accurate_rnd:out_color_matrix=bt709, format=yuv420p \
      -color_primaries bt709 -colorspace bt709 -color_primaries bt709 \
      -color_trc iec61966_2_1 -c:v libx264 -profile:v main -crf 16 outfile.mp4
  </code></pre>
  <p>I hope you understand that sRGB uses sRGB transfer (iec61966_2_1), not BT.709, but uses BT.709 primaries.</p>
  <p>Your RGB is incorrectly tagged as limited, gdigrab had this bug, update FFmpeg to latest build here: <a href="https://github.com/BtbN/FFmpeg-Builds/" rel="nofollow noreferrer">https://github.com/BtbN/FFmpeg-Builds/</a></p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-09-08T19:39:30.993Z
Answers.Text: Other option for updating FFmpeg: [Gyan's FFmpeg Builds
  binaries for Windows](https://www.gyan.dev/ffmpeg/builds/).
Answers.UserDisplayName: MarianD
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-04-16T11:36:12.330Z
Answers.LastActivityDate: 2023-09-08T18:27:20.530Z
Answers.LastEditDate: 2023-09-08T18:27:20.530Z
Answers.UserDisplayName: Валерий Заподовников
Body: <p>The ffmpeg command below is being used to capture the desktop and create a resulting mp4.  ffmpeg log says the input stream is bmp and I specified the target as h264 yuv420p.   I found several older articles talking about a ffmpeg color shift problem issue and experimented several hours with the suggestions and filters.  But as the pics show the resulting mp4 is washed out and not as vibrant as the original screen.</p>
  <p>Using</p>
  <ul>
  <li>Win 10</li>
  <li>ffmpeg 5.0</li>
  <li>VLC 3.16</li>
  <li>Chrome</li>
  </ul>
  <pre><code>ffmpeg -f gdigrab -offset_x 1600 -offset_y 0 -video_size 1600x1200 -i desktop -pix_fmt yuv420p -vcodec libx264 -profile:v main -crf 16 outfile.mp4
  
  </code></pre>
  <p>Original - <a href="https://i.sstatic.net/czAf2l.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/czAf2s.png" alt="orig screen" /></a> Resulting file - <a href="https://i.sstatic.net/QVeHMl.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/QVeHMs.png" alt="color shift" /></a></p>
  <p>--- end of original post ---</p>
  <h1>Updates and information</h1>
  <p>I really needed this project done so after making the original post I made some further experiments which I think will mostly address the issue and create a workable solution.</p>
  <p>The first issue to resolve is which color space to use for the resulting file? The basic choice revolves around where you want to play the resulting file. Some players do not like certain formats.  According to <a href="https://trac.ffmpeg.org/wiki/Encode/H.264" rel="nofollow noreferrer">this</a> post yuv420p is for old players and it was yuv420p that was causing the issues that resulted in my posting here.</p>
  <p>The rest of this post will concern itself with the rgb &amp; yuv options.</p>
  <h3>RGB</h3>
  <p>The ffmpeg string which captures desktop to an rgb colorspace mp4.  Played fine in chrome and vlc 3.16</p>
  <p>Just like the yuv file below the rgb colors in the output file were true to the original desktop.</p>
  <pre><code>ffmpeg -f gdigrab -offset_x 1600 -offset_y 0 -video_size 1600x1200 -i desktop -c:v libx264rgb -qp 0 -pix_fmt rgb24 outfile.mp4
  
  </code></pre>
  <p><a href="https://i.sstatic.net/ma9p2h.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/ma9p2s.png" alt="Media info results" /></a></p>
  <h3>YUV</h3>
  <p>The ffmpeg string which captures desktop to a yuv colorspace mp4.
  Using the yuv444p color space results in a file which to the eye looks just like the desktop looked when it was recorded.  There may be some rounding errors and slight color variations if you look at it from a mathematical perspective but for my eyes and purposes it offers great fidelity to the original image.  I found no combination of parameters which could make yuv420p true to the original desktop - all my results with 420 resulted in washed out images.  Played fine in chrome and vlc 3.16</p>
  <p>I was hoping the file size would be significantly smaller than rgb but that was not the result of my test - yuv and rgb produced files approximately the same size.</p>
  <pre><code>ffmpeg -f gdigrab -offset_x 1600 -offset_y 0 -video_size 1600x1200 -i desktop -vf scale=out_color_matrix=bt709:out_range=full,format=yuv444p -color_primaries bt709 -colorspace bt709 -color_trc bt709 -pix_fmt yuv444p outfile.mp4
  
  </code></pre>
  <p><a href="https://i.sstatic.net/KRAuph.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/KRAups.png" alt="Media info results" /></a></p>
  
Tags: <ffmpeg><colorspace>
Title: Using ffmpeg gdigrab to capture desktop output to h264 yuv420p. Color shift problem
UserDisplayName: Bidder
ThreadText: # Using ffmpeg gdigrab to capture desktop output to h264 yuv420p. Color shift problem
  
  (Asked by: username_0 on 2022-03-31)
  
  The ffmpeg command below is being used to capture the desktop and create a resulting mp4. ffmpeg log says the input stream is bmp and I specified the target as h264 yuv420p. I found several older articles talking about a ffmpeg color shift problem issue and experimented several hours with the suggestions and filters. But as the pics show the resulting mp4 is washed out and not as vibrant as the original screen.
  
  Using
  
  * Win 10
  * ffmpeg 5.0
  * VLC 3.16
  * Chrome
  
  ```
  ffmpeg -f gdigrab -offset_x 1600 -offset_y 0 -video_size 1600x1200 -i desktop -pix_fmt yuv420p -vcodec libx264 -profile:v main -crf 16 outfile.mp4
  
  ```
  
  Original - [![orig screen](https://i.sstatic.net/czAf2s.png)](https://i.sstatic.net/czAf2l.png) Resulting file - [![color shift](https://i.sstatic.net/QVeHMs.png)](https://i.sstatic.net/QVeHMl.png)
  
  --- end of original post ---
  
  # Updates and information
  
  I really needed this project done so after making the original post I made some further experiments which I think will mostly address the issue and create a workable solution.
  
  The first issue to resolve is which color space to use for the resulting file? The basic choice revolves around where you want to play the resulting file. Some players do not like certain formats. According to [this](https://trac.ffmpeg.org/wiki/Encode/H.264) post yuv420p is for old players and it was yuv420p that was causing the issues that resulted in my posting here.
  
  The rest of this post will concern itself with the rgb & yuv options.
  
  ### RGB
  
  The ffmpeg string which captures desktop to an rgb colorspace mp4. Played fine in chrome and vlc 3.16
  
  Just like the yuv file below the rgb colors in the output file were true to the original desktop.
  
  ```
  ffmpeg -f gdigrab -offset_x 1600 -offset_y 0 -video_size 1600x1200 -i desktop -c:v libx264rgb -qp 0 -pix_fmt rgb24 outfile.mp4
  
  ```
  
  [![Media info results](https://i.sstatic.net/ma9p2s.png)](https://i.sstatic.net/ma9p2h.png)
  
  ### YUV
  
  The ffmpeg string which captures desktop to a yuv colorspace mp4.
  Using the yuv444p color space results in a file which to the eye looks just like the desktop looked when it was recorded. There may be some rounding errors and slight color variations if you look at it from a mathematical perspective but for my eyes and purposes it offers great fidelity to the original image. I found no combination of parameters which could make yuv420p true to the original desktop - all my results with 420 resulted in washed out images. Played fine in chrome and vlc 3.16
  
  I was hoping the file size would be significantly smaller than rgb but that was not the result of my test - yuv and rgb produced files approximately the same size.
  
  ```
  ffmpeg -f gdigrab -offset_x 1600 -offset_y 0 -video_size 1600x1200 -i desktop -vf scale=out_color_matrix=bt709:out_range=full,format=yuv444p -color_primaries bt709 -colorspace bt709 -color_trc bt709 -pix_fmt yuv444p outfile.mp4
  
  ```
  
  [![Media info results](https://i.sstatic.net/KRAups.png)](https://i.sstatic.net/KRAuph.png)
  
  **Tags:** ffmpeg, colorspace
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2022-04-16. Score: 1
  
  You cannot go from BGR to YUV420p without having a shift in colors, a bug with a known workaround (accurate\_rnd). <https://trac.ffmpeg.org/ticket/979>
  
  You also did not tag the output.
  
  ```
  ffmpeg -f gdigrab -offset_x 1600 -offset_y 0 -video_size 1600x1200 -i desktop \
      -vf scale=flags=accurate_rnd:out_color_matrix=bt709, format=yuv420p \
      -color_primaries bt709 -colorspace bt709 -color_primaries bt709 \
      -color_trc iec61966_2_1 -c:v libx264 -profile:v main -crf 16 outfile.mp4
  
  ```
  
  I hope you understand that sRGB uses sRGB transfer (iec61966\_2\_1), not BT.709, but uses BT.709 primaries.
  
  Your RGB is incorrectly tagged as limited, gdigrab had this bug, update FFmpeg to latest build here: <https://github.com/BtbN/FFmpeg-Builds/>
  
  > **Comments:**
  > **username_2**: Other option for updating FFmpeg: [Gyan's FFmpeg Builds binaries for Windows](https://www.gyan.dev/ffmpeg/builds/).  
  
  ---
  
  