How to Use scale_vaapi in FFmpeg for Scaling

This guide provides a practical overview of using FFmpeg's scale_vaapi filter to perform hardware-accelerated video scaling on Linux systems with compatible Intel or AMD GPUs. You will learn the required driver settings, how to initialize the hardware device, and how to construct commands for both hybrid and fully hardware-accelerated transcoding pipelines.

Prerequisites

To use scale_vaapi, your system must meet the following requirements:

  • A compatible GPU (Intel integrated graphics or AMD Radeon).
  • The appropriate VAAPI drivers installed (intel-media-va-driver, i965-va-driver, or mesa-va-drivers).
  • FFmpeg compiled with --enable-vaapi.
  • Verified hardware access via the vainfo command.

Basic Concepts

FFmpeg requires you to specify a hardware device using the -vaapi_device option (typically pointing to /dev/dri/renderD128).

Because scale_vaapi operates in GPU memory, the video frames must be in VAAPI surface format before reaching the filter. This is achieved either by:

  1. Uploading software-decoded frames to the GPU via the hwupload filter.
  2. Decoding directly into GPU memory using the -hwaccel vaapi option.

Method 1: Full Hardware Pipeline (Decode, Scale, and Encode)

For maximum performance, decode the video using hardware, pass the frames directly to scale_vaapi, and encode using a VAAPI encoder like h264_vaapi. This avoids copying frames between CPU and GPU memory.

ffmpeg -hwaccel vaapi \
       -hwaccel_output_format vaapi \
       -vaapi_device /dev/dri/renderD128 \
       -i input.mp4 \
       -vf "scale_vaapi=w=1280:h=720" \
       -c:v h264_vaapi \
       -b:v 2M \
       output_720p.mp4

Method 2: Software Decode with Hardware Scaling and Encoding

If the input codec is not supported by your hardware decoder, you can decode the stream with your CPU, upload the frames to the GPU for scaling, and encode them with VAAPI.

ffmpeg -vaapi_device /dev/dri/renderD128 \
       -i input.mkv \
       -vf "format=nv12,hwupload,scale_vaapi=w=1920:h=1080" \
       -c:v h264_vaapi \
       -b:v 4M \
       output_1080p.mp4

Note: The format=nv12 filter ensures pixel compatibility before uploading frames via hwupload.

Method 3: Hardware Scaling with Software Encoding

If you need to use a software encoder like libx264 or libx265 for higher compression efficiency, download the frames back to system memory using hwdownload after scaling.

ffmpeg -hwaccel vaapi \
       -hwaccel_output_format vaapi \
       -vaapi_device /dev/dri/renderD128 \
       -i input.mp4 \
       -vf "scale_vaapi=w=1280:h=720,hwdownload,format=nv12" \
       -c:v libx264 \
       -crf 23 \
       output_soft.mp4

Common scale_vaapi Parameters

  • Maintaining Aspect Ratio: Set one dimension to -1 to preserve the aspect ratio, or -2 to ensure the calculated dimension is divisible by 2:

    scale_vaapi=w=1280:h=-2
  • Output Pixel Format (format): Force a specific pixel format supported by the hardware surface:

    scale_vaapi=w=1920:h=1080:format=nv12
  • Scaling Algorithm (mode): Control the scaling quality/algorithm supported by the driver:

    • default: The driver's default algorithm.
    • fast: Prioritizes speed over quality (e.g., nearest-neighbor or bilinear).
    • hq: Enables high-quality scaling (hardware-dependent).
    scale_vaapi=w=1280:h=720:mode=hq