Skip to content

Libavcodec Compression

Martin Pulec edited this page Jun 5, 2020 · 30 revisions

FFMPEG provides a huge collection of codecs for use. Some of them (but not all) may be used with UltraGrid.

Table of Contents

Basics

H.264/HEVC compression is provided via libavcodec (both Libav or FFPEG supported). Some other lavc codecs are supported as well.

H.264

Usage:

uv -t deltacast -c libavcodec:codec=H.264 <address>                 # use H.264
uv -t deltacast -c libavcodec:codec=H.264:bitrate=20M <address>     # specifies requested bitrate
uv -t deltacast -c libavcodec:codec=H.264:subsampling=420 <address> # use subsampling 420 (default 422 for interlaced, 420 for progressive)

Using NVENC encoding (NVIDIA only):

uv -t deltacast -clibavcodec:encoder=h264_nvenc <address>

Use CUVID (HW accelerated) decoder:

uv -d gl --paramforce-lavd-decoder=h264_cuvid

HEVC

Since HEVC is relatively new and still a bit demanding compression providing a great compression ratio, you may need to tweak things a bit to achieve optimal performance.

There are multiple encoders supporting HEVC encoding, namely libx265 and hevc_nvenc (and also hevc_qsv if available). While encoding HEVC is still a bit demanding, it is advisable to use the NVENC encoder (or QSV) to encode the stream:

uv -t deltacast -c libavcodec:encoder=hevc_nvenc <address>

Currently, the stream encoded by NVENC encoder isn’t much parallelizable by decoder, so you may want to force hardware decoder (please note that the decoder currently adds some 4 frames of latency!):

uv -d gl --param force-lavd-decoder=hevc_cuvid

Alternatively, you may reduce the bit rate, 10 or 15 Mbps is a way easier to decode:

uv -t deltacast -c libavcodec:encoder=hevc_nvenc:bitrate=15M <address>

You can use also software encoder, which can be a bit slowish, however decoder parallelizes easily.

uv -t deltacast -c libavcodec:encoder=libx265 <address>

Once you have both hardware encoder and decoder, you can turn on spatial AQ to improve the image quality (of course it can be used also along with SW decoder, however decoding is then a bit more computationally demanding).

uv -t deltacast -c libavcodec:encoder=hevc_nvenc:spatial_aq=1 <address>

Other compressions

Besides H.264/HEVC, UltraGrid supports also few other codecs that may be used, eg.:

  • MJPEG
  • VP8/VP9
  • J2K - FFMPEG's implementation of J2K is however very slow
uv -t deltacast -c libavcodec <addr>             # use default libavcodec codec (currently MJPEG)
uv -t deltacast -c libavcodec:codec=MJPEG <addr> # use MJPEG codec explicitly
uv -t deltacast -c libavcodec:help <addr>        # prints available codecs/encoders (and decoders)

HW accelerations

Linux

  • VAAPI/VDPAU accelerated decoding (if supported) can be toggled with following command:

    uv -d decklink --paramuse-hw-accel

  • CUVID decoder (se also above, section H.264/HEVC).

    uv -d gl --param force-lavd-decoder=hevc_cuvid

HW accelerated encoding is toggled by selecting appropriate encoder, eg. hevc_vaapi or hevc_nvenc:

uv -t testcard -c libavcodec:encoder=hevc_vaapi <receiver>

macOS

In macOS, you can use:

  1. videotoolbox encoder: uv -c libavcodec:encoder=h264_videotoolbox (or hevc_videotoolbox)
  2. for NVIDIA cards - NVENC encoder, CUVID decoder (similar to Linux, described above)

Windows

Windows offers number of possible HW-accelerated encoders and decoders which may be viewed by:

uv -c libavcodec:help

No FFMPEG hw acceleration is specifically implemented for Windows, however, standalone HW-accelerated encoders/decoders may work as with other platforms, eg.:

  • NVENC, CUVID
  • Intel Quick Sync - currently (2018-09-24) only 4:2:0 subsampling works (both decoding and encoding)
  • AMF (?)

Remember that to enable HW-accelerated decoding you need to provide name of the decoder with a parameter --param force-lavd-decoder=.

Advanced

UltraGrid parameters allow more fine-grained selecting of parameters, eg. converting R12L to 4:4:4 YCbCr (automatic would be to convert to RGB if compression doesn't allow higher bit depth RGB).

Eg. at encoder:

uv -t decklink:codec=R12L --param lavc-use-codec=yuv444p16le -c libavcodec:encoder=hevc_nvenc <recv>

Than at decoder, you can toggle the counterpart, eg.:

uv -d decklink --param decoder-use-codec=R12L <sender>

Here the codec is one that is supported by the display, you can see supported ones by issuing eg:

uv -d decklink:help

Checking available pixel formats

It is sometimes tricky to know which pixel formats are available and provided by the decoder. Fortunately it can be probed with UltraGrid, just run (for example for x264; don't forgot to press Ctrl-C to exit UltraGrid):

uv -t testcard -c libavcodec:encoder=libx264 --verbose=7 2>&1 | grep 'supported pixel formats'

You can also check what codec would go from decoder. This is only informative, UltraGrid can do a conversion if needed. But if you expect 12-bit and there are only 8-bits available, it would need more tweaking (another decoder or a card):

uv -t testcard -c libavcodec:encoder=libx264 -d dummy --verbose=7 2>&1 | grep 'Available output pixel formats:'

Note: the available output pixel formats may differ according to input stream properties, thus pass the parameters to encoder exactly.

Checking supported pixel formats

NVENC/NVDEC

To see capabilities of a graphic card, you can download and compile this tool (requires nv-codec-headers) and see output of nvencinfo and nvdecinfo for an list of HW supported features

git clone https://github.com/FFmpeg/nv-codec-headers.git
cd nv-codec-headers && make && sudo make install
cd ..
git clone https://github.com/philipl/nv-video-info
cd nv-video-info && ./autogen.sh && make
./nvencinfo

Also this matrix may be useful.

VDPAU/VAAPI

For VDPAU and VAAPI there exist functions vdpauinfo and vainfo to check capabilities

Clone this wiki locally