Deband
37c3317fd058; modified for Encode Wiki · CC BY-SA 4.0Banding is visible stepping in what should be a smooth gradient: skies, fades, dark rooms, flat-shaded animation backgrounds. It comes from too few code values to describe the gradient (8-bit sources and dark scenes are the worst), from earlier lossy compression that flattened the noise which hid the steps, or from an 8-bit conversion without dithering. A debander finds those flat steps, smooths across them and adds a little dither so the new values don’t re-band.
It only helps when the banding is in what the encoder receives. Banding that appears only in your encode is the encoder removing noise and flattening the gradient; encode at 10-bit (even from an 8-bit source), use a lower CRF, and consider adding grain or letting the codec synthesise it.
FFmpeg
Section titled “FFmpeg”FFmpeg has two debanders. deband is the one to use before encoding:
ffmpeg -i input.mkv -vf "format=yuv420p10le,deband" -c:v libsvtav1 -crf 30 -pix_fmt yuv420p10le output.mkvdeband replaces pixels that look banded with the average of randomly chosen pixels around them. It runs at any bit depth, but an 8-bit frame has no values between two adjacent steps, so the filter can only scatter pixels across each step edge. Converting to 10-bit first gives it room to produce the in-between values of a smooth gradient, and the encode should be 10-bit anyway. Keep -pix_fmt yuv420p10le on the output: without it, FFmpeg may negotiate deband’s output back down to 8-bit for the encoder.
gradfun fits a gradient and dithers the result back to 8-bit. It only accepts 8-bit formats (FFmpeg silently converts higher bit depths down before it), and its documentation says it is designed for playback: lossy compression tends to remove the dither and bring the bands back. Keep it out of encoding chains.
| Option | What it does |
|---|---|
1thr, 2thr, 3thr | Per-plane threshold, 0.00003 to 0.5, default 0.02. A pixel counts as banded when its difference from its reference pixels is below the threshold, so raising it deals with stronger banding and also flattens more real detail. |
range | How far away the reference pixels are picked, in pixels (randomly up to this value). Default 16. |
blur | On by default: compare against the average of the surrounding pixels. Turning it off requires all four neighbours to be within the threshold, which touches less real detail. |
VapourSynth
Section titled “VapourSynth”For anything beyond a quick pass, vsdeband in vs-jetpack is more flexible. f3k_deband implements f3kdb-style debanding through the vszip plugin; placebo_deband uses libplacebo’s GPU-based debander. Both take a radius and a threshold:
from vsdeband import f3k_deband, deband_detail_mask, Grainer
deband = f3k_deband(clip, radius=16, thr=96)mask = deband_detail_mask(clip)deband = core.std.MaskedMerge(deband, clip, mask) # keep detailed areas untoucheddeband = Grainer.GAUSS(deband, strength=0.5, luma_scaling=10)Deband at high bit depth (the starting script works in 16-bit) and let the final dither to 10-bit carry the result. thr uses the old neo_f3kdb scale (default 96); raise it for stronger banding, and use grain or a separate Grainer pass to add dither-like noise afterwards. A higher luma_scaling reduces the grain in brighter areas, which suits banding because it shows up in the darks. mdb_bilateral is a multi-stage option for extreme banding, and pfdeband blurs first and limits how far the result may move from the original.
The detail mask keeps the debander away from edges and texture. Without it, a threshold high enough to fix the sky also smooths faces and fabric. View the mask (mask.set_output()): it should be white on edges and texture, which keep the original pixels, and black in the flat gradients you want debanded.
Pitfalls
Section titled “Pitfalls”- Too strong a threshold blurs low-contrast detail: dark-scene texture, film grain, skin. Start low and raise it only until the steps vanish.
- Debanding the whole video when only a few scenes band. Apply it to those shots, or at least check the others for damage.
- No grain. A perfectly smooth gradient is exactly what an encoder will quantise back into bands. Fine noise added after debanding survives better.
- HDR. Thresholds are in code values, and a step of a given size looks different in PQ or HLG than in SDR, so re-tune and judge on an HDR display.