layout | title | nav_order | parent |
---|---|---|---|
default |
Web Color Preservation |
5 |
Encoding Overview |
Table of contents
{: .text-delta } 1. TOC {:toc}There are a number of metadata flags designed to help the player know what colorspace the media is in, so it can correctly interpret it for playback. We do recommend adding the metadata tags to media, particularly if you are reviewing it on a web browser, however there are a lot of gotchas here.
The NCLC/NCLX is defined as a ISO spec here (see ISO-23091 ). The numbers below are part of the definition. NCLC stands for Non-Consistent Luminance Coding, a brief overview of its history is here. For MP4 files, its also known as NCLX. Additionally this metadata can also be represented in the h264 metadata stream in the video usability Information (VUI) block.
You can read the metadata using mp4box.js which is a visual browser of the mp4 metadata, and look at moov/trak/mdia/minf/stbl/stsd/avc1/colr property.
NOTE: None of the flags below affect the encoding of the source imagery, they are meant to be used to guide how the mp4 file is decoded.
The docs are pretty sparse for this, some of the better info is FFmpeg/pixfmt.h at master
There are four possible tags that you can apply to movies:
- color_trc - The transfer function (e.g. gamma)
- color_primaries - e.g. bt709, rec2020, display-p3
- color_range - Is it tv vs. full range
- color_space - Is it YUV vs. RGB
For a detailed breakdown of what browsers support what flags see: here
This is setting the transfer function, which is typically going to be related to the gamma of the display. There are a number of existing gamma profiles, e.g. bt709 or sRGB, as well as gamma 2.2, and 2.8. Having said that, bt709 is frankly rather useless, consequently we recommend using sRGB as a default.
For more details see: here
Using the -color_trc iec61966-2-1
flag (the sRGB spec is defined as iec61966-2-1 ). This appears to be the most reliable one, working across all machines and browsers that support it. It's a shame that the flag has to be so cryptic.
Source sRGB PNG | |
Mp4 Video should match PNG |
Using the -color_trc bt709
flag (AKA rec709). This is often the default tag, however produces the most confusing results. On Chrome this will actually match sRGB, but on safari it will match the camera bt709 parameters, which roughly match gamma 1.95. NOTE, there is no support at all for BT1886, which is what we would conventionally use for the TV gamma of 2.4, the closest you can get is using Quicktime on OSX. See Apple Quicktime gamma for the workaround.
This is the bt709 mp4. | |
This is a Quicktime with a gamma of 1.95. This should be nearly identical to the above bt709 mp4, which implies OSX is correctly interpreting camera bt709. | |
This is the srgb.mp4 which may match the bt709 result. For chrome on windows, this should match bt709, which implies its treating it as sRGB. |
Screenshots
Screenshot of mp4 of chrome on windows | |
Screenshot of mp4 of safari on OSX |
Using the -color_trc gamma22
flag. This does not work correctly on safari, see Color-TRC Comparison for OSX
Source gamma 2.2 PNG | |
Mp4 Video should match PNG |
Using the -color_trc linear
flag. This is unlikely to ever be used for video, however it does make for a good test that something is working.
Source linear PNG | |
Mp4 Video should match PNG |
Apple has a workaround flag for quicktime files that allows you to explicitly set the gamma of the file. Adding the flags
-color_trc unknown -movflags write_colr+write_gama -mov_gamma 2.4
would correctly set the gamma of the media to bt1886 on Apple hardware. You can similarly use this for any other gamma, see: Color-TRC Comparison for OSX. NOTE, you do need the -color_trc unknown
so that it knows to fall back on the mov_gamma value.
ffmpeg -r 24 -start_number 1 -i inputfile.%04d.png \
-pix_fmt yuv420p \
-vf "scale=in_range=full:in_color_matrix=bt709:out_range=tv:out_color_matrix=bt709" \
-c:v libx264 -t 5 -qscale:v 1 -color_range tv -colorspace bt709 -color_primaries bt709 \
-color_trc unknown -movflags write_colr+write_gama -mov_gamma 2.4 outputfile.mov
We recommend the use of -color_trc iec61966-2-1
to use sRGB. There is no support for a gamma 2.4, if you still need it, we recommend that you use -color_trc unknown and ensure that your monitor is set correctly
Normally web browsers use the bt709 color gamut (which is different to the bt709 gamma), but in theory you could define your media as having a wider gamut, e.g. DCI-P3 or rec2020. The files below show a PNG and MP4 file defined using the rec2020 gamut, so depending on which monitor you are using it will show different text. This is similar to the excellent WIDE>Gamut test page.
PNG file | Mp4 file (which should match PNG file) |
---|---|
What the image should look like if nothing is working, or you have a rec2020 monitor. | |
What the image should look like if you have a display-p3 monitor. |
Chrome on windows, and Safari and Chrome on IOS will always assume the display is sRGB. In theory chrome://flags/#force-color-profile should give you some settings for this, but it seems to be ignored.
See:
- NCLC Testing Overview This is an overview of the NCLC Tag tests for web review.
- Comparing different outputs for -color_trc - Showing what the -color_trc flag is doing, compared to embedding in mov and png.
- Comparing different outputs for the -colorprimaries