Hardware-Accelerated Video Scaling in FFmpeg with CUDA

This guide provides a quick overview and actionable instructions for implementing hardware-accelerated video scaling using NVIDIA CUDA inside FFmpeg. By offloading video decoding, scaling, and encoding directly to an NVIDIA GPU, you prevent CPU bottlenecks and avoid costly data transfers between system RAM and VRAM. The following sections cover the necessary prerequisites, standard command syntax using the scale_cuda filter, aspect-ratio preservation, and performance-tuning options.

Prerequisites

To perform CUDA-accelerated scaling, ensure your environment meets the following requirements:

  • An NVIDIA GPU that supports NVDEC and NVENC.
  • Up-to-date proprietary NVIDIA display drivers.
  • An FFmpeg build compiled with CUDA support (flags: --enable-cuda-nvcc, --enable-cuvid, --enable-nvenc, and --enable-libnpp if using NPP filters).

Verify your FFmpeg installation supports CUDA filters by running:

ffmpeg -filters | grep cuda

Look for scale_cuda in the output list.

Basic CUDA Scaling Command

To achieve maximum performance, decode the input video in hardware, keep the frames in VRAM using -hwaccel_output_format cuda, apply the scale_cuda filter, and encode using an NVIDIA hardware encoder (h264_nvenc or hevc_nvenc).

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

Parameter Breakdown:

  • -hwaccel cuda: Enables CUDA hardware acceleration for decoding.
  • -hwaccel_output_format cuda: Retains decoded frames directly in GPU memory so the scaling filter can process them without copying frames back to system memory.
  • -vf "scale_cuda=1920:1080": Scales the video to a fixed width of 1920 and a height of 1080 on the GPU.
  • -c:v h264_nvenc: Encodes the output using NVIDIA's H.264 hardware encoder.
  • -c:a copy: Copies the audio stream without re-encoding.

Maintaining Aspect Ratio

To resize a video while preserving its original aspect ratio, set one dimension explicitly and pass -1 or -2 to the other dimension:

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

Using -2 ensures that the calculated dimension is divisible by 2, which is required by most video codecs.

Selecting an Interpolation Algorithm

The scale_cuda filter supports several interpolation algorithms via the interp_algo parameter. Available options include nearest, bilinear, bicubic, and lanczos.

For higher quality upscaling, use lanczos or bicubic:

ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 -vf "scale_cuda=3840:2160:interp_algo=lanczos" -c:v hevc_nvenc -c:a copy output.mp4

For maximum processing speed, bilinear (the default) or nearest provides the lowest latency.

Scaling CPU-Decoded Video on the GPU

If your input codec cannot be decoded by your GPU, you can decode the stream using the CPU and manually upload the frames to the GPU for scaling and encoding using the hwupload_cuda filter:

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