Skip to content

FFmpeg Integration

Adam Wieckowski edited this page Sep 6, 2023 · 49 revisions

Currently there is no official support for VVC in FFmpeg. But community patches have been submitted, so it is possible to apply them manually.

The submitted patch series is called 'Add support for H266/VVC' and adds support for VVdeC and VVenC to FFmpeg.

Linux

  1. Build and install VVenC and VVdeC where it can be found by pkg-config
  • Build VVenC and VVdeC shared and install into a system path, e.g.:
    sudo make install install-prefix=/usr/local
  1. Clone FFmpeg and to into the downloaded folder
  • git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg
  • cd ffmpeg
  1. Checkout latest working FFmpeg version
  • git checkout 9413bdc381
  1. Download the VVC patchset (version 7) from ffmpeg patchwork
  • wget -O Add-support-for-H266-VVC.patch https://patchwork.ffmpeg.org/series/8577/mbox/
  1. Patch FFmpeg with the downloaded patch file for VVC support
  • git apply --check Add-support-for-H266-VVC.patch

  • git apply Add-support-for-H266-VVC.patch

    Attention: In case git apply --check fails caused by the libavcodec/version.h like:
    error: patch failed: libavcodec/version.h:29
    you can force to apply the patch and ignoring the version number by using:
    git apply Add-support-for-H266-VVC.patch --exclude=libavcodec/version.h

    If other issues occur, please use latest working revision 9413bdc381
    clean the master, checkout and apply patch:
    git reset --hard
    git clean -df
    git checkout 9413bdc381
    git apply Add-support-for-H266-VVC.patch

  1. Configure and build FFmpeg
  • ./configure --enable-pthreads --enable-pic --enable-shared --enable-rpath --arch=amd64 --enable-demuxer=dash --enable-libxml2 --enable-libvvdec --enable-libvvenc
    • Add more options to your configure command to enable all needed tools and codecs
  • make (use make -j to compile multi-threaded)
  1. Install ffmpeg (optional step)
  • sudo make install
  1. Check if FFmpeg supports VVC
    ffmpeg -hide_banner -codecs | grep vvc
    DEV.L. vvc H.266 / VVC (Versatile Video Coding) (decoders: libvvdec ) (encoders: libvvenc )
  • if libvvdec and libvvenc are not listed, something went wrong

In case you want to revert all changes the master can be cleaned up to origin/master by using:
git reset --hard
git clean -df

Using latest FFmpeg release 6.0

Only patchset v6 works with the latest FFmpeg release 6.0 ("Von Neumann").
To apply the patch libavcodec/version.h must be ignored.
Checkout n6.0, download patch v6 and apply:
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg
git checkout release/6.0
wget -O Add-support-for-H266-VVC.patch https://patchwork.ffmpeg.org/series/8365/mbox/
git apply ../Add-support-for-H266-VVC.patch --exclude=libavcodec/version.h

MacOS

In general you can follow the guidelines for Linux when build on MacOS.

VVenC and VVdeC is also available in Homebrew.
If you want to skip the build process it can be installed by calling:
brew install vvdec vvenc

When building on an ARM platform please follow this guide:

ARM devices (M1, M2)

When running on an ARM device you have to build and install VVenC, VVdeC and FFmpeg for ARM To build VVenC and VVdeC on ARM ninja build must be used to build, as with XCode generated libraries are not working.
It can be installed by using Homebrew: brew install ninja

  1. Build and install VVdeC:
    sudo make g=ninja install install-prefix=/usr/local
    Alternatively install via Homebrew: brew install vvdec
  2. Build and install VVenC:
    sudo make g=ninja install install-prefix=/usr/local
    Alternatively install via Homebrew: brew install vvenc
  3. configure and build FFmpeg (after patch has been applied):
    ./configure --enable-pthreads --enable-pic --enable-shared --enable-rpath --arch=arm64 --enable-demuxer=dash --enable-libxml2 --enable-libvvdec --enable-libvvenc

Windows

