Log in

View Full Version : Stab_Light v1.4 — CleanEdges pre-pass for mirror mode


shurik_pronkin
7th April 2026, 06:19
Stab_Light v1.4 — CleanEdges pre-pass for mirror mode

Added a small but practically important pre-pass to Stab_Light that fixes a long-standing problem with mirror=true on film-sourced material.

The problem

DePan's mirror fill replicates pixels from the current frame edge outward into the area exposed by the shift. If the source has even a 1–2 px residual black strip at the edge — typical after SmartCrop or any block-adaptive border removal where the crop amount varies between blocks of frames, also common on jittery film reels and telecined material — then the mirror source is that black strip, and the entire mirror fill region turns into a black band. The whole point of mirror mode is defeated.

Why detection-based cleanup doesn't work

My first attempt used FindBorders (already present in the script for FillBorders2) with an AverageLuma threshold to detect and clean only the affected edges. It failed in practice because residual strips after SmartCrop's block-based pass are non-uniform along the edge — 0 px in one vertical block, 1 px in the next, 2 px in another. AverageLuma over the full column averages these out to something like 40–60, which no sane threshold catches without also eating real dark content in night scenes.

The fix

Unconditional edge-pixel replication via FillBorders(mode=0) on a small fixed number of pixels (default 2) on all four sides, before DePan sees the frame. No detection, no threshold. 2 px out of 720 is visually indistinguishable from the source, and DePan is now guaranteed to see clean edges regardless of what was actually there.

Critically: motion estimation still runs on the unmodified pre_clp. Only the clip that gets warped and mirrored is cleaned. Vector accuracy is unaffected.

New parameters
CleanEdges Default: =mirror - Enable the pre-pass. Auto-on whenever mirror=true.
CleanMaxB Default: 2 - Pixels per side to replicate. 2 covers typical
SmartCrop residue; raise to 3-4 for very jittery
reels. Visually invisible at these values.
CleanInterlaced Default: false - Pass-through to FillBorders for sources flagged
as interlaced (DVD MPEG-2).

Implementation
Function CleanThinEdges(clip c, int "MaxB", bool "interlaced") {
MaxB = Default(MaxB, 2)
interlaced = Default(interlaced, false)
return c.FillBorders(left=MaxB, top=MaxB, right=MaxB, bottom=MaxB,
\ mode=0, y=3, u=3, v=3, interlaced=interlaced)
}

Wired in just before the DePan call:
inter_dp = CleanEdges ? CleanThinEdges(inter, MaxB=CleanMaxB, interlaced=CleanInterlaced) : inter

dp = DePan(inter_dp, data=mdata, offset=-1, mirror=mirror?15:0,
\ pixaspect=PAR, matchfields=false, subpixel=2)

Notes

Use CleanMaxB=2 (even number) for YV12 — odd values get rounded on chroma due to 2× subsampling, leaving stale chroma columns at the edge. With even values FillBorders handles luma and chroma cleanly.
For DVD MPEG-2 sources flagged as interlaced, either set CleanInterlaced=true or — better, if the content is actually progressive — call AssumeFrameBased() right after the source filter. The latter also helps DePan estimate vectors on full frames instead of fields.
No effect when mirror=false unless explicitly set CleanEdges=true — the existing FixBorders / FillBorders2 path handles that case.
No change to output dimensions. The frame is not cropped — only the outermost N pixels are replaced by their immediate neighbours.


Tested on DVD animation with SmartCrop in front of Stab_Light. With the previous version, mirror=true was unusable on these sources — black bands all over the mirror fill area. With CleanEdges=true the mirror fill is finally clean.

Full updated Stab_Light_1.4.avsi attached.

StainlessS
7th April 2026, 14:19
Tanx Shurik,
Can I ask that in future you try to remember to add link to your D9 thread for your version (in the avs somewhere, ideally after note of version number).
Most people dont do this, I usually try to, if I remember, although I might forget and only add in the D9 post of a script (if whole script posted on d9).
Dont bother for now, but if modded again, try to append, and also for your future scripts too please.
(everybody should be doing this but none of us is perfect)
[EDIT: can be difficult to add link when the post dont exist yet, I usually post then add zip with script within a few minutes, with link to the new post]

EDIT: And/Or, add a "Stab_Light v1.4 continued here" type comment to post after this one,
https://forum.doom9.org/showthread.php?p=1939729#post1939729

EDIT: Thank you shurik_pronkin for waking us ol' timers up, you're do'in a good job, please continue. :)