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... mpeg2_vaapi          MPEG-2 (VAAPI) (codec mpeg2video)
V... mjpeg_vaapi          MJPEG (VAAPI) (codec mjpeg)
V... h264_vaapi           H.264/AVC (VAAPI) (codec h264)
V... vp8_vaapi            VP8 (VAAPI) (codec vp8)
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

MPEG-2

The MPEG-2 encoder only supports constant-quality mode.

MPEG-2 options

avconv option

AVCodecContext field

Meaning

Default

profile

profile

Bits 4-6 of profile_and_level_indication

4 (Main)

level

level

Bits 0-3 of profile_and_level_indication

4 (High)

g

gop_size

GOP size (distance between IDR frames)

120

bf

max_b_frames

Number of B frames between P frames

1

global_quality

global_quality

Fixed quantiser of P frames

10

i_qfactor

i_quant_factor

Fixed quantiser of IDR frames = quantiser of P frames * i_qfactor + i_qoffset

1

i_qoffset

i_quant_offset

0

b_qfactor

b_quant_factor

Fixed quantiser of B frames = quantiser of P frames * b_qfactor + b_qoffset

1.2

b_qoffset

b_quant_factor

0

VP8

VP8 options

avconv option

AVCodecContext field

Meaning

Default

b

bit_rate

Target bitrate

0 (off, uses constant quality instead)

g

gop_size

GOP size (distance between key frames)

120

global_quality

global_quality

Fixed q_index of non-key frames

40

i_qfactor

i_quant_factor

Fixed q_index of key frames = q_index of non-key frames * i_qfactor + i_qoffset

1

i_qoffset

i_quant_offset

0

loop_filter_level

-

Set the corresponding codec parameters

16

loop_filter_sharpness

-

4

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


CategoryWIP