Skip to content

KB: WebM (VP9) Encoding

suntong edited this page Oct 12, 2021 · 5 revisions

HEVC vs VP9

HEVC, aka High Efficiency Video Codec, aka H.265 can produce videos visually comparable to H.264's result, but in about half the file size.

both HEVC and VP9 provide about the same quality at a given stream size, yet HEVC has serious freeness issues: you are not allowed, without paying an extra fee, to have it as a part of any software that's preinstalled on a computer, use hardware-assisted implementations, and so on.

For thes reasons, support for VP9 is drastically more widespread than HEVC -- in browsers, https://caniuse.com/ says

  • HEVC is 8% working 6% partial, while
  • VP9 is 75% working 4% partial.

Also,

  • HEVC usually goes with AAC, while
  • VP9 with Opus;

the list of client setups that support HEVC is nearly identical to the list of those that don't support Opus. And yeah, Opus is massively better than AAC.

So it would be a much better idea to use VP9 rather than HEVC in ffcvt. However, because VP9 encoders took longer to mature than HEVC, so when ffcvt was initially developed, only HEVC was mature enough to be usable. Now is the time to use VP9 in ffcvt by default instead, because as of today,

VP9 decoding is supported on over 2 billion end points including Chrome, Opera, Edge, Firefox and Android devices, as well as millions of smart TVs.

Alas, AV1 is not yet mature enough -- it beats both HEVC and VP9 by around 25% even in its early state. However, as of today, AV1 encoding is still "very slow in comparison to VP9 or H.264, and considered experimental at this stage".

Official Sites

From webmproject/ffmpeg

FFmpeg and VP9 Encoding Guide
https://trac.ffmpeg.org/wiki/Encode/VP9

VP9 Encoding Guide
http://wiki.webmproject.org/ffmpeg/vp9-encoding-guide

VP8 Encode Parameter Guide
https://www.webmproject.org/docs/encoder-parameters/

From google

VP9 Encoding Guide
https://sites.google.com/a/webmproject.org/wiki/ffmpeg/vp9-encoding-guide

VP9 Video Encoding
https://developers.google.com/media/vp9/

Recommended Settings for VOD
https://developers.google.com/media/vp9/settings/vod/

The CRF Encoding

There's a constant quality (CQ) mode (like CRF in the x264 encoder) that will ensure that every frame gets the number of bits it deserves to achieve a certain (perceptual) quality level, rather than forcing the stream to have an average bit rate. This results in better overall quality. If you do not care about (precisely controlling) the file size, this should be your method of choice.

To trigger this mode, you must use a combination of -crf and -b:v 0. -b:v MUST be 0.

This method allows the encoder to attempt to achieve a certain output quality for the whole file when output file size is of less importance. This provides maximum compression efficiency with a single pass. Each frame gets the bitrate it needs to keep the requested quality level. The downside is that you can't tell it to get a specific filesize or not go over a specific size or bitrate.

In CQ mode, you will also set the maximum quality level. The following quality levels are recommended for file-based VP9 encoding:

Frame Height Target Quality (CQ)
240 37
360 36
480 34 (LQ) or 33 (MQ)
720 32
1080 31
1440 24
2160 15

In FFMpeg, quality is set with the -crf command. For example, to set the quality to 33 you would use the command -crf 33.

CRF Guide

CRF Guide (Constant Rate Factor in x264 and x265)
https://slhck.info/video/2017/02/24/crf-guide.html

Understanding Rate Control Modes (x264, x265, vpx)
https://slhck.info/video/2017/03/01/rate-control.html

Very good articles!

CRF Guide
http://williamyaps.blogspot.com/2017/01/ffmpeg-encoding-h264-decrease-size.html

CRF stands for Constant Rate Factor, x264’s best single-pass encoding method.

Quick Summary: What is the Constant Rate Factor?

The Constant Rate Factor (CRF) is the default quality setting for the x264 encoder. You can set the values between 0 and 51, where lower values would result in better quality (at the expense of higher file sizes). Sane values are between 18 and 28. The default for x264 is 23, so you can use this as a starting point.
If you're unsure about what CRF to use, begin with 23 and change it according to your subjective impression of the output. Is the quality good enough? No? Then set a lower CRF. Is the file size too high? Choose a higher CRF. A change of ±6 should result in about half/double the file size, although your results might vary.

CRF Comparison

The following are the results of compressing Tears of Steel with VP9 using various CRF values, gathered straight from ffcvt transcoding output, e.g.:

== Transcoding: tears_of_steel_720p.mov
] -i tears_of_steel_720p.mov -c:a libopus -b:a 64k -c:v libvpx-vp9 -b:v 0 -crf 30 -y tears_of_steel_720p_.webm
                 
Done.            
Org Size: 363455 KB
New Size: 171209 KB
Saved:    52% with 192246 KB
Time: 1h51m11.978079491s at 2018-09-15 21:04:51
                 
                 
Transcoding completed in 1h51m11.978226691s
Org Size: 354 MB 
New Size: 167 MB 
Saved:    52%    

The original file is the HD 720p (mov, 2.0) version, tears_of_steel_720p.mov, 354 MB in size.

