def limit_filter(
flt: vs.VideoNode, src: vs.VideoNode, ref: vs.VideoNode | None = None,
mode: LimitFilterMode = LimitFilterMode.CLAMPING, planes: PlanesT = None,
thr: float | tuple[float, float] = 1, elast: float = 2.0, bright_thr: float | None = None
) -> ConstantFormatVideoNode:
assert check_variable(src, limit_filter)
assert check_variable(flt, limit_filter)
check_ref_clip(src, flt, limit_filter)
check_ref_clip(flt, ref, limit_filter)
if ref is not None:
assert check_variable(ref, limit_filter)
planes = normalize_planes(flt, planes)
is_yuv = flt.format.color_family == vs.YUV
got_ref = ref is not None
if isinstance(thr, tuple):
thr, thrc = thr
else:
thrc = thr
if bright_thr is None:
bright_thr = thr
for var, name, lower_bound in [
(thr, 'thr', 0), (thrc, 'thrc', 0), (bright_thr, 'bright_thr', 0), (elast, 'elast', 1)
]:
if var < lower_bound:
raise CustomIndexError(f'{name} must be >= {lower_bound}', limit_filter, reason=var)
if ref is None and mode != LimitFilterMode.CLAMPING:
raise CustomValueError('You need to specify ref!', limit_filter, reason='mode={mode}', mode=mode)
force_expr = mode.force_expr
if any([
got_ref, flt.format.sample_type == vs.FLOAT,
thr >= 128, bright_thr >= 128, mode != LimitFilterMode.CLAMPING
]):
force_expr = True
if thr <= 0 and bright_thr <= 0 and (not is_yuv or thrc <= 0):
return src
if thr >= 255 and bright_thr >= 255 and (not is_yuv or thrc >= 255):
return flt
if force_expr:
peak = get_peak_value(flt)
clips = [flt, src]
if ref:
clips.append(ref)
return norm_expr(
clips,
(_limit_filter_expr(got_ref, thr, elast, bright_thr, peak, mode),
_limit_filter_expr(got_ref, thrc, elast, thrc, peak, mode)),
func=limit_filter
)
diff = flt.std.MakeDiff(src, planes)
diff = _limit_filter_lut(diff, elast, thr, bright_thr, [0])
if 1 in planes or 2 in planes:
diff = _limit_filter_lut(diff, elast, thrc, thrc, list({*planes} - {0}))
return flt.std.MakeDiff(diff, planes)