As building FFmpeg for Windows can be tricky, we recommend the Media Autobuild Suite.
VVenC and VVdeC are already part of the suite and must be enabled during the script setup to get VVC support in FFmpeg.

Follow the guide given in the Media Autobuild Suite to build FFmpeg.

  1. Clone the media-autobuild_suite
  • git clone https://github.com/m-ab-s/media-autobuild_suite
  • cd media-autobuild_suite
  1. Patch media-autobuild_suite to enable ffmpeg with vvc support
  • Open the file media-autobuild_suite/build/media-suite_compile.sh in your favorite Editor
  • Search for line lib/cmake/vvenc/vvencConfig.cmake):
if [[ $bits = 64bit && $vvenc = y ]] &&
     do_vcs "$SOURCE_REPO_LIBVVENC"; then
 # vvenc implementation
fi
  • change the line fi to following code:
else
    pc_exists libvvenc || do_removeOption "--enable-libvvenc"
fi
  • Search for line lib/cmake/vvdec/vvdecConfig.cmake):
if [[ $bits = 64bit && $vvdec= y ]] &&
     do_vcs "$SOURCE_REPO_LIBVVDEC"; then
 # vvdecimplementation
fi
  • change the line fi to following code:
else
    pc_exists libvvdec || do_removeOption "--enable-libvvdec"
fi
  • Search for line do_changeFFmpegConfig:
do_changeFFmpegConfig "$license"
  • Go into next line and insert the following code to apply the v7 patchset:
if [[ $bits = 64bit ]] && enabled_any libvvdec libvvenc; then
	  do_patch "https://patchwork.ffmpeg.org/project/ffmpeg/patch/20230321150124.21999-2-thomas.ff@spin-digital.com/mbox/" am  ||
          do_removeOptions "--enable-libvvdec --enable-libvvenc"
	  do_patch "https://patchwork.ffmpeg.org/project/ffmpeg/patch/20230321150124.21999-3-thomas.ff@spin-digital.com/mbox/" am  ||
          do_removeOptions "--enable-libvvdec --enable-libvvenc"
	  do_patch "https://patchwork.ffmpeg.org/project/ffmpeg/patch/20230321150124.21999-4-thomas.ff@spin-digital.com/mbox/" am  ||
          do_removeOptions "--enable-libvvdec --enable-libvvenc"
	  do_patch "https://patchwork.ffmpeg.org/project/ffmpeg/patch/20230321150124.21999-5-thomas.ff@spin-digital.com/mbox/" am  ||
          do_removeOptions "--enable-libvvdec --enable-libvvenc"
	  do_patch "https://patchwork.ffmpeg.org/project/ffmpeg/patch/20230321150124.21999-6-thomas.ff@spin-digital.com/mbox/" am  ||
          do_removeOptions "--enable-libvvdec --enable-libvvenc"
	  do_patch "https://patchwork.ffmpeg.org/project/ffmpeg/patch/20230321150124.21999-7-thomas.ff@spin-digital.com/mbox/" am  ||
          do_removeOptions "--enable-libvvdec --enable-libvvenc"
	  do_patch "https://patchwork.ffmpeg.org/project/ffmpeg/patch/20230321150124.21999-8-thomas.ff@spin-digital.com/mbox/" am  ||
          do_removeOptions "--enable-libvvdec --enable-libvvenc"
	  do_patch "https://patchwork.ffmpeg.org/project/ffmpeg/patch/20230321150124.21999-9-thomas.ff@spin-digital.com/mbox/" am  ||
          do_removeOptions "--enable-libvvdec --enable-libvvenc"
	  do_patch "https://patchwork.ffmpeg.org/project/ffmpeg/patch/20230321150124.21999-10-thomas.ff@spin-digital.com/mbox/" am  ||
          do_removeOptions "--enable-libvvdec --enable-libvvenc"
	  do_patch "https://patchwork.ffmpeg.org/project/ffmpeg/patch/20230321150124.21999-11-thomas.ff@spin-digital.com/mbox/" am  ||
          do_removeOptions "--enable-libvvdec --enable-libvvenc"
