FFmpeg is frequently used by different studios for encoding their media, however the documentation for ffmpeg is often poor, or cryptic so its often harder than it should be to come up with a good starting point. We are aiming to come up with recommendations for different scenarios as well as document what the different flags are doing with the aim to make this easier to get to a good baseline.
...
Name | Source | ffmpeg flags | Description | Size |
---|---|---|---|---|
colorspace_yuv444p10le | https://trac.ffmpeg.org/wiki/colorspace | -c:v libx264 -preset placebo -qp 0 -x264-params "keyint=15:no-deblock=1" -pix_fmt yuv444p10le -sws_flags spline+accurate_rnd+full_chroma_int -vf "colorspace=bt709:iall=bt601-6-625:fast=1" -color_range 1 -colorspace 1 -color_primaries 1 -color_trc 1 | ||
Prores 4444 | -c:v prores_ks -profile:v 4444 -qscale:v 1 -pix_fmt yuv444p10le -sws_flags spline+accurate_rnd+full_chroma_int -vf "colorspace=bt709:iall=bt601-6-625:fast=1" -color_range 1 -colorspace 1 -color_primaries 1 -color_trc 1 | |||
-profile:v 4444 is equivalent to -profile:v 4 | ||||
shotgun_diy_encode | https://support.shotgunsoftware.com/hc/en-us/articles/219030418-Do-it-yourself-DIY-transcoding', | -vcodec libx264 -pix_fmt yuv420p -g 30 -vprofile high -bf 0 -crf 2 | ||
Prores 422 HQ | Some FFMpeg commands I need to remember for converting footage for video editing. http://bit.ly/vidsnippets · GitHub |
| ||
Note the -profile:v 3 is equivalent to -profile:v hq |
VMAF
I did explore using VMAF - Video Multi-Method Assessment Fusion as a way to quantify the compression, the notes for setting this up are below, however I think we are going with a fairly high compression factor , so I think this is probably not really going to help us much.
...
The above gets the underlying data stored correctly, but there are additional metadata flags that can be set that are interpreted by some players, these are the NCLC color tags for color primaries, transfer function and conversion matrix. This is defined as a ISO spec here (see https://www.iso.org/standard/5779473412.html which sadly is paywalled). The numbers below are part of the definition.
" -color_range 1 -colorspace 1 -color_primaries 1 -color_trc 1 "
-color_range 1 # mpeg see: FFmpeg/pixfmt.h at master · FFmpeg/FFmpeg · GitHub
-colorspace 1 # BT709 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 · FFmpeg/FFmpeg · GitHub
Color Range
Uses the flag -color_primaries 1 # BT709 FFmpeg/pixfmt.h at master · FFmpeg/FFmpeg · GitHub-color_trc 1 # bt709 FFmpeg/pixfmt.h at master · FFmpeg/FFmpeg · GitHub - Color Transfer Characteristics.range e.g. -color_range 1 or -color_range tv
Numeric value | String Values | Numeric range | Notes |
---|---|---|---|
0 | Unspecified | ||
1 | tv mpeg | 16-135 | This is the default. |
2 | pc jpeg | 0-255 |
Color Space
This defines the YUV colorspace type, as defined by ISO/IEC 23091-2_2019 subclause 8.3
Use flag -colorspace, e.g. -colorspace 1 or -colorspace rec709
This is a subset of the full list of values, for more details, see FFmpeg/pixfmt.h at master · FFmpeg/FFmpeg · GitHub
Numeric Value | String values | Description |
---|---|---|
0 | rgb | |
1 | bt709 | Typically set it to this. |
2 | unspecified | |
9 | bt2020nc bt2020_ncl | ITU-R BT2020 non-constant luminance system |
10 | bt2020c bt2020_cl | ITU-R BT2020 constant luminance system |
Color Primaries
Chromaticity coordinates of the source primaries. These values match the ones defined by ISO/IEC 23091-2_2019 subclause 8.1 and ITU-T H.273.
This is defining your color gamut, so you typically want to be setting this for -color_primaries 1 unless you are working in bt2020.
This is a subset of the full list of values, for more details, see FFmpeg/pixfmt.h at master · FFmpeg/FFmpeg · GitHub
Numeric Value | String Values | Description |
---|---|---|
1 | bt709 | |
9 | bt2020 |
Color Transfer Characteristic aka color_trc
These values match the ones defined by ISO/IEC 23091-2_2019 subclause 8.2.
This is defines the OETF, which typically is the gamma.
Numeric Value | String Values | Description |
---|---|---|
1 | bt709 | Note this is the camera gamma i.e. ~1.95 this is NOT bt1886 |
2 | Image characteristics are unknown or are determined by the application. | |
4 | gamma22 | |
5 | gamma28 | |
8 | linear | Linear |
9 | log log100 | |
14 | bt2020_10 bt2020_10bit | Note this is the camera gamma i.e. ~1.95 |
15 | bt2020_12 bt2020_12bit | Note this is the camera gamma i.e. ~1.95 |
NOTE: -color_trc 1 - is not bt1886, but is actually the camera gamma, so has a gamma of ~1.95 rather than the 2.4 that is defined by bt1886 has. In order to get a gamma 2.4, you will need to use a quicktime hack (see below), but this only works on OSX. However, we suspect that chrome ignores the setting (see the following tests).
...
- https://vimeo.com/349868875
- https://developer.apple.com/documentation/avfoundation/media_assets_and_metadata/sample-level_reading_and_writing/tagging_media_with_video_color_information
- https://www.iso.org/standard/73412.html - Note this has a link to the download of the earlier version of the doc, the latest and paywalled version is here: https://www.iso.org/standard/57794.html
Web Browser Deliverables
How should we be encoding content for a web browser.
...
Browser | Platform | Interpret NCLC flags | Color Managed | Tested | Notes |
---|---|---|---|---|---|
Firefox | OSX | No | |||
Firefox | Windows | No | |||
Firefox | Windows | ||||
Safari | OSX | Yes | Yes | ||
Chrome | OSX | Yes | Yes | ||
Safari | IOS | No | |||
Chrome | Windows | Sometimes | Seems to occasionally stop working, it could be related to multiple screens. | ||
Chrome | Linux | ||||
Edge | Windows | Sometimes | Seems to occasionally stop working, it could be related to multiple screens. |
Gamma 2.4
There is not a color_trc flag for gamma 2.4, the only option that exists for OSX is a cheat
...
-movflags write_colr+write_gama -mov_gamma 2.4 – allows you to specify a gamma parameter directly to the quicktime file.
e.g.
ffmpeg
...
-y
...
-i
...
chip-chart-1080.png
...
-c:v
...
libx264
...
-pix_fmt
...
yuv444p
...
-qscale:v
...
1
...
-sws_flags
...
spline+accurate_rnd+full_chroma_int
...
-vf
...
"colorspace=bt709:iall=bt601-6-625:fast=1"
...
-color_range
...
1
...
-colorspace
...
1
...
-color_primaries
...
1
...
-color_trc
...
2
...
-movflags
...
write_colr+write_gama
...
-mov_gamma
...
2.4
...
test2-h264-ffmpeg-yuv444p-gamma24.mp4
Full range vs. legal range
Typically x264 (and other codecs) are following the video standard that lumance is scaled to the range 16-235. This has a history from early signaling where 236-255 were used for signaling and 0-15 to avoid any noise in the low end (some of the logic was derived from analog video)
...
ffmpeg -y -i radialgrad.png -sws_flags spline+accurate_rnd+full_chroma_int -vf "scale=in_range=full:in_color_matrix=bt709:out_range=full:out_color_matrix=bt709" -c:v libx264 -pix_fmt yuvj420p -qscale:v 1 -color_range 2 -colorspace 1 -color_primaries 1 -color_trc 1 ./greyramp-fulltv/greyscale-fullj.mp4
...
ffmpeg -y -i radialgrad.png -sws_flags spline+accurate_rnd+full_chroma_int -vf "scale=in_range=full:in_color_matrix=bt709:out_range=full:out_color_matrix=bt709" -c:v libx264 -pix_fmt yuv420p -qscale:v 1 -color_range 2 -colorspace 1 -color_primaries 1 -color_trc 1 ./greyramp-fulltv/greyscale-full.mp4
...
Other links