FFmpeg Scale Filter: Every Option You Actually Need

By Hieu Dinh

FFmpeg Scale Filter: Every Option You Actually Need

scale=1280:720 works. It is also, in a lot of real situations, wrong — it will happily stretch a 4:3 source into widescreen, produce odd dimensions that some encoders reject, and resample with an algorithm that is not the best fit for your content.

This guide covers the parts of the scale filter that matter in practice: automatic dimension calculation, expressions, aspect-ratio handling, algorithm selection, and the hardware-accelerated variants that are much faster on modern machines.


The Basic Form

ffmpeg -i input.mp4 -vf scale=1280:720 output.mp4

-vf is shorthand for -filter:v. Everything after scale= is a colon-separated argument list, first width then height.

That command re-encodes the video, which is unavoidable — you cannot change frame dimensions without re-encoding, since the dimensions are baked into the compressed bitstream. Because you are re-encoding anyway, it is worth passing quality settings rather than accepting the defaults:

ffmpeg -i input.mp4 -vf scale=1280:720 -c:v libx264 -crf 20 -preset slow -c:a copy output.mp4

-c:a copy passes the audio through untouched, which saves time and avoids a pointless generation of audio loss.


-1 and -2: Automatic Dimensions

Hardcoding both dimensions means you have to know the source aspect ratio. You usually do not, especially in a batch. FFmpeg can compute one from the other.

# Height 1080, width computed to preserve aspect ratio
ffmpeg -i input.mp4 -vf "scale=-2:1080" output.mp4

# Width 1280, height computed
ffmpeg -i input.mp4 -vf "scale=1280:-2" output.mp4

Use -2, not -1. Both preserve the aspect ratio; the difference is rounding.

  • -1 gives the exact computed value, which is frequently odd.
  • -2 rounds to the nearest even number.

H.264, HEVC and most other codecs use 4:2:0 chroma subsampling, which requires even dimensions. Feed libx264 a width of 853 and it will fail with width not divisible by 2. The one-pixel difference -2 introduces is invisible; the error -1 produces is not.

There is also -n for any positive n, which rounds to the nearest multiple of n. scale=-4:720 guarantees divisibility by 4, occasionally required by specific hardware encoders.


Expressions: iw, ih and Arithmetic

The scale filter accepts expressions, not just numbers. The two variables you will use constantly:

  • iw — input width
  • ih — input height
# Half size
ffmpeg -i input.mp4 -vf "scale=iw/2:ih/2" output.mp4

# 75% of original
ffmpeg -i input.mp4 -vf "scale=iw*0.75:ih*0.75" output.mp4

# Double (upscaling — see the caveat below)
ffmpeg -i input.mp4 -vf "scale=iw*2:ih*2" output.mp4

Fractional scaling can produce odd dimensions, so wrap it:

ffmpeg -i input.mp4 -vf "scale=trunc(iw*0.75/2)*2:trunc(ih*0.75/2)*2" output.mp4

That looks worse than it is: divide by 2, truncate to an integer, multiply back by 2. The result is always even.

Conditional scaling is where expressions earn their keep. This downscales anything wider than 1920 and leaves smaller files alone:

ffmpeg -i input.mp4 -vf "scale='min(1920,iw)':-2" output.mp4

Without the min(), a 720p source would be upscaled to 1920 — bigger file, no additional detail, worse than doing nothing. This is the single most useful expression in the filter and it belongs in most batch scripts.


force_original_aspect_ratio

For fitting video into a fixed box without distortion, this option is cleaner than manual expressions.

# Fit inside 1920x1080 — never exceeds either dimension
ffmpeg -i input.mp4 -vf "scale=1920:1080:force_original_aspect_ratio=decrease" output.mp4

# Cover 1920x1080 — fills the box, may overflow one dimension
ffmpeg -i input.mp4 -vf "scale=1920:1080:force_original_aspect_ratio=increase" output.mp4

decrease is the letterbox-friendly behaviour: the output fits entirely within the target and one dimension will usually come up short. increase is the crop-friendly behaviour: the output covers the target and overflows.

Combine decrease with pad to get exact output dimensions with black bars rather than a stretched picture:

ffmpeg -i input.mp4 -vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2" output.mp4

The pad arguments are target width, target height, then x and y offsets. (ow-iw)/2 and (oh-ih)/2 centre the video in the padded frame. This is the standard recipe for delivering mixed-aspect footage to a platform that demands one fixed size.

Note the comma: scale and pad are two filters chained in a single filtergraph, applied left to right.


