66from math import comb , sqrt
77from typing import Any , Literal , Protocol , Self , TypedDict , overload
88
9- from jetpytools import CustomIntEnum , CustomValueError , FuncExcept , cachedproperty , fallback , normalize_seq , to_arr
9+ from jetpytools import (
10+ CustomEnum ,
11+ CustomIntEnum ,
12+ CustomValueError ,
13+ FuncExcept ,
14+ cachedproperty ,
15+ fallback ,
16+ normalize_seq ,
17+ to_arr ,
18+ )
1019
1120from vsaa import NNEDI3
1221from vsdeband import Grainer
@@ -93,7 +102,7 @@ class Mask(TypedDict, total=False):
93102
94103
95104class _QTGMCBuilder :
96- class NoiseDeintMode (CustomIntEnum ):
105+ class NoiseDeintMode (CustomEnum ):
97106 """How to 'deinterlace' noise taken from an interlaced source."""
98107
99108 WEAVE = auto ()
@@ -115,7 +124,7 @@ class NoiseDeintMode(CustomIntEnum):
115124 Generate fresh noise lines.
116125 """
117126
118- class LosslessMode (CustomIntEnum ):
127+ class LosslessMode (CustomEnum ):
119128 """When to put the original fields into the output."""
120129
121130 NONE = auto ()
@@ -138,7 +147,7 @@ class LosslessMode(CustomIntEnum):
138147 not used. Offers minimal sharpness control and tends to have more significant artifacts.
139148 """
140149
141- class BackBlendMode (CustomIntEnum ):
150+ class BackBlendMode (CustomEnum ):
142151 """When to back-blend the (blurred) difference between the pre- and post-sharpened clips."""
143152
144153 NONE = auto ()
@@ -177,7 +186,7 @@ class BackBlendMode(CustomIntEnum):
177186 `SharpenLimitMode.TEMPORAL_POSTSMOOTH`.
178187 """
179188
180- class SharpenLimitMode (CustomIntEnum ):
189+ class SharpenLimitMode (CustomEnum ):
181190 """How and when to apply limiting to [QTempGaussMC.sharpen][vsdeinterlace.QTempGaussMC.sharpen]."""
182191
183192 NONE = auto ()
@@ -217,22 +226,22 @@ class SharpenLimitMode(CustomIntEnum):
217226 algorithm leaves the result sharper, but can produce additional artifacts.
218227 """
219228
220- @cachedproperty
229+ @property
221230 def is_spatial (self ) -> bool :
222231 """Whether the mode uses spatial sharpness limiting."""
223232 return self in (self .SPATIAL_PRESMOOTH , self .SPATIAL_POSTSMOOTH )
224233
225- @cachedproperty
234+ @property
226235 def is_temporal (self ) -> bool :
227236 """Whether the mode uses temporal sharpness limiting."""
228237 return self in (self .TEMPORAL_PRESMOOTH , self .TEMPORAL_POSTSMOOTH )
229238
230- @cachedproperty
239+ @property
231240 def is_presmooth (self ) -> bool :
232241 """Whether the mode applies sharpness limiting prior to smoothing."""
233242 return self in (self .SPATIAL_PRESMOOTH , self .TEMPORAL_PRESMOOTH )
234243
235- @cachedproperty
244+ @property
236245 def is_postsmooth (self ) -> bool :
237246 """Whether the mode applies sharpness limiting after smoothing."""
238247 return self in (self .SPATIAL_POSTSMOOTH , self .TEMPORAL_POSTSMOOTH )
@@ -293,7 +302,7 @@ def prefilter(
293302 * ,
294303 tr : int = 2 ,
295304 sc_threshold : float = 0.1 ,
296- strength : tuple [float , float ] = (1.9 , 0.9 ),
305+ strength : tuple [float , float ] = (1.96 , 0.9 ),
297306 limit : tuple [float , float , float ] = (3 , 7 , 2 ),
298307 bias : float = 0.51 ,
299308 mask_shimmer_args : QTGMCArgs .MaskShimmer | None = None ,
@@ -917,7 +926,7 @@ class QTGMCGraph(VSObject):
917926 Additional usage info: [JET Encoding Guide](https://jaded-encoding-thaumaturgy.github.io/JET-guide/master/filtering/situational/qtgmc/)
918927 """
919928
920- class Mode (CustomIntEnum ):
929+ class Mode (CustomEnum ):
921930 """Processing mode used to construct the graph."""
922931
923932 DEINTERLACE = auto ()
@@ -1048,27 +1057,24 @@ def prefilter(self) -> vs.VideoNode:
10481057 else :
10491058 smoothed = search
10501059
1051- gauss_sigma , blend_weight = self .settings .prefilter_strength
1052- apply_blur = bool (gauss_sigma and blend_weight )
1060+ sigma , blend_weight = self .settings .prefilter_strength
10531061 lim1 , lim2 , lim3 = [scale_delta (thr , 8 , self .clip ) for thr in self .settings .prefilter_limit ]
10541062
1055- blurred = gauss_blur (smoothed , gauss_sigma ) if apply_blur else smoothed
1056-
1057- if apply_blur or (self .settings .prefilter_tr and lim1 and (lim2 or lim3 )):
1058- blurred = norm_expr (
1059- [blurred , smoothed , search ],
1060- "y x y - {weight} * + BLUR! z y {lim1} - y {lim1} + clamp TWEAK! "
1061- "BLUR@ {lim2} + TWEAK@ < BLUR@ {lim3} + BLUR@ {lim2} - TWEAK@ > BLUR@ {lim3} - "
1062- "TWEAK@ BLUR@ TWEAK@ - {bias} * + ? ?" ,
1063- weight = blend_weight ,
1064- lim1 = lim1 ,
1065- lim2 = lim2 ,
1066- lim3 = lim3 ,
1067- bias = self .settings .prefilter_bias ,
1068- func = self .func ,
1069- )
1063+ blurred = gauss_blur (smoothed , sigma ) if sigma and blend_weight else smoothed
1064+ limited = norm_expr (
1065+ [blurred , smoothed , search ],
1066+ "y x y - {weight} * + BLUR! z y {lim1} - y {lim1} + clamp TWEAK! "
1067+ "BLUR@ {lim2} + TWEAK@ < BLUR@ {lim3} + BLUR@ {lim2} - TWEAK@ > BLUR@ {lim3} - "
1068+ "TWEAK@ BLUR@ TWEAK@ - {bias} * + ? ?" ,
1069+ weight = blend_weight ,
1070+ lim1 = lim1 ,
1071+ lim2 = lim2 ,
1072+ lim3 = lim3 ,
1073+ bias = self .settings .prefilter_bias ,
1074+ func = self .func ,
1075+ )
10701076
1071- return prefilter_to_full_range (blurred , func = self .func , ** self .settings .prefilter_range_expansion_args )
1077+ return prefilter_to_full_range (limited , func = self .func , ** self .settings .prefilter_range_expansion_args )
10721078
10731079 @cachedproperty
10741080 def mv (self ) -> MVTools :
@@ -1249,11 +1255,7 @@ def basic(self) -> vs.VideoNode:
12491255 self .settings .BackBlendMode .BOTH ,
12501256 ):
12511257 resharp = self ._back_blend (resharp , smoothed )
1252- elif (
1253- self .settings .back_blend_mode is not self .settings .BackBlendMode .NONE
1254- and self ._sharpening_enabled
1255- and not self ._back_blend_noop
1256- ):
1258+ elif self .settings .back_blend_mode is not self .settings .BackBlendMode .NONE and self ._sharpening_enabled :
12571259 resharp = self ._back_blend (resharp , smoothed )
12581260
12591261 return self ._noise_restore (resharp , self .settings .basic_noise_restore )
@@ -1344,17 +1346,12 @@ def _sharpen_sigma(self) -> float:
13441346 def _sharpening_enabled (self ) -> bool :
13451347 return bool (self .settings .sharpen_strength and self ._sharpen_sigma )
13461348
1347- @cachedproperty
1348- def _back_blend_noop (self ) -> bool :
1349- return not (self .settings .back_blend_mode is self .settings .BackBlendMode .NONE or self .settings .back_blend_scale )
1350-
13511349 @cachedproperty
13521350 def _sharpness_limiting_enabled (self ) -> bool :
13531351 return (
13541352 self .settings .sharpen_limit_mode is not self .settings .SharpenLimitMode .NONE
13551353 and bool (self .settings .sharpen_limit_radius )
13561354 and self ._sharpening_enabled
1357- and not self ._back_blend_noop
13581355 )
13591356
13601357 @cachedproperty
@@ -1469,9 +1466,6 @@ def _sharpen(self, clip: vs.VideoNode) -> vs.VideoNode:
14691466 resharp = clip
14701467
14711468 if self ._sharpening_enabled :
1472- if self ._back_blend_noop :
1473- return clip
1474-
14751469 if self .settings .sharpen_offset is not False :
14761470 dark_offset , bright_offset = self .settings .sharpen_offset
14771471
0 commit comments