CRF New Size Saved Time
30 167 52% 1h51m12
33 133 62% 1h44m5
37 110 69% 1h40m
40 79 77% 1h34m31
43 64 81% 1h32m21
46 51 85% 1h28m50

The following present the crf comparison data from above list in graph. Clicking on it to bring up the interactive graph.

CRF Comparison

As for the results, because "YouTube, Vimeo, and other similar sites will re-encode anything you give it", I cannot upload them to anywhere without it being distorted. However, when I looked at the result files myself, transcoded from the above HD 720p (mov, 2.0) version of Tears of Steel (Video: h264, 1280x534, 3857kb/s, 24fps, 24tbr, 24tbn, 48tbc), even the -crf 46 one looks pretty amazing -- no obvious artifact found in the result file, despite it is merely 14.6% of the original size! That's very impressive to me.

Compressing video is a trade-off between the quality of the output, and the amount of time it takes to create it. Generally speaking, you can always get higher quality by allowing more time to encode, but the time required to get the highest possible quality may be impractical.

-quality May be set to good, best, or realtime
-speed This parameter has different meanings depending upon whether quality is set to good or realtime. Speed settings 0-4 apply for VoD in good and best, with 0 being the highest quality and 4 being the lowest. Realtime valid values are 5-8; lower numbers mean higher quality

Your choices for quality and speed settings may vary depending upon resolution and available processing power. A full set of recommendations can be found in Recommended Settings.

The following are the results of compressing the above HD 720p (mov, 2.0) version of Tears of Steel with VP9 using CRF 46. So we can see, by default, -speed is 1.

Speed New Size Saved Time
0 50 85% 4h35m
1 51 85% 1h31m
2 51 85% 56m
3 51 85% 31m
4 51 85% 26m

The following present the data from above list in graph. Clicking on it to bring up the interactive graph.

Speed Comparison

For the record, I didn't find any obvious visual differences between speed 2 and 1, as a general impression, although I didn't do frame to frame image comparison. I'll stick to the default (-speed 1) whenever possible, although -speed 2 is not bad at all visually.

Converting Examples

Modern.Love.2019.S02

This result is so amazing that I feel like I have to document it, as I've compressed it down to only 3% of the original size and the result still looks good to me.

$ date; nice ffcvt -nc -debug 1 -d . -w $FFCVT_DST $FFCVT_p2c $FFCVT_E -- -auto-alt-ref 1 -lag-in-frames 18 -error-resilient 1 -frame-parallel 1 -tile-columns 3 -threads 4 -vf "scale=iw/2:-2"; date

== Transcoding [1/8]: 'Modern.Love.2019.S02E01.1080p.WEB.H264-GLHF.mkv'
   under .
] ffmpeg -i ./Modern.Love.2019.S02E01.1080p.WEB.H264-GLHF.mkv -speed 2 -af volume=1.6,channelmap=channel_layout=5.1 -map 0:v -c:v libvpx-vp9 -b:v 0 -crf 45 -map 0:a:m:language:eng -c:a libopus -b:a 64k -map 0:s:m:language:eng -map 0:s:m:language:chi -c:s copy -auto-alt-ref 1 -lag-in-frames 18 -error-resilient 1 -frame-parallel 1 -tile-columns 3 -threads 4 -vf scale=iw/2:-2 /.../cvt/Modern.Love.2019.S02/Modern.Love.2019.S02E01.1080p.WEB.H264-GLHF.mkv

Done.
Org Size: 2449523 KB
New Size: 67257 KB
Saved:    97% with 2382266 KB
Time: 36m38.0382534s at 2021-10-12 11:01:51

Time taken so far 36m38.04001s
Finishing the remaining 87% in 4h16m26.280984576s

== Transcoding [2/8]: 'Modern.Love.2019.S02E02.1080p.WEB.H264-GGEZ.mkv'
   under .
] ffmpeg -i ./Modern.Love.2019.S02E02.1080p.WEB.H264-GGEZ.mkv -speed 2 -af volume=1.6,channelmap=channel_layout=5.1 -map 0:v -c:v libvpx-vp9 -b:v 0 -crf 45 -map 0:a:m:language:eng -c:a libopus -b:a 64k -map 0:s:m:language:eng -map 0:s:m:language:chi -c:s copy -auto-alt-ref 1 -lag-in-frames 18 -error-resilient 1 -frame-parallel 1 -tile-columns 3 -threads 4 -vf scale=iw/2:-2 /.../cvt/Modern.Love.2019.S02/Modern.Love.2019.S02E02.1080p.WEB.H264-GGEZ.mkv

Done.
Org Size: 2552965 KB
New Size: 52622 KB
Saved:    97% with 2500343 KB
Time: 40m36.0955422s at 2021-10-12 11:42:27

Time taken so far 1h17m14.1359031s
Finishing the remaining 75% in 3h51m42.40858112s

Hope someday you can grab a copy of Modern.Love.2019.S02, and try the above command and see it for yourself.

Update:

Modern.Love.2019.S02E01.1080p.WEB.H264-GLHF.mkv
65.68MB

Download Links👇
Link 1: https://uploadbot2.cf/dlutb/adljcxeyd0oy/Modern.Love.2019.S02E01.1080p.WEB.H264_GLHF.mkv
Link 2: https://uptobox.com/adljcxeyd0oy

Don't know how long the links will be available though.