Skip to content

DecombUCF

Rainman74 edited this page Sep 18, 2025 · 1 revision

DecombUCF Filters (KFM.dll)

Scene‑change–aware frame replacement filters in KFM, inspired by and extended from DecombUCF (merged scene‑change logic, CUDA‑enabled).

Reference: DecombUCF by ちょっとだけ.

KNoiseClip(clip, clip, int "nmin_y", int "range_y", int "nmin_uv", int "range_uv")

Pre‑processing filter for noise analysis used by DecombUCF

  • clip – Source clip
  • clip – Noise‑detection clip (e.g., source with Gaussian blur applied)
  • int nmin_y = 1
  • int range_y = 128
  • int nmin_uv = 1
  • int range_uv = 128

KAnalyzeNoise(clip, clip, clip "pad")

Noise analysis filter for DecombUCF

  • CUDA support: Yes
  • clip – Source clip
  • clipKNoiseClip clip
  • clip "pad"KFMPad clip

KDecombUCFParam(int "chroma", float "fd_thresh", int "th_mode", float "off_t", float "off_b", float "namax_thresh", float "namax_diff", float "nrt1y", float "nrt2y", float "nrt2x", float "nrw", bool "show", float "y1", float "y2", float "y3", float "y4", float "y5", float "x1", float "x2", float "x3", float "x4", float "x5")

Parameter clip for DecombUCF

  • CUDA support:

  • int chroma = 1[0–2] #(0:Y), (1:UV), (2:YUV) for noise detection

  • float fd_thresh = 128[0–] #threshold of FieldDiff; fd_thresh = FieldDiff * 100 / (Width * Height)

  • int th_mode = 0[1–2:debug][3–7:normal][8–10:restricted] #preset of diff threshold. You can also specify thresholds via x1–x5/y1–y5 (requires th_mode=0).

  • float off_t = 0 – Offset for top‑field diff threshold (first field, top, diff<0)

  • float off_b = 0 – Offset for bottom‑field diff threshold (second field, bottom, 0<diff)

  • reverse (works only when chroma=0. If absolute noise is too large, treat it as a visual effect and keep the noisier field; the smaller one is flattened by block noise)

    • int namax_thresh = 8282 #MX:90 #[0–256] #disabled with chroma=1; upper limit of max noise for detection (75–80–83)
    • int namax_diff = 3830–40 #disabled with chroma=1; if average noise ≥ namax_thresh, use namax_diff as diff threshold.
  • NR

    • float nrt1y = 2828–29–30 #threshold for NR
    • float nrt2y = 3636–36.5–37 #exclusion range
    • float nrt2x = 53.553–54–55 #exclusion range
    • float nrw = 21–2 #diff weight for NR threshold
  • bool show = false – Turn on debug display (actual behavior varies by filter)

  • float y1..y5, x1..x5 – Score calculation parameters

KDecombUCF(clip, clip, clip, clip, clip, clip "nr")

Analyzes a 24p clip and applies replacement to a 24p clip (same as the original).

  • CUDA support: Yes
  • clip – Target 24p clip
  • clipKDecombUCFParam clip
  • clipKAnalyzeNoise clip
  • clipbob clip (for when the next field is corrupted)
  • clipbob clip (for when the previous field is corrupted)
  • clip "nr" – Optional NR clip

Two bob clips are required because QTGMC‑like bob filters interpolate from both previous and next fields. Even if you choose the previous field to avoid a corrupted field, the nature of the algorithm still mixes in the corrupted field. To avoid this, input two bob clips: one interpolated without using the next field and one without using the previous field, and switch between them appropriately.

The original QTGMC has no option to “not use the next/previous field”. KTGMC can switch this via useFlag. See the usage example below.

Example

TODO

KDecombUCF24(clip, clip, clip, clip, clip, clip "nr")

Analyzes a 60i clip and applies replacement to a 24p clip.

  • CUDA support: Yes
  • clip – Target 24p clip
  • clipKDecombUCFParam clip
  • clipKFMCycleAnalyze clip
  • clipKAnalyzeNoise clip
  • clipbob clip (for when the next field is corrupted)
  • clipbob clip (for when the previous field is corrupted)
  • clip "nr" – Optional NR clip

Example

TODO

KDecombUCF60(clip, clip, clip, clip, clip, clip "nr", float "sc_thresh", float "dup_factor")

Analyzes a 60i clip and applies replacement to a 60p clip.

  • Algorithm

    • Roughly: the primary judgment uses DecombUCF noise detection; the secondary judgment uses scene‑change detection (both to improve accuracy).
    • Perform DecombUCF noise detection on each frame of the DoubleWeaved interlaced source.
      • Frames corresponding to fields detected as “dirty” are marked “dirty frames.”
    • Not all dirty frames are replaced; replacement occurs only if both of the following hold:
      • The dirty frame lies around a scene change; and
      • The frame before or after the replacement candidate is static
        • Static frames are likely clean
        • Motion‑heavy segments are rejected by this criterion
    • Additionally, for the dirty frame and its ±1 neighbors, the bob clip is selected to avoid the dirty field.
      • In other words, the dirty frame and its neighbors are replaced by frames drawn from the bob clip.
  • CUDA support: Yes

  • clip – Target 60p clip

  • clipKDecombUCFParam clip

  • clipKAnalyzeNoise clip

  • clipbob clip (when the next field is corrupted)

  • clipbob clip (when the previous field is corrupted)

  • clip "nr" – Optional NR clip

  • float sc_thresh = 256 – Threshold to determine scene changes around the replacement target. Smaller → more frames considered scene changes.

  • float dup_factor = 2.5 – Threshold to determine whether frames around the replacement target are static. Smaller → more frames considered static.

Example

srcpath = "..."
src = LWLibavVideoSource(srcpath,dominance=1,repeat=True).OnCPU(2)
bob = src.KTGMC(Preset="Faster")
before = src.KTGMC(Preset="Faster", PrevGlobals="Reuse", useFlag=1)
after = src.KTGMC(Preset="Faster", PrevGlobals="Reuse", useFlag=2)
fields = src.SeparateFields().Crop(4,4,-4,-4).Align()
noise = fields.KGaussResize(p=2.5)
noise = src.KAnalyzeNoise(fields.KNoiseClip(noise), src.KFMPad()).OnCUDA(2)
bob.KDecombUCF60(KDecombUCFParam(), noise, before, after).OnCUDA(2)