{
  "schemaVersion": 1,
  "contentVersion": "ca42e61ede0a24f789d7287a0001244ad22f4abf",
  "id": "docs/tools/filtering/deband",
  "collection": "docs",
  "title": "Deband",
  "description": "Debanding smooths the visible steps in gradients such as skies and dark scenes; this page covers the FFmpeg and vs-jetpack options and how to avoid smearing real detail.",
  "canonicalUrl": "https://encode.wiki/tools/filtering/deband/",
  "apiUrl": "https://encode.wiki/api/v1/documents/docs/tools/filtering/deband.json",
  "markdownUrl": "https://encode.wiki/api/v1/markdown/docs/tools/filtering/deband.md",
  "status": "current",
  "tags": [
    "migrated"
  ],
  "license": "CC BY-SA 4.0",
  "dates": {
    "lastVerified": "2026-10-08T00:00:00.000Z"
  },
  "authors": [],
  "sources": [
    {
      "title": "FFmpeg deband filter documentation",
      "url": "https://ffmpeg.org/ffmpeg-filters.html#deband",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "FFmpeg gradfun filter documentation",
      "url": "https://ffmpeg.org/ffmpeg-filters.html#gradfun",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "vs-jetpack v2.2.6",
      "url": "https://github.com/Jaded-Encoding-Thaumaturgy/vs-jetpack/tree/v2.2.6",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "vapoursynth-zip Deband wiki",
      "url": "https://github.com/dnjulek/vapoursynth-zip/wiki/Deband",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    }
  ],
  "provenance": {
    "originUrl": "https://github.com/av1-community-contributors/codec-wiki/blob/37c3317fd058b23c71a87679bed5619a98f77752/docs/filtering/deband.mdx",
    "originCommit": "37c3317fd058b23c71a87679bed5619a98f77752",
    "migratedAt": "2026-08-21T00:00:00.000Z",
    "modified": true,
    "originPath": "docs/filtering/deband.mdx"
  },
  "headings": [
    {
      "depth": 2,
      "text": "FFmpeg",
      "anchor": "ffmpeg"
    },
    {
      "depth": 2,
      "text": "VapourSynth",
      "anchor": "vapoursynth"
    },
    {
      "depth": 2,
      "text": "Pitfalls",
      "anchor": "pitfalls"
    }
  ],
  "sections": [
    {
      "id": "_preamble",
      "title": "Page introduction",
      "depth": 0,
      "canonicalUrl": "https://encode.wiki/tools/filtering/deband/",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/tools/filtering/deband/_preamble.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/tools/filtering/deband/_preamble.md",
      "checksum": "6eb9d192411e951f0da9b48bdd1920fb52637e27478e9a1a43c5b3f66028748a",
      "bytes": 789
    },
    {
      "id": "ffmpeg",
      "title": "FFmpeg",
      "depth": 2,
      "anchor": "ffmpeg",
      "canonicalUrl": "https://encode.wiki/tools/filtering/deband/#ffmpeg",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/tools/filtering/deband/ffmpeg.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/tools/filtering/deband/ffmpeg.md",
      "checksum": "99263312c032c741aa384b14fc355c26743de5d6e11b67db0cfa23fa93d7d34d",
      "bytes": 2330
    },
    {
      "id": "vapoursynth",
      "title": "VapourSynth",
      "depth": 2,
      "anchor": "vapoursynth",
      "canonicalUrl": "https://encode.wiki/tools/filtering/deband/#vapoursynth",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/tools/filtering/deband/vapoursynth.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/tools/filtering/deband/vapoursynth.md",
      "checksum": "7619672fb338f8adc462e26bc41a50cefa413beda628abef7f7a9e7039829aab",
      "bytes": 1481
    },
    {
      "id": "pitfalls",
      "title": "Pitfalls",
      "depth": 2,
      "anchor": "pitfalls",
      "canonicalUrl": "https://encode.wiki/tools/filtering/deband/#pitfalls",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/tools/filtering/deband/pitfalls.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/tools/filtering/deband/pitfalls.md",
      "checksum": "f76c933fb9ee997ad6d43376e3f8e546011e91f1679c762f38c06a8a645b4528",
      "bytes": 589
    }
  ],
  "outboundReferences": [
    "/tools/filtering/basics/#starting-script",
    "/tools/filtering/graining/",
    "/tools/filtering/vapoursynth/"
  ],
  "checksum": "b16c6f6816c04897c5bab9cc06708cecc5d7b43bf692b9c67ad4edf765b79556",
  "contentFormat": "markdown",
  "markdown": "Banding 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.\n\nIt 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](/tools/filtering/graining/) or letting the codec synthesise it.\n\n## FFmpeg\n\nFFmpeg has two debanders. `deband` is the one to use before encoding:\n\n```sh\nffmpeg -i input.mkv -vf \"format=yuv420p10le,deband\" -c:v libsvtav1 -crf 30 -pix_fmt yuv420p10le output.mkv\n```\n\n`deband` 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.\n\n`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.\n\n| Option                 | What it does                                                                                                                                                                                                                    |\n| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `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. |\n| `range`                | How far away the reference pixels are picked, in pixels (randomly up to this value). Default 16.                                                                                                                                                                     |\n| `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.                                                   |\n\n## VapourSynth\n\nFor anything beyond a quick pass, `vsdeband` in [vs-jetpack](/tools/filtering/vapoursynth/) 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:\n\n```python\nfrom vsdeband import f3k_deband, deband_detail_mask, Grainer\n\ndeband = f3k_deband(clip, radius=16, thr=96)\nmask = deband_detail_mask(clip)\ndeband = core.std.MaskedMerge(deband, clip, mask)   # keep detailed areas untouched\ndeband = Grainer.GAUSS(deband, strength=0.5, luma_scaling=10)\n```\n\nDeband at high bit depth (the [starting script](/tools/filtering/basics/#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.\n\nThe 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.\n\n## Pitfalls\n\n- **Too strong a threshold** blurs low-contrast detail: dark-scene texture, film grain, skin. Start low and raise it only until the steps vanish.\n- **Debanding the whole video** when only a few scenes band. Apply it to those shots, or at least check the others for damage.\n- **No grain.** A perfectly smooth gradient is exactly what an encoder will quantise back into bands. Fine noise added after debanding survives better.\n- **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.\n"
}