fi
  • Save and close the file media-autobuild_suite/build/media-suite_compile.sh
  • Open the file media-autobuild_suite/media-autobuild_suite.bat in your favorite Editor
  • Search for the line:
    libdav1d libaom --disable-debug libfdk-aac
  • Change the line to:
    libdav1d libaom --disable-debug libfdk-aac libvvdec libvvenc
  • Save and close the file media-autobuild_suite/media-autobuild_suite.bat
  1. Open the Windows PowerShell and run:
    media-autobuild_suite.bat

  2. Follow the instructions given by the script and enable VVenC and VVdeC when asked

Using latest FFmpeg release 6.0

Using the latest ffmpeg release n6.0 which is compliant with the patchset v6.
In General follow the same guide as given above.
To set a specific ffmpeg version or tag you have to adapt the file media-autobuild_suite.ini:

  • Open the file media-autobuild_suite/build/media-autobuild_suite.ini in your favorite Editor
  • Search for line ffmpegPath and change the uri to the following line:
    ffmpegPath=https://git.ffmpeg.org/ffmpeg.git#tag=n6.0
  • Save and close the file media-autobuild_suite/build/media-autobuild_suite.ini

To apply the patchset v6 please add following code into media-autobuild_suite/build/media-suite_compile.sh under the line:

do_changeFFmpegConfig "$license"
if [[ $bits = 64bit ]] && enabled_any libvvdec libvvenc; then
	  do_patch "https://patchwork.ffmpeg.org/project/ffmpeg/patch/20230210174106.44514-2-thomas.ff@spin-digital.com/mbox/" am  ||
		  do_removeOptions "--enable-libvvdec --enable-libvvenc"
	  do_patch "https://patchwork.ffmpeg.org/project/ffmpeg/patch/20230210174106.44514-3-thomas.ff@spin-digital.com/mbox/" am  ||
		  do_removeOptions "--enable-libvvdec --enable-libvvenc"
	  do_patch "https://patchwork.ffmpeg.org/project/ffmpeg/patch/20230210174106.44514-4-thomas.ff@spin-digital.com/mbox/" am  ||
		  do_removeOptions "--enable-libvvdec --enable-libvvenc"
	  do_patch "https://patchwork.ffmpeg.org/project/ffmpeg/patch/20230210174106.44514-5-thomas.ff@spin-digital.com/mbox/" am  ||
		  do_removeOptions "--enable-libvvdec --enable-libvvenc"
	  do_patch "https://patchwork.ffmpeg.org/project/ffmpeg/patch/20230210174106.44514-6-thomas.ff@spin-digital.com/mbox/" am  ||
		  do_removeOptions "--enable-libvvdec --enable-libvvenc"
	  do_patch "https://patchwork.ffmpeg.org/project/ffmpeg/patch/20230210174106.44514-7-thomas.ff@spin-digital.com/mbox/" am  ||
		  do_removeOptions "--enable-libvvdec --enable-libvvenc"
	  do_patch "https://patchwork.ffmpeg.org/project/ffmpeg/patch/20230210174106.44514-8-thomas.ff@spin-digital.com/mbox/" am  ||
		  do_removeOptions "--enable-libvvdec --enable-libvvenc"
	  do_patch "https://patchwork.ffmpeg.org/project/ffmpeg/patch/20230210174106.44514-9-thomas.ff@spin-digital.com/mbox/" am  ||
		  do_removeOptions "--enable-libvvdec --enable-libvvenc"
	  do_patch "https://patchwork.ffmpeg.org/project/ffmpeg/patch/20230210174106.44514-10-thomas.ff@spin-digital.com/mbox/" am  ||
		  do_removeOptions "--enable-libvvdec --enable-libvvenc"
	  do_patch "https://patchwork.ffmpeg.org/project/ffmpeg/patch/20230210174106.44514-11-thomas.ff@spin-digital.com/mbox/" am  ||
		  do_removeOptions "--enable-libvvdec --enable-libvvenc"
fi

Usage

Check for valid FFmpeg installation