Choosing the Scaling Algorithm

FFmpeg's default is bicubic. It is a fine default and often not the best choice.

ffmpeg -i input.mp4 -vf "scale=1280:-2:flags=lanczos" output.mp4
AlgorithmBest forCharacter
bicubicGeneral purpose (default)Balanced sharpness and speed
lanczosDownscaling video and photosSharpest perceived detail; slight ringing on hard edges
bilinearSpeed-critical workFast, noticeably soft
neighborPixel art, crisp UI screen recordingsNo interpolation at all; preserves hard pixel edges
splineUpscalingSmooth, low artefacts
areaLarge downscale ratiosAverages source pixels; good anti-aliasing

The practical takeaways: use lanczos when downscaling real-world footage — it is the most common upgrade over the default and costs very little. Use neighbor for screen recordings of text or UI, where interpolation turns crisp pixels into mush. Use area when shrinking dramatically, such as generating thumbnails, where lanczos ringing becomes visible.


Hardware-Accelerated Scaling

On modern machines, scaling on the GPU or media engine is substantially faster, particularly when the decode and encode are already happening there — it avoids round-tripping frames through system memory.

macOS (VideoToolbox):

ffmpeg -hwaccel videotoolbox -i input.mp4 -vf "scale_vt=1280:-2" -c:v h264_videotoolbox output.mp4

NVIDIA:

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

Intel Quick Sync:

ffmpeg -hwaccel qsv -i input.mp4 -vf "scale_qsv=w=1280:h=-1" -c:v h264_qsv output.mp4

Two caveats. The hardware scalers expose fewer options — you generally do not get algorithm selection. And mixing hardware and software filters in one chain forces frames back and forth between GPU and system memory, which can be slower than staying in software the whole way. Keep the chain entirely on one side where you can.

Quality trade-offs of hardware versus software processing are covered in hardware vs software video encoding.


-s vs -vf scale

You will see both in older documentation.

ffmpeg -i input.mp4 -s 1280x720 output.mp4       # legacy shorthand
ffmpeg -i input.mp4 -vf scale=1280:720 output.mp4 # filter

-s sets fixed output dimensions and will stretch the image if the aspect ratio does not match. It offers no expressions, no automatic dimension calculation and no algorithm selection. It also conflicts with a filtergraph that already scales.

Use -vf scale. There is no situation where -s is better.


A Note on Upscaling

The scale filter will upscale as readily as it downscales, but it cannot invent detail that was never captured. Scaling 720p to 4K produces a 4K file that looks like soft 720p, at several times the bitrate. The only things that genuinely gain from upscaling are compatibility with a pipeline that demands a specific resolution, and delivery targets that penalise low resolutions.

If you must upscale, spline or lanczos tend to look best, and it is worth being honest that neither is doing anything a good display's own scaler would not.


Scaling is rarely the only thing you need:


When You Do Not Want a Command Line

FFmpeg is the correct tool when you need exact control, scriptable batches, or something no GUI exposes. It is a poor tool when you just want a folder of video to be smaller and you are looking up the same three flags every time.

Compresto covers the common cases natively on macOS — downscale resolution, set a target size or quality, batch a whole folder, all with hardware acceleration handled automatically. No commands, no dependency install, and files never leave your Mac.

Keep FFmpeg for the unusual jobs. Use Compresto for the routine ones.

Download Compresto for Mac →


Frequently Asked Questions

Why does my FFmpeg scale command fail with "width not divisible by 2"?

You used -1 and the computed dimension came out odd. Switch to -2, which rounds to an even number.

How do I scale a video to a specific file size?

Scaling changes dimensions, not file size directly. To target a size you need to control bitrate — either by calculating a target bitrate from the duration, or by adjusting CRF. See FFmpeg compress video.

Can I scale without re-encoding?

No. Frame dimensions are part of the encoded bitstream, so changing them requires decoding and re-encoding. Only operations that leave the video stream untouched — remuxing to a different container, trimming on keyframes — can avoid re-encoding.

How do I scale multiple videos at once?

A shell loop works: for f in *.mp4; do ffmpeg -i "$f" -vf "scale=-2:720" "out_$f"; done. For anything more involved, a GUI batch tool will be less error-prone.

Does scaling down improve quality?

It cannot add quality, but downscaling does hide compression artefacts and noise by averaging them away, so a downscaled version of a poor source often looks cleaner than the original at full size. It also reduces the bitrate needed for a given perceived quality.

Ready to compress your files? Join thousands of creators using Compresto ⚡