How to Transcode H.264 with FFmpeg and VAAPI on Linux

This article provides a quick, step-by-step guide on how to leverage the Video Acceleration API (VAAPI) in Linux to transcode H.264 videos using your hardware’s GPU. By offloading both the decoding and encoding processes to your graphics hardware via FFmpeg, you can significantly reduce CPU usage and drastically speed up conversion times.

Step 1: Verify VAAPI Installation and Hardware Support

Before running FFmpeg, you must ensure that your system has the correct VAAPI drivers installed and that your GPU supports H.264 hardware decoding and encoding.

Install the vainfo utility using your package manager (e.g., sudo apt install vainfo on Debian/Ubuntu) and run it in your terminal:

vainfo

Look for the following entry profiles in the output to confirm H.264 support: * VAProfileH264Main or VAProfileH264High (with VAEntrypointVLD for decoding) * VAProfileH264Main or VAProfileH264High (with VAEntrypointEncSlice for encoding)

Step 2: Identify Your GPU Device Path

VAAPI requires direct access to your GPU’s render node. On most Linux distributions, the default graphics device path is:

/dev/dri/renderD128

If you have multiple GPUs, you can list them using ls /dev/dri/ to find the correct render node.

Step 3: Run the FFmpeg Transcoding Command

To perform a full hardware-accelerated transcode (decoding the input with VAAPI and encoding the output with VAAPI), use the following FFmpeg command structure:

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

Command Breakdown

Advanced: Applying Hardware Filters (Scaling)

If you need to resize the video during transcoding, you must use hardware-based filters to keep the frames inside the GPU memory. Use the scale_vaapi filter as shown below:

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi -i input.mp4 -vf "scale_vaapi=w=1920:h=1080" -c:v h264_vaapi -b:v 5M output.mp4

This command scales the input video to 1080p resolution entirely within the GPU hardware before encoding.