Use VAAPI for FFmpeg Hardware Acceleration on Linux

Using the Video Acceleration API (VAAPI) with FFmpeg on Linux allows you to offload video encoding, decoding, and filtering from your CPU to your graphics hardware (such as Intel or AMD GPUs). This guide provides a quick overview of verifying your VAAPI drivers, setting up the correct environment variables, and executing FFmpeg commands for hardware-accelerated H.264 and HEVC video processing. By configuring VAAPI correctly, you can drastically reduce CPU utilization and speed up media rendering workflows.

Prerequisites and Driver Verification

Before running FFmpeg with VAAPI, you must ensure that the proper hardware drivers are installed and that your user account has permission to access the video rendering nodes.

  1. Install Driver Packages: Intel users typically need the intel-media-driver (for modern Gen8+ graphics) or i965-va-driver (for older hardware). AMD users require the mesa-va-drivers package.
  2. Check Render Group Permissions: Your user needs access to the /dev/dri/renderD128 device. You can add your user to the appropriate group by running: sudo usermod -aG video,render $USER (relog for changes to take effect).
  3. Verify VAAPI Support: Install the vainfo utility from your distribution’s package manager and run it in the terminal. A successful setup will output a list of supported entry points, such as VAEntrypointVLD (decoding) and VAEntrypointEncSlice (encoding).

Choosing the Correct Driver Variable

If your system has multiple graphics devices or hybrid drivers, you may need to explicitly tell VAAPI which driver to load using environment variables.

Hardware-Accelerated Decoding and Encoding

To utilize VAAPI, FFmpeg needs to initialize the hardware device, pass the video frames to the GPU memory, perform the operation, and either filter or write the output. The -vaapi_device flag defines the render node to use.

VAAPI Accelerated Encoding (CPU Decoding)

If your source video is in a format not supported by your GPU for decoding, or if you only want to accelerate the compression phase, use the following syntax to encode h264 via hardware:

ffmpeg -vaapi_device /dev/dri/renderD128 -i input.mp4 -vf "format=nv12,hwupload" -c:v h264_vaapi output.mp4

In this command, -vf "format=nv12,hwupload" changes the pixel format to a GPU-compatible layout and uploads the raw frames into graphics memory before passing them to the h264_vaapi encoder.

Full Hardware Transcoding (GPU Decoding and Encoding)

For maximum efficiency, you can decode the input stream on the GPU, keep the frames in hardware memory, and encode them without ever downloading the video data back to the CPU.

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi -i input.mp4 -c:v hevc_vaapi -b:v 5M output.mp4

Hardware Filtering and Scaling

If you need to resize or modify video dimensions during a hardware transcode, regular software filters like -vf scale will fail because the frames reside in GPU memory. Instead, you must use VAAPI-specific filters like scale_vaapi.

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi -i input.mp4 -vf "scale_vaapi=1280:720" -c:v h264_vaapi output_720p.mp4

This pipeline maintains the entire transcoding chain—decoding, scaling, and encoding—directly on your graphics hardware, ensuring minimal CPU overhead and optimal performance on Linux systems.