How to Use scale_npp Filter in FFmpeg for NVIDIA GPUs
The scale_npp filter in FFmpeg provides
hardware-accelerated video scaling by leveraging the NVIDIA Performance
Primitives (NPP) library directly on NVIDIA GPUs. This guide explains
how to properly configure and use the scale_npp filter
within an end-to-end GPU processing pipeline—incorporating hardware
decoding (NVDEC) and hardware encoding (NVENC)—to achieve maximum
throughput without CPU-GPU memory transfer bottlenecks.
Prerequisites
To use scale_npp, your FFmpeg build must be compiled
with the following flags enabled:
--enable-cuda-nvcc(or--enable-cuda-llvm)--enable-libnpp--enable-nvenc--enable-nvdec
You must also have compatible NVIDIA drivers and the CUDA toolkit installed.
Basic End-to-End Hardware Pipeline
To maximize performance, you should keep the decoded video frames
entirely within GPU memory (VRAM). This requires using
-hwaccel cuda along with
-hwaccel_output_format cuda before the input file.
Here is the standard command for scaling a video to 1080p:
ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 \
-vf "scale_npp=1920:1080" \
-c:v h264_nvenc -c:a copy output.mp4In this command:
-hwaccel cuda -hwaccel_output_format cuda: Decodes the input video using NVDEC and keeps the uncompressed frames in CUDA surface memory.-vf "scale_npp=1920:1080": Scales the CUDA frames to 1920x1080 resolution on the GPU.-c:v h264_nvenc: Encodes the scaled frames directly using NVENC without copying them back to system RAM.
Choosing an Interpolation Algorithm
The scale_npp filter supports multiple scaling
algorithms via the interp_algo parameter. Depending on
whether you are upscaling or downscaling, you can choose an algorithm
that balances speed and visual quality:
nn: Nearest neighbor (fastest, lowest quality)linear: Bilinearcubic: Bicubiclanczos: Lanczos (ideal for high-quality upscaling)super: Super-sampling (recommended specifically for downscaling)
Example using Lanczos scaling:
ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 \
-vf "scale_npp=1280:720:interp_algo=lanczos" \
-c:v h264_nvenc -c:a copy output.mp4Example using Super-sampling for downscaling to 480p:
ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 \
-vf "scale_npp=854:480:interp_algo=super" \
-c:v h264_nvenc -c:a copy output.mp4Preserving Aspect Ratio
To maintain the input video's aspect ratio, set one dimension
explicitly and use -1 (or -2 to ensure
dimensions remain divisible by 2 for the encoder) for the other
dimension:
ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 \
-vf "scale_npp=1920:-2" \
-c:v h264_nvenc -c:a copy output.mp4Scaling from a CPU Decoded Source
If your input codec is not supported by NVDEC, you can decode the
stream using the CPU, upload the raw frames to GPU memory with
hwupload_cuda, and then apply scale_npp:
ffmpeg -i input.mkv \
-vf "hwupload_cuda,scale_npp=1280:720" \
-c:v hevc_nvenc -c:a copy output.mp4While this method is slower than a full hardware pipeline due to the PCIe bus transfer overhead from system RAM to VRAM, it still offloads the computationally expensive scaling and encoding stages to the GPU.