FFmpeg VAAPI Device Initialization and Deinterlacing
This guide provides a direct walkthrough on initializing a VAAPI
(Video Acceleration API) device in FFmpeg and applying the
hardware-accelerated deinterlace_vaapi filter. Utilizing
VAAPI offloads deinterlacing directly to compatible Intel or AMD GPUs,
significantly lowering CPU consumption while maintaining high-speed
video processing on Linux systems.
Initializing the VAAPI Device
To use VAAPI filters, FFmpeg must first initialize the hardware
context pointing to your GPU's DRM render node (typically
/dev/dri/renderD128).
Device initialization is defined before the input using either the legacy shortcut flag or the generic hardware device flag:
- Shortcut flag:
-vaapi_device /dev/dri/renderD128 - Generic flag:
-init_hw_device vaapi=va:/dev/dri/renderD128
Understanding Hardware Surface Requirements
The deinterlace_vaapi filter operates strictly on VAAPI
hardware surfaces, not software pixel formats like YUV420P. Your
pipeline must provide frames in vaapi pixel format. This is
accomplished in one of two ways:
- Hardware Decoding: Decode directly into VAAPI
memory using
-hwaccel vaapi -hwaccel_output_format vaapi. - Software Upload: Decode on the CPU and upload the
frames to GPU memory inside the filter chain using
format=nv12,hwupload.
The
deinterlace_vaapi Filter Syntax
The basic filter call is simply deinterlace_vaapi. It
accepts parameters to tune the output:
mode: Specifies the deinterlacing algorithm.default: Driver default (typically motion-adaptive).bob: Bob deinterlacing.weave: Weave deinterlacing (no interpolation).motion_adaptive: Motion-adaptive algorithm.motion_compensated: Motion-compensated algorithm.
rate: Specifies frame rate output.frame: Output one frame for each frame (preserves input frame rate).field: Output one frame for each field (doubles the frame rate, e.g., 29.97i to 59.94p).
Complete Command Examples
1. Full Hardware Pipeline (Decode, Deinterlace, Encode)
This is the most efficient method because the video stays in GPU memory throughout the entire transcode process.
ffmpeg -vaapi_device /dev/dri/renderD128 \
-hwaccel vaapi -hwaccel_output_format vaapi \
-i input_interlaced.mp4 \
-vf "deinterlace_vaapi=mode=motion_adaptive:rate=field" \
-c:v h264_vaapi -b:v 5M \
-c:a copy output_progressive.mp42. Software Decode with Hardware Deinterlacing
If your input codec cannot be hardware-decoded by VAAPI, decode using the CPU, upload the frames to the GPU for deinterlacing, and encode using the GPU:
ffmpeg -init_hw_device vaapi=hw:/dev/dri/renderD128 \
-filter_hw_device hw \
-i input_interlaced.mkv \
-vf "format=nv12,hwupload,deinterlace_vaapi=rate=frame" \
-c:v h264_vaapi -qp 24 \
-c:a copy output_progressive.mp43. Hardware Deinterlace with Software Encoding
If you need to encode using a CPU-based encoder (such as
libx264), you must download the frames back to system
memory using hwdownload after deinterlacing:
ffmpeg -vaapi_device /dev/dri/renderD128 \
-hwaccel vaapi -hwaccel_output_format vaapi \
-i input_interlaced.ts \
-vf "deinterlace_vaapi=rate=field,hwdownload,format=nv12" \
-c:v libx264 -crf 20 -preset fast \
-c:a copy output_progressive.mp4