VAAPI
Building
Make sure you have libva headers installed, then configure with
./configure --enable-vaapi
to enable all available VAAPI encoders, decode hwaccels and filters. Older libva versions may not support all codecs, but this is detected automatically by configure.
To make sure that the encode support has been built properly:
avconv -encoders | grep vaapi V... mjpeg_vaapi MJPEG (VAAPI) (codec mjpeg) V... h264_vaapi H.264/AVC (VAAPI) (codec h264) V... hevc_vaapi H.265/HEVC (VAAPI) (codec hevc)
Hardware Support
VAAPI requires suitable hardware and software support. These tables attempt to describe what the hardware is capable of - not everything described here is implemented in libav (yet).
Intel platforms use the i965 driver developed by Intel: https://cgit.freedesktop.org/vaapi/intel-driver . It works on all recent Intel chips with a graphics core built-in to the processor - primarily the high-power main-line of Intel Core processors (since Sandy Bridge), but also the low-power Intel Atom platforms (since Bay Trail). The development is strongly tied to the development of libva itself, and that generally considers it to be the reference implementation. Most distributions package this driver, typically called something like i965-va-driver or va-intel-driver.
AMD platforms use the gallium driver which is developed as part of the Mesa graphics library: http://www.mesa3d.org/ . It is less complete than the Intel driver, supporting fewer use cases - decode support has existed for a while and is relatively stable, but encode support was only added recently and is still in flux. Only some distributions package it - recent Debian-based distributions include it in mesa-va-drivers.
Other drivers exist, but have not been tested with libav. Reports of them working (or not) are very welcome!
Decode support |
|||||||||||
Manufacturer |
Platform |
8-bit |
10-bit |
||||||||
|
|
MPEG-2 |
H.263 / MPEG-4 part 2 |
H.264 / AVC |
H.265 / HEVC |
WMV3 / VC-1 |
MJPEG |
VP8 |
VP9 |
H.265 / HEVC |
VP9 |
Intel |
Sandy Bridge |
x |
- |
x |
- |
x |
- |
- |
- |
- |
- |
Ivy Bridge |
x |
- |
x |
- |
x |
x |
- |
- |
- |
- |
|
Bay Trail |
x |
- |
x |
- |
x |
x |
- |
- |
- |
- |
|
Haswell |
x |
- |
x |
- |
x |
x |
- |
- |
- |
- |
|
Broadwell |
x |
- |
x |
- |
x |
x |
x |
- |
- |
- |
|
Cherry Trail / Braswell |
x |
- |
x |
x |
x |
x |
x |
- |
- |
- |
|
Skylake |
x |
- |
x |
x |
x |
x |
x |
- |
- |
- |
|
Apollo Lake |
x |
- |
x |
x |
x |
x |
x |
x |
x |
- |
|
Kaby Lake |
x |
- |
x |
x |
x |
x |
x |
x |
x |
x |
|
AMD |
Southern Islands |
x |
x |
x |
- |
x |
- |
- |
- |
- |
- |
Sea Islands |
x |
x |
x |
- |
x |
- |
- |
- |
- |
- |
|
Volcanic Islands |
x |
x |
x |
x |
x |
- |
- |
- |
- |
- |
|
Arctic Islands |
x |
x |
x |
x |
x |
- |
- |
- |
x |
- |
|
Warning: H.263 / MPEG-4 part 2 support in Mesa/Gallium is considered flaky and not enabled by default: set the enivronment variable VAAPI_MPEG4_ENABLED=true if you want to use it.
Encode support |
|||||||||||
Manufacturer |
Platform |
8-bit |
10-bit |
||||||||
|
|
H.264 / AVC |
H.265 / HEVC |
MJPEG |
VP8 |
VP9 |
H.265 / HEVC |
VP9 |
|||
Intel |
Sandy Bridge |
x |
- |
- |
- |
- |
- |
- |
|||
Ivy Bridge |
x |
- |
- |
- |
- |
- |
- |
||||
Bay Trail |
x |
- |
- |
- |
- |
- |
- |
||||
Haswell |
x |
- |
- |
- |
- |
- |
- |
||||
Broadwell |
x |
- |
- |
x |
- |
- |
- |
||||
Cherry Trail / Braswell |
x |
- |
- |
x |
- |
- |
- |
||||
Skylake |
x |
x |
x |
x |
- |
- |
- |
||||
Apollo Lake |
x |
x |
x |
x |
- |
- |
- |
||||
Kaby Lake |
x |
x |
x |
x |
x |
x |
- |
||||
AMD |
Southern Islands |
x |
- |
- |
- |
- |
- |
- |
|||
Sea Islands |
x |
- |
- |
- |
- |
- |
- |
||||
Volcanic Islands |
x |
x |
- |
- |
- |
- |
- |
||||
Arctic Islands |
x |
x |
- |
- |
- |
- |
- |
||||
Device Selection
The libva driver needs to be attached to a DRM device to work. This can be connected either directly or via a running X server. When working standalone, it is generally best to use a DRM render node (/dev/dri/render*); only use a connection via X if you actually want to deal with surfaces inside X (with DRI2, for example).
If you are only using a decode hwaccel, the device can be associated using the per-stream option hwaccel_device:
avconv -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -i ...
or:
avconv -hwaccel vaapi -hwaccel_device :0 -i ...
If you are intending to use encode or filter capabilities, the global vaapi_device option is required. If you use this option, hwaccel_device is not required on each stream.
avconv -vaapi_device /dev/dri/renderD128 ...
Surface Formats
Frame data used by VAAPI may be stored either in normal memory like other frames, or in hardware surfaces which are not accessible to other operations. The hardware surfaces are represented by the format vaapi; the internal format of the surface is not reflected here. Currently none of the conversions into and out of hardware formats are implicit.
Normally, the hwaccel decoder will output a normal frame matching the internal format of the hardware surfaces it is drawing from (in the Intel case, this will be NV12). Therefore, it can be used directly with software filters and encoders, and with colour conversion handled automatically as it normally is. For example, to decode in hardware and encode with x264 you can do:
avconv -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -i input.mp4 -c:v libx264 ... output.mp4
The hwaccel decoder then takes the additional option hwaccel_output_format to specify what format it's output should be. If set to vaapi, it will send the hardware surfaces into the filter chain without copying back to normal memory, so that hardware filters can act on them directly. It can also specify a particular normal output format, which may be useful to avoid an extra conversion step later.
Decode and output as YUV 4:2:0 planar (the normal intput format of x264, this will likely be slightly faster than the previous versions because it avoids an extra conversion step):
avconv -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format yuv420p -i input.mp4 -c:v libx264 ... output.mp4
Decode and output as a hardware surface, then use the VAAPI scaler to rescale, then download and encode with x264:
avconv -vaapi_device /dev/dri/renderD128 -hwaccel vaapi -hwaccel_output_format vaapi -i input.mp4 -vf 'format=nv12|vaapi,hwupload,scale_vaapi=w=1280:h=720:format=yuv420p,hwdownload' -c:v libx264 ... output.mp4
The hwupload instance there is required in order to handle the case where VAAPI does not actually support the input file: the software decoder will be used, but won't output in a hardware surface so an extra upload step is required to be able to use the scaler. The hwupload step does nothing if the output is already in vaapi format.
Encoding
The encoders can only take input as VAAPI surfaces, so it will typically need to be preceeded by a hwupload instance to convert a normal frame into a vaapi format frame. Note that the internal format of the surface will be derived from the format of the hwupload input, so additional format filters may be required to make everything work.
H.264
Encode a random input file with default options:
avconv -vaapi_device /dev/dri/renderD128 -i input.mp4 -an -vf 'format=nv12,hwupload' -c:v h264_vaapi output.mp4
If you want to transcode fully in hardware, then we need some hwaccel options and the filtering is not necessary:
avconv -vaapi_device /dev/dri/renderD128 -hwaccel vaapi -hwaccel_output_format vaapi -i input.mp4 -an -c:v h264_vaapi output.mp4
If the input is not guaranteed to be able to be decoded by your hardware (for example if it comes from random user input, and could be anything), then an instance of the hwupload filter with some format constraints is also needed in order to handle cases where the input was decoded in software:
avconv -vaapi_device /dev/dri/renderD128 -hwaccel vaapi -hwaccel_output_format vaapi -i input.mp4 -an -vf 'format=nv12|vaapi,hwupload' -c:v h264_vaapi output.mp4
This command works regardless of whether the input is decoded in hardware or not, though performance may vary a lot between those cases.
H.264 options |
|||
avconv option |
AVCodecContext field |
Meaning |
Default |
profile |
profile |
H.264 profile_idc |
100 (High) |
level |
level |
H.264 level_idc (level value * 10) |
51 (Level 5.1, up to 4K30) |
b |
bit_rate |
Target bitrate |
0 (off, uses -qp instead) |
g |
gop_size |
GOP size (distance between IDR frames) |
120 |
bf |
max_b_frames |
Number of B frames between P frames |
2 |
qp |
- |
Fixed QP of P frames (ignored if bitrate is set instead) |
20 |
i_qfactor |
i_quant_factor |
Fixed QP of IDR frames = QP of P frames * i_qfactor + i_qoffset |
1 |
i_qoffset |
i_quant_offset |
0 |
|
b_qfactor |
b_quant_factor |
Fixed QP of B frames = QP of P frames * b_qfactor + b_qoffset |
1.2 |
b_qoffset |
b_quant_factor |
0 |
|
quality |
- |
Encode quality - higher is worse and faster |
0 (use driver default) |
H.265
The H.265 encoder functions identically to H.264, though the default options are slightly different. On suitable hardware, it also supports 10-bit encoding - for this, you will need to make P010 input surfaces and then set profile to 2 (Main 10).
H.265 options |
|||
avconv option |
AVCodecContext field |
Meaning |
Default |
profile |
profile |
H.265 general_profile_idc |
1 (Main) |
level |
level |
H.265 general_level_idc / 3 (level value * 10) |
51 (Level 5.1, up to 4K60) |
b |
bit_rate |
Target bitrate |
0 (off, uses -qp instead) |
g |
gop_size |
GOP size (distance between IDR frames) |
120 |
bf |
max_b_frames |
Number of B frames between P frames |
2 |
qp |
- |
Fixed QP of P frames (ignored if bitrate is set instead) |
25 |
i_qfactor |
i_quant_factor |
Fixed QP of IDR frames = QP of P frames * i_qfactor + i_qoffset |
1 |
i_qoffset |
i_quant_offset |
0 |
|
b_qfactor |
b_quant_factor |
Fixed QP of B frames = QP of P frames * b_qfactor + b_qoffset |
1.2 |
b_qoffset |
b_quant_factor |
0 |
|
MJPEG
The MJPEG encoder only accepts YUV 4:2:0 surfaces and encodes them as baseline DCT using the standard quantisation and huffman tables. The one usable option is global_quality, which sets JPEG quality (to scale the standard quantisation tables) in the range 1-100.
avconv -vaapi_device /dev/dri/renderD128 -hwaccel vaapi -hwaccel_output_format vaapi -i input.mp4 -an -vf 'format=nv12|vaapi,hwupload' -c:v mjpeg_vaapi -global_quality 70 output.mp4
Contents