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

1 Answers1

2

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
  • 3,346