How to Use scale_cuda in FFmpeg for GPU Scaling

FFmpeg's scale_cuda filter enables high-speed, hardware-accelerated video scaling directly on NVIDIA GPUs. By performing resizing tasks inside GPU memory, this filter eliminates the performance penalty of transferring video frames back and forth between system RAM and video memory. This guide explains the prerequisites, core command syntax, essential parameters, and best practices for creating a fully hardware-accelerated video scaling pipeline.

Prerequisites

To use scale_cuda, ensure your environment meets the following requirements:

  • An NVIDIA GPU that supports NVDEC and NVENC.
  • Up-to-date NVIDIA proprietary display drivers.
  • A build of FFmpeg compiled with CUDA support (specifically with flags such as --enable-cuda-nvcc, --enable-nvenc, and --enable-cuvid or --enable-ffnvcodec).

You can verify your FFmpeg build supports the filter by running:

ffmpeg -filters | grep scale_cuda

Basic Syntax and Full GPU Pipeline

For optimal throughput, keep the entire decoding, filtering, and encoding pipeline on the GPU. If you decode on the CPU and scale on the GPU, you will lose performance due to memory transfer overhead.

Use the -hwaccel cuda and -hwaccel_output_format cuda options before the input file to ensure frames remain in CUDA memory:

ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 -vf "scale_cuda=1920:1080" -c:v h264_nvenc -c:a copy output.mp4

In this command:

  • -hwaccel cuda: Enables CUDA hardware acceleration for decoding.
  • -hwaccel_output_format cuda: Keeps the decoded frames in VRAM as CUDA surfaces.
  • -vf "scale_cuda=1920:1080": Scales the video to 1920x1080 using the GPU.
  • -c:v h264_nvenc: Encodes the output using NVIDIA's hardware H.264 encoder.
  • -c:a copy: Copies the audio stream without re-encoding.

Maintaining Aspect Ratio

You can specify -1 or -2 for one of the dimensions to scale proportionally:

  • Use -1 to calculate the dimension directly based on the aspect ratio:

    -vf "scale_cuda=1280:-1"
  • Use -2 to ensure the calculated dimension is divisible by 2, which is required by most video codecs:

    -vf "scale_cuda=1280:-2"

Selecting Scaling Algorithms

The scale_cuda filter supports different interpolation algorithms via the interp_algo parameter:

  • nearest
  • bilinear (default)
  • bicubic
  • lanczos

Higher-quality algorithms like lanczos or bicubic provide sharper results at the cost of slightly higher GPU utilization:

ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 -vf "scale_cuda=1280:720:interp_algo=lanczos" -c:v h264_nvenc output.mp4

Handling Software-Decoded Inputs

If you are working with an input format that cannot be decoded via NVDEC, frames will start in system memory (CPU). You must explicitly upload the frames to GPU memory using the hwupload filter before applying scale_cuda:

ffmpeg -i input.mkv -vf "hwupload_cuda,scale_cuda=1280:720" -c:v h264_nvenc output.mp4