ffmpeg -hide_banner -codecs | grep vvc
DEV.L. vvc H.266 / VVC (Versatile Video Coding) (decoders: libvvdec ) (encoders: libvvenc )

Available options

Run FFmpeg full help to see available options ffmpeg -h full

libvvenc-vvc encoder AVOptions:
-preset <int> E..V....... set encoding preset(0: faster - 4: slower (from 0 to 4) (default medium)
faster 0 E..V....... 0
fast 1 E..V....... 1
medium 2 E..V....... 2
slow 3 E..V....... 3
slower 4 E..V....... 4
-qp <int> E..V....... set quantization (from 0 to 63) (default 32)
-period <int> E..V....... set (intra) refresh period in seconds (from 1 to INT_MAX) (default 1)
-subjopt <boolean> E..V....... set subjective (perceptually motivated) optimization (default true)
-vvenc-params <dictionary> E..V....... set the vvenc configuration using a :-separated list of key=value parameters
-levelidc <int> E..V....... vvc level_idc (from 0 to 105) (default 0)
0 0 E..V....... auto
1 16 E..V....... 1
2 32 E..V....... 2
2.1 35 E..V....... 2.1
3 48 E..V....... 3
3.1 51 E..V....... 3.1
4 64 E..V....... 4
4.1 67 E..V....... 4.1
5 80 E..V....... 5
5.1 83 E..V....... 5.1
5.2 86 E..V....... 5.2
6 96 E..V....... 6
6.1 99 E..V....... 6.1
6.2 102 E..V....... 6.2
6.3 105 E..V....... 6.3
-tier <int> E..V....... set vvc tier (from 0 to 1) (default main)
main 0 E..V....... main
high 1 E..V....... high

Usage

Basic

  • Encode a RAW video file with VVenC into mp4:
    ffmpeg -f rawvideo -vcodec rawvideo -s 1920x1080 -framerate 25 -pix_fmt yuv420p -i file_1080p_25Hz_420_8bit.yuv -an -vcodec vvc output.mp4

  • Encode with VVenC by using a preset and bitrate:
    ffmpeg -i <input> -c:v vvc -b:v 2600k -preset faster <output>

available presets: faster,fast,medium,slow,slower

  • Set thread count (default: auto detection)
    ffmpeg -i <input> -an -vcodec vvc -threads 6 <output>

Encoder specific parameter (vvenc-params)

  • Set any available VVenC parameter via -vvenc-params (separated by :) e.g.
    ffmpeg -i <input> -an -vcodec vvc -vvenc-params bitrate=1M:passes=2:pass=1 <output>

  • Combines command with all available VVenC options:
    ffmpeg -i <input> -an -vcodec vvc -b:v 2M -subjopt 0 -period 2 -preset medium -vvenc-params passes=2:pass=1 <output>

Special options via vvenc-params

  • using low decoder energy preset (preset must be set to medium)
    ffmpeg -i <input> -an -vcodec vvc -preset medium -vvenc-params "NumRefPics=2:DeblockLastTLayers=1:MaxMTTDepth=332222:MaxMTTDepthI=3:Affine=3:ALFSpeed=1:BCW=2:BIO=0:DMVR=0:ISP=0:LFNST=0:LMCSEnable=0:MIP=0:FastMIP=0:SAO=2:SbTMVP=0:FastMrg=2" <output>

Rate control (VBR mode)

  • Set target bitrate (VBR mode) (default: 200kbit/s)
    ffmpeg -i <input> -an -vcodec vvc -b:v 2000k <output>
    ffmpeg -i <input> -an -vcodec vvc -b:v 2M <output>

  • Set 2-pass encoding (default: single pass)

  1. run 1st pass:
    ffmpeg -i <input> -an -vcodec vvc -vvenc-params passes=2:pass=1:rcstatsfile=stats.json -b:v 2M -f null /dev/null
  2. run 2nd pass:
    ffmpeg -i <input> -acodec copy -vcodec vvc -vvenc-params passes=2:pass=2:rcstatsfile=stats.json -b:v 2M <output>

combined call:

ffmpeg -i <input> -an          -vcodec vvc -vvenc-params passes=2:pass=1:rcstatsfile=stats.json -b:v 2M -f null /dev/null &&  
ffmpeg -i <input> -acodec copy -vcodec vvc -vvenc-params passes=2:pass=2:rcstatsfile=stats.json -b:v 2M <output>  
  • rcstatsfile defines a json files where the statistics of the 1st pass are written to.
  • If not given a default statsfile 'vvenc-rcstats.json' is used.
  • Be aware to use unique statfiles when running several ffmpeg instances!
  • If they are not unique all instances writes into the same file which leads to encoder failures
  • As first pass does not output anything, you can set a filename or -f null /dev/null (windows: -f null NUL)
  • Set fix qp mode (default: off)
    ffmpeg -i <input> -an -vcodec vvc -b:v 0 -qp 25 <output>

PSNR based encoding

The parameter -subjopt for better perceptual quality is enabled per default.
That means the encoder will perform for better subjective quality and better MS-SSIM results.
When this setting is disabled the encoder performs for better PSRN and VMAF results.

  • Disable perceptual optimization for better PSNR and VMAF ( default: enabled )
    ffmpeg -i <input> -an -vcodec vvc -subjopt 0 <output>

Intra Period (also known as GOP or keyframe interval) and decoding refresh types

  • Set intra period (keyframe interval) to 2 seconds ( default: 1sec )
    ffmpeg -i <input> -an -vcodec vvc -period 2 <output>

  • Set intra period (keyframe interval) in frames to 64
    ffmpeg -i <input> -an -vcodec vvc -vvenc-params intraperiod=64 <output>

  • Set decoding refreshtype ( idr,cra,idr2,cra_cre, default: cra )
    ffmpeg -i <input> -an -vcodec vvc -vvenc-params "decodingrefreshtype=idr" <output>

idr : closed GOP
cra : open GOP
cra_cre : open GOP for streaming

HDR and SDR signalization for RAW input

  • signalization is only needed when input does not contain specific information
  • signalizing SDR BT.709: -vvenc-params Sdr=sdr ( BT.2020 -vvenc-params Sdr=sdr_2020)
  • signalizing HDR10/PQ : -vvenc-params Hdr=pq ( BT.2020 -vvenc-params Hdr=pq_2020)
  • signalizing HLG : -vvenc-params Hdr=hlg (BT.2020: -vvenc-params Hdr=hlg_2020)

Special Encoding options

  • Tile encoding for faster multithreading when using more than 8 threads
    ffmpeg -i <input> -an -vcodec vvc -threads 16 -vvenc-params wavefrontsynchro=1:tiles=2x2 <output>

Transcoding

  • Transcode Transport stream file with VVC into ISOBMFF file format:
    ffmpeg -i input.ts -an -vcodec vvc output.mp4

  • Extract RAW ES from mp4:
    ffmpeg -i input.mp4 -an -vcodec copy -bsf h266_mp4toannexb output.266

Playback

ffplay is part of ffmpeg and can be used to playback VVC streams. Following file formats are supported and can be played with ffplay:

  • RAW elementary streams (.266, .vvc)
  • ISO base media file format (.mp4, .mpd)
  • MPEG transport streams (.ts)

general usage of ffplay

ffplay input

To playback a specific video track the option -vst v:id can be used. e.g.:
ffplay  dashfile.mpd -vst v:2
To toggle between different tracks during playback use v

Test streams

A variety of transport streams and dash streams according to the DVB specification can be found at:
https://dvb.org/specifications/verification-validation/vvc-test-content/

All test bitstreams from JVET can be found at: https://www.itu.int/wftp3/av-arch/jvet-site/bitstream_exchange/VVC/draft_conformance/draft6/

Disclaimer

This installation guide will only work as long as the patch series can be merged with the FFmpeg master.
The used patchset is an community submitted patch and not merged into the master nor checked by the developer team.
This guide was tested with FFmpeg commit 9413bdc381 and patchset v7.