1

The colors come out fine when I try using VP8 WebM or H264 MP4, but whenever I use VP9 WebM there's a slight change in color. The change in color can be seen in Chrome, not sure about other browsers or viewers. I also tried ezGIF online GIF to WebM converter (which uses FFmpeg under the hood), and it worked fine (colors remained the same), so I'm not sure why it's not working correctly when I run FFmpeg locally.

Command I used:

ffmpeg -i duck.gif duck.webm

Color difference screenshot:

Duck Color Difference

Orignal GIF: Original Duck GIF

Output WebM: https://sportyz.000webhostapp.com/duck.webm

SportySpice
  • 183
  • 1
  • 2
  • 7
  • Can you try doing the conversion with ffmpeg using [a custom palette](https://www.bannerbear.com/blog/how-to-make-a-gif-from-a-video-using-ffmpeg/#enhancement)? I don't know if that plays a role in conversion to `webm`, but maybe worth a try. [Possible helpful scripts](https://gist.github.com/goncalossilva/865e90b66e4bddc58f40). – Saaru Lindestøkke Oct 26 '22 at 18:01
  • Using a palette seems to work, however it removes alpha/transparency so now the video has a white/black/yellow background (depending on my exact command). Here's what I tried: `ffmpeg -i duck.gif -filter_complex palettegen=use_alpha=1" palette.png`. and then: `ffmpeg -i duck.gif -i palette.png -filter_complex paletteuse=use_alpha=1 duck.webm` – SportySpice Oct 26 '22 at 19:13
  • The issue is related to transparency. When I open the WebM in Chrome browser, the video background is black. How did you get the vp9 to play on white background? – Rotem Oct 26 '22 at 19:21
  • The original WebM I created has no background(it's transparent). If you add it to a HTML page with a white background, its background will be white. If you just open it in its own tab in chrome, chrome will automatically show a page with a black background. However, you can change that as well by right clicking on the page, choosing inspect, clicking on the body element and adding "background-color: white" to element.style. – SportySpice Oct 26 '22 at 19:27
  • Here I created a small webpage to illustrate the problem more clearly: https://sportyz.000webhostapp.com/duck.html – SportySpice Oct 26 '22 at 19:38
  • Try the following command: `ffmpeg -y -i duck.gif -vf scale=out_color_matrix=bt709:out_range=tv -pix_fmt yuva420p duck2.webm` when using `out_color_matrix=bt709:out_range=tv` the color looks the same to me as the animated gif. Please check if the colors are the same. – Rotem Oct 26 '22 at 19:46

1 Answers1

1

Adding -vf scale=out_color_matrix=bt709:out_range=tv to FFmpeg command seems to solve the issue.
"Just in case", we may also mark the stream Metadata as BT.709 and "TV Range":

ffmpeg -y -i duck.gif -vf scale=out_color_matrix=bt709:out_range=tv -pix_fmt yuva420p -bsf:v vp9_metadata=color_space=bt709:color_range=tv duck2.webm


For non-HDR video there are two mainly used color standards: BT.601 and BT.709.
The difference is the conversion matrix from RGB to YUV color space.

There are also two main color ranges for YUV: "TV Range" applies values in range [16, 235], and "PC Range" applies values in range [0, 255].

It looks like FFmpeg uses BT.601 conversion by default (when encoding VP9), while Chrome assumes BT.709 standard (when decoding VP9).
The result is a noticeable "color shift".


For overcoming the issue, we may select "BT.709" and "TV Range" explicitly.

  • scale=out_color_matrix=bt709:out_range=tv - enforces conversion from RGB to YUV using BT.709 conversion formula, and "TV Range" range.
  • -bsf:v vp9_metadata=color_space=bt709:color_range=tv sets the stream Metadata to BT.709 and "TV Range" (probably not required).

HTML code used for testing:

<body style="background-color:cornflowerblue">
    <img src="duck.gif">
    <div>Original GIF</div>
    <br><br><br>
    <video autoplay loop muted playsinline src="duck2.webm"></video> <div>WebM conversion with bt709 and TV range</div>
    <br><br><br>
</body>

Output in Chrome browser:
enter image description here

Rotem
  • 1,607
  • 3
  • 10
  • 11
  • It's super close. looks about 95% the same, but still ever so slightly different. The difference is more noticeable if you put the 2 images in 2 different tabs and switch between them, especially if you zoom in the page to say 200%. The conversion using a palette on the other hand is 100% perfect (except the white background issue). If there is no way to get a palette conversion working together with transparency I will use your solution, as most people will never notice the difference anyway. Thanks for the help and time you put into this. – SportySpice Oct 26 '22 at 21:31