Home / Alt manpages / ffmpeg-scaler(1)

  • ffmpeg-scaler(1)
  • User command
  • linux

Scale FFmpeg Video Predictably with libswscale

You will resize a video or a single image, choose the libswscale algorithm deliberately, and verify the output dimensions and pixel format. The examples use ordinary user privileges and take about ten minutes if FFmpeg is already installed.

Before you start

You need the ffmpeg executable and an input file you can read. The ffmpeg-scaler(1) manpage documents the rescaler behind FFmpeg's tools, including scaling algorithms, range handling, dithering and alpha blending. It does not describe a separate command called ffmpeg-scaler: the settings are passed to FFmpeg.

Check which binary your shell will run, then record its version:

command -v ffmpeg
ffmpeg -version | sed -n '1,2p'

On the machine used for these examples, the Ubuntu package database reports FFmpeg 6.1.1, while the executable found on PATH reports 8.0.1. That mismatch is a useful warning: package documentation and the binary you invoke can come from different installations. Test the command you intend to use.

Checkpoint: make a small test output

Start with a generated source. This proves that the scaler invocation works without modifying a real recording:

mkdir -p /tmp/ffmpeg-scaler-demo
ffmpeg -hide_banner -f lavfi -i testsrc2=size=1280x720:rate=1 \
  -frames:v 1 -vf 'scale=640:-1:flags=lanczos' \
  -sws_dither ed -n /tmp/ffmpeg-scaler-demo/lanczos.png
file /tmp/ffmpeg-scaler-demo/lanczos.png

Expected output from file includes PNG image data, 640 x 360. The -1 height asks the scale filter to preserve the source aspect ratio. The flags=lanczos part selects the scaler for this filter. The manpage calls the same algorithm lanczos and says its default alpha, or width, is 3.

The -n option refuses to overwrite an existing file. If you rerun the example, either choose another output name or remove only this generated file:

rm -- /tmp/ffmpeg-scaler-demo/lanczos.png

This removal is reversible only if you can regenerate the output, so do not adapt that command to point at an original recording.

Choose the scaling algorithm

The documented default for sws_flags is bicubic. Set it explicitly when output consistency matters, or when you are comparing quality and speed. The manpage says to select only one algorithm.

  • fast_bilinear and bilinear are simple choices when speed matters.
  • bicubic is the default.
  • The nearest-neighbour algorithm is useful for some hard-edged material and deliberately unsuitable for smooth photographic resizing.
  • area averages pixels and can be useful when reducing an image.
  • lanczos, sinc, gauss and spline are available when you want to compare sharper or smoother results.

There are two common ways to select the algorithm. Put it on the scale filter when that filter is the thing you are tuning:

ffmpeg -hide_banner -i "input.mp4" \
  -vf 'scale=1280:-1:flags=lanczos' \
  -c:v libx264 -crf 20 -c:a copy -n "scaled-lanczos.mp4"

Or set the scaler option for FFmpeg's conversion pipeline:

ffmpeg -hide_banner -i "input.mp4" \
  -vf 'scale=1280:-1' -sws_flags bilinear \
  -c:v libx264 -crf 20 -c:a copy -n "scaled-bilinear.mp4"

These commands may fail if your FFmpeg build lacks the requested video encoder. That is an encoder problem, not evidence that scaling failed. Replace libx264 with an encoder available in your build, or use a format and codec appropriate to your workflow. Keep -c:a copy only when the original audio is acceptable in the new container.

Checkpoint: inspect the result

Use ffprobe to check what was actually written. It does not change the file:

ffprobe -v error -select_streams v:0 \
  -show_entries stream=width,height,pix_fmt \
  -of default=noprint_wrappers=1 "scaled-lanczos.mp4"

For the example above, the video stream should report a width of 1280, a height calculated from the source ratio, and a pixel format selected by the encoder. Do not assume that the filename extension tells you the pixel format.

Convert the pixel format deliberately

Scaling and pixel format conversion often happen in the same pipeline. The scaler manpage describes src_format and dst_format as API-only integer options, so do not copy those names into an FFmpeg command line. For the command-line tool, request the output format with FFmpeg's -pix_fmt option:

ffmpeg -hide_banner -i "input.mp4" \
  -vf 'scale=1920:1080:flags=bicubic' -pix_fmt yuv420p \
  -c:v libx264 -crf 20 -c:a copy -n "scaled-yuv420p.mp4"

Verify it with the same ffprobe command. Be careful with range settings too. The documented defaults are limited range for both source and destination, represented by src_range=0 and dst_range=0. Setting either to full range without understanding the source metadata can make blacks or highlights look wrong. If you need full range, make that a tested, intentional decision:

ffmpeg -hide_banner -i "input.mp4" \
  -vf 'scale=1280:-1:flags=lanczos' -src_range 1 -dst_range 1 \
  -pix_fmt yuv420p -c:v libx264 -crf 20 -c:a copy -n "scaled-full-range.mp4"

Dithering, alpha and repeatability

sws_dither defaults to auto. The other documented values are none, bayer, ed, a_dither and x_dither. Error diffusion, selected with ed, can help when reducing precision, but compare the output rather than treating one setting as universally best.

If an input has an alpha channel and the output does not, alphablend controls the conversion. Its default is none; the alternatives blend onto a uniform colour or a checkerboard. A transparent source can therefore produce an unexpected background if you do not choose how it should be blended. Test a frame with transparency before processing a batch.

The bitexact scaler flag asks for bit-exact output. It is useful for reproducible conversion tests, but it is not a general promise that complete media files will match byte for byte. Encoders, timestamps and container metadata can still differ.

Common traps

  • Do not pass srcw, dstw, src_format or dst_format as if they were normal command-line settings. The manpage marks them API-only.
  • Do not combine several scaler algorithms in sws_flags. Select one algorithm and add only the separate flags you have a reason to use.
  • Do not use -y casually. It overwrites output without asking. The examples use -n, which stops instead.
  • Do not confuse a successful FFmpeg exit with suitable quality. Inspect dimensions and pixel format, then watch a representative frame or short section of the result.

Done means

  • The command selected the intended FFmpeg executable and version.
  • The output dimensions match the requested scale and aspect ratio.
  • The scaler algorithm, range, dithering and alpha behaviour are explicit where they matter.
  • ffprobe confirms the output pixel format.
  • The original input remains untouched and output files were not overwritten accidentally.