{
  "schemaVersion": 1,
  "contentVersion": "ca42e61ede0a24f789d7287a0001244ad22f4abf",
  "id": "docs/tools/filtering/deinterlace",
  "collection": "docs",
  "title": "Deinterlace",
  "description": "How to tell whether a video is really interlaced and how to deinterlace it properly with FFmpeg, vs-jetpack or QTGMC.",
  "canonicalUrl": "https://encode.wiki/tools/filtering/deinterlace/",
  "apiUrl": "https://encode.wiki/api/v1/documents/docs/tools/filtering/deinterlace.json",
  "markdownUrl": "https://encode.wiki/api/v1/markdown/docs/tools/filtering/deinterlace.md",
  "status": "current",
  "tags": [
    "migrated"
  ],
  "license": "CC BY-SA 4.0",
  "dates": {
    "lastVerified": "2026-10-08T00:00:00.000Z"
  },
  "authors": [],
  "sources": [
    {
      "title": "FFmpeg bwdif filter documentation",
      "url": "https://ffmpeg.org/ffmpeg-filters.html#bwdif",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "FFmpeg yadif filter documentation",
      "url": "https://ffmpeg.org/ffmpeg-filters.html#yadif",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "FFmpeg idet filter documentation",
      "url": "https://ffmpeg.org/ffmpeg-filters.html#idet",
      "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": "havsfunc r34 release notes",
      "url": "https://github.com/HomeOfVapourSynthEvolution/havsfunc/releases/tag/r34",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    }
  ],
  "provenance": {
    "originUrl": "https://github.com/av1-community-contributors/codec-wiki/blob/37c3317fd058b23c71a87679bed5619a98f77752/docs/filtering/deinterlace.mdx",
    "originCommit": "37c3317fd058b23c71a87679bed5619a98f77752",
    "migratedAt": "2026-08-21T00:00:00.000Z",
    "modified": true,
    "originPath": "docs/filtering/deinterlace.mdx"
  },
  "headings": [
    {
      "depth": 2,
      "text": "Check the source",
      "anchor": "check-the-source"
    },
    {
      "depth": 2,
      "text": "Single rate or double rate",
      "anchor": "single-rate-or-double-rate"
    },
    {
      "depth": 2,
      "text": "FFmpeg",
      "anchor": "ffmpeg"
    },
    {
      "depth": 2,
      "text": "VapourSynth",
      "anchor": "vapoursynth"
    },
    {
      "depth": 2,
      "text": "Check the result",
      "anchor": "check-the-result"
    }
  ],
  "sections": [
    {
      "id": "_preamble",
      "title": "Page introduction",
      "depth": 0,
      "canonicalUrl": "https://encode.wiki/tools/filtering/deinterlace/",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/tools/filtering/deinterlace/_preamble.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/tools/filtering/deinterlace/_preamble.md",
      "checksum": "39d005b72e83b297212e699ee55bc1257f1aa4723f6177b296d68c487f6e6702",
      "bytes": 1911
    },
    {
      "id": "check-the-source",
      "title": "Check the source",
      "depth": 2,
      "anchor": "check-the-source",
      "canonicalUrl": "https://encode.wiki/tools/filtering/deinterlace/#check-the-source",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/tools/filtering/deinterlace/check-the-source.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/tools/filtering/deinterlace/check-the-source.md",
      "checksum": "a1344215b41ab9b89b1183571276014ccc8da28483517c8e325764505999566f",
      "bytes": 875
    },
    {
      "id": "single-rate-or-double-rate",
      "title": "Single rate or double rate",
      "depth": 2,
      "anchor": "single-rate-or-double-rate",
      "canonicalUrl": "https://encode.wiki/tools/filtering/deinterlace/#single-rate-or-double-rate",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/tools/filtering/deinterlace/single-rate-or-double-rate.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/tools/filtering/deinterlace/single-rate-or-double-rate.md",
      "checksum": "24ede39f8c3760a9c471659bbfd43280eee4058ee93a4e41bca5ae581173dca0",
      "bytes": 526
    },
    {
      "id": "ffmpeg",
      "title": "FFmpeg",
      "depth": 2,
      "anchor": "ffmpeg",
      "canonicalUrl": "https://encode.wiki/tools/filtering/deinterlace/#ffmpeg",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/tools/filtering/deinterlace/ffmpeg.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/tools/filtering/deinterlace/ffmpeg.md",
      "checksum": "b2771ab617add6b52d890cb136df0c2c20ddf5dbbe7a22e167fc5a113148b8ba",
      "bytes": 843
    },
    {
      "id": "vapoursynth",
      "title": "VapourSynth",
      "depth": 2,
      "anchor": "vapoursynth",
      "canonicalUrl": "https://encode.wiki/tools/filtering/deinterlace/#vapoursynth",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/tools/filtering/deinterlace/vapoursynth.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/tools/filtering/deinterlace/vapoursynth.md",
      "checksum": "d1ecd9028bf31ce39237f6ba732b95248d6c2dfce0f273e35e6e1253a844bdf4",
      "bytes": 1320
    },
    {
      "id": "check-the-result",
      "title": "Check the result",
      "depth": 2,
      "anchor": "check-the-result",
      "canonicalUrl": "https://encode.wiki/tools/filtering/deinterlace/#check-the-result",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/tools/filtering/deinterlace/check-the-result.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/tools/filtering/deinterlace/check-the-result.md",
      "checksum": "5738d69f04adc3a4c6decf653fac171e28549ed5a51e9dd87f11ce7394face7f",
      "bytes": 373
    }
  ],
  "outboundReferences": [
    "/tools/filtering/decombing/",
    "/tools/filtering/ivtc/",
    "http://avisynth.nl/index.php/QTGMC",
    "https://gist.github.com/Ichunjo/76c96f1130c9e9f972de956f40571e54"
  ],
  "checksum": "660f8a8da384f1d0bcd5181993d683496a3ffe552d199b42ef9cac72c1ffdda4",
  "contentFormat": "markdown",
  "markdown": "Interlaced video stores each frame as two fields captured a moment apart, one holding the odd lines and the other the even lines. A 1080i or 576i broadcast, a DVD or a camcorder recording carries 50 or 59.94 fields per second this way. Shown as a single frame, any moving edge looks like a comb. Deinterlacing rebuilds full progressive frames from the fields.\n\nBefore you deinterlace, work out what you actually have, because three different things get called \"interlaced\":\n\n| Source                                                                | What it looks like                                                            | What to do                                                                                     |\n| --------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |\n| True interlaced (video camera, sports, live TV)                       | Every moving frame is combed; each field is a separate moment in time         | Deinterlace, as on this page                                                                   |\n| Telecined film (NTSC DVDs of movies, some anime)                      | A repeating pattern of three clean frames and two combed ones in every five   | [Inverse telecine](/tools/filtering/ivtc/), which gets back the original 24 progressive frames |\n| Progressive content stored as fields (most PAL film DVDs, 25p as 50i) | Combing only when the fields are mismatched; matching them gives clean frames | Field-match and weave; no interpolation needed                                                 |\n\nDeinterlacing telecined or already-progressive material throws away detail for nothing. Mixed sources and leftover combing are covered in [decombing](/tools/filtering/decombing/).\n\n## Check the source\n\nFFmpeg's `idet` classifies frames. Run it over part of the video that has motion:\n\n```sh\nffmpeg -ss 600 -t 30 -i input.mkv -vf idet -f null -\n```\n\nThe summary reports how many frames are top field first (TFF), bottom field first (BFF) and progressive, plus a \"Repeated Fields\" line whose Top/Bottom counts are the sign of telecine. Mostly TFF or BFF with no repeated fields means true interlaced. Then step through a few moving frames in a previewer to confirm: you should see combing, and in true interlaced video each field-to-field step has fresh motion.\n\nContainer flags are often wrong, especially on DVD rips, so don't rely on them alone. Field order matters: if you deinterlace with the wrong order, motion steps backward and forward and looks jerky. When `idet` and the container disagree, test both on a clip with a pan and keep the smooth one.\n\n## Single rate or double rate\n\nA deinterlacer can output one frame per frame (25 or 29.97 fps, a \"single-rate\" or `send_frame` result), or one frame per field (50 or 59.94 fps, \"double rate\" or \"bob\"). Double rate keeps all the motion the source captured and is what you want for sports and anything with fast movement, but it needs a higher-framerate encode and player support. Single rate discards half the temporal information; it is a fine choice when you need to stay at the source frame rate and the motion is moderate.\n\n## FFmpeg\n\n`bwdif` is the usual FFmpeg choice: a motion-adaptive deinterlacer based on yadif, with w3fdif and cubic interpolation added. It outputs double rate by default:\n\n```sh\nffmpeg -i input.mkv -vf bwdif -c:v libx264 -crf 18 output.mkv\n```\n\nAdd `mode=send_frame` for single rate. Field order is detected from the stream; if that is wrong, set it with `parity=tff` or `parity=bff`. Leave `deint` alone unless you want to touch only frames flagged as interlaced, which trusts the flags.\n\n`yadif` is the older filter with similar options, and it defaults to single rate. FFmpeg's `nnedi` filter needs a separate weights file. For a one-off conversion any of these is adequate; use VapourSynth when you want better quality or control.\n\nDeinterlace before scaling or any filter that mixes lines, since resizing blends the two fields together.\n\n## VapourSynth\n\n[QTGMC](http://avisynth.nl/index.php/QTGMC) is the community's highest-quality deinterlacer: motion-compensated, with built-in noise handling and temporal stabilisation, and much slower than FFmpeg's filters. In vs-jetpack it is `QTempGaussMC` in `vsdeinterlace`. The `havsfunc` package no longer provides QTGMC, and its parameter names differ from the new implementation (there is a [mapping](https://gist.github.com/Ichunjo/76c96f1130c9e9f972de956f40571e54)).\n\n```python\nfrom vsdeinterlace import QTempGaussMC\n\nclip = QTempGaussMC().deinterlace(clip, tff=True)\n```\n\nThat returns double rate. For single rate, QTGMC's motion-blur stage can divide the frame rate:\n\n```python\nclip = QTempGaussMC().motion_blur(fps_divisor=2).deinterlace(clip, tff=True)\n```\n\nIf `tff` is omitted it is read from the clip's `_FieldBased` property, so set it yourself when you aren't sure the source filter marked it correctly. For something lighter, `vsaa` has plain bobbers:\n\n```python\nfrom vsaa import NNEDI3, BWDIF\n\nclip = NNEDI3().deinterlace(clip, tff=True, double_rate=True)\nclip = BWDIF().deinterlace(clip, tff=True, double_rate=True)\n```\n\nNNEDI3 interpolates only the missing lines of each field with a neural network and is much quicker than QTGMC, though it doesn't clean up temporal artefacts the way QTGMC does.\n\n## Check the result\n\nLook at scrolling text, thin horizontal lines and fast pans. Remaining combing means the wrong field order or a missed mode; shimmering thin lines are normal single-pass bobbing and what QTGMC's stabilisation exists to reduce. If the frame count of your output isn't what you expected (double rate doubles it), check it with `ffprobe` before encoding.\n"
}
