Home / Alt manpages / ffmpeg-scaler(1)

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

Scale FFmpeg Video Predictably with libswscale

You will resize video or a single image with ffmpeg, choosing the libswscale algorithm deliberately. Along the way you will verify the output dimensions and pixel format instead of trusting a successful exit code. The examples use ordinary user privileges and take about ten minutes if FFmpeg is already installed.

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.

1. Confirm the binary and version

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.

2. Run a small, disposable test scale

Start with a generated source rather than a real recording. This proves the scaler invocation works without touching anything of value:

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

Checkpoint

file reports PNG image data, 640 x 360. The -1 height asks the scale filter to preserve the source aspect ratio, and flags=lanczos selects the algorithm for this filter; the manpage gives the lanczos filter's default alpha (width) as 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

That removal is reversible only because you can regenerate the output. Do not adapt the command to point at an original recording.

3. Choose the scaling algorithm on purpose

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

  • fast_bilinear and bilinear are simple choices when speed matters most.
  • bicubic is the default.
  • Nearest-neighbour suits some hard-edged material and is deliberately unsuitable for smooth photographic resizing.
  • area averages pixels, which can help 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 it. 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 instead:

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 build lacks the requested video encoder. That is an encoder problem, not evidence that scaling failed: replace libx264 with an encoder your build actually has, and keep -c:a copy only when the original audio suits the new container.

4. Verify the result with ffprobe

Check what was actually written rather than trusting the command's exit status. ffprobe 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"

Checkpoint

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

5. 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 -pix_fmt:

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. Watch the range settings too: the documented defaults are limited range for both source and destination, shown as src_range=0 and dst_range=0. Setting either to full range without understanding the source metadata can make blacks or highlights look wrong, so treat it as 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"

6. Control 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, so 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

  • API-only options in a command line. srcw, dstw, src_format and dst_format are marked API-only in the manpage; do not pass them as ordinary settings.
  • Stacked algorithms in sws_flags. Select one algorithm and add only the separate flags you have a reason to use.
  • Casual use of -y. It overwrites output without asking. The examples here use -n, which stops instead.
  • Trusting a clean exit as proof of quality. Inspect dimensions and pixel format, then watch a representative frame or short section of the result.

Done means

  • Binary confirmed: you know which ffmpeg executable and version ran the commands.
  • Dimensions verified: the output size matches the requested scale and aspect ratio.
  • Algorithm chosen deliberately: the scaler algorithm, range, dithering and alpha behaviour are explicit where they matter.
  • Pixel format confirmed: ffprobe reports the output pixel format you expected.
  • Inputs untouched: the original input is unchanged and no output file was overwritten by accident.