soifunc 0.10.1__py3-none-any.whl → 0.11.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
soifunc/__init__.py CHANGED
@@ -1,3 +1,4 @@
1
1
  from .deband import * # noqa: F401, F403
2
2
  from .denoise import * # noqa: F401, F403
3
+ from .interpolate import * # noqa: F401, F403
3
4
  from .resize import * # noqa: F401, F403
soifunc/deband.py CHANGED
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from vsdeband import F3kdb
3
+ from vsdeband import f3k_deband
4
4
  from vsmasktools import dre_edgemask
5
5
  from vstools import InvalidVideoFormatError, check_variable, core, vs
6
6
 
@@ -19,7 +19,7 @@ def retinex_deband(
19
19
  16 might be a more sane starting point. Increase as needed.
20
20
 
21
21
  This function does not add grain on its own. Use another function like
22
- `vsdeband.sized_grain` to do that.
22
+ `vsdeband.AddNoise` to do that.
23
23
  """
24
24
  assert check_variable(clip, retinex_deband)
25
25
 
@@ -39,5 +39,5 @@ def retinex_deband(
39
39
  if showmask:
40
40
  return mask
41
41
 
42
- deband = F3kdb().deband(clip, thr=(threshold << 2))
42
+ deband = f3k_deband(clip, thr=(threshold << 2))
43
43
  return core.std.MaskedMerge(deband, clip, mask)
soifunc/denoise.py CHANGED
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  from typing import Callable, Optional
4
4
 
5
5
  import vsdenoise
6
- from vsdenoise import DFTTest, FilterType, Profile, mc_degrain
6
+ from vsdenoise import DFTTest, bm3d, mc_degrain
7
7
  from vstools import core, vs
8
8
 
9
9
  __all__ = ["MCDenoise", "magic_denoise", "hqbm3d", "mc_dfttest"]
@@ -13,7 +13,7 @@ def hqbm3d(
13
13
  clip: vs.VideoNode,
14
14
  luma_str: float = 0.45,
15
15
  chroma_str: float = 0.4,
16
- profile: Profile = Profile.FAST,
16
+ profile: bm3d.Profile = bm3d.Profile.FAST,
17
17
  ) -> vs.VideoNode:
18
18
  """
19
19
  High-quality presets for motion compensated denoising.
@@ -24,24 +24,22 @@ def hqbm3d(
24
24
  blksize = select_block_size(clip)
25
25
  mv = mc_degrain(
26
26
  clip,
27
- preset=vsdenoise.MVToolsPresets.HQ_SAD,
27
+ preset=vsdenoise.MVToolsPreset.HQ_SAD,
28
28
  tr=2,
29
29
  thsad=100,
30
30
  refine=3 if blksize > 16 else 2,
31
31
  blksize=blksize,
32
32
  prefilter=vsdenoise.Prefilter.DFTTEST(
33
33
  clip,
34
- slocation=[(0.0, 1.0), (0.2, 4.0), (0.35, 12.0), (1.0, 48.0)],
34
+ sloc=[(0.0, 1.0), (0.2, 4.0), (0.35, 12.0), (1.0, 48.0)],
35
35
  ssystem=1,
36
36
  full_range=3.5,
37
37
  planes=0,
38
38
  ),
39
39
  planes=None,
40
40
  )
41
- bm3d = vsdenoise.BM3D.denoise(
42
- clip, sigma=luma_str, tr=1, ref=mv, profile=profile, planes=0
43
- )
44
- return vsdenoise.nl_means(bm3d, strength=chroma_str, tr=1, ref=mv, planes=[1, 2])
41
+ out = bm3d(clip, sigma=luma_str, tr=1, ref=mv, profile=profile, planes=0)
42
+ return vsdenoise.nl_means(out, h=chroma_str, tr=1, ref=mv, planes=[1, 2])
45
43
 
46
44
 
47
45
  def mc_dfttest(
@@ -62,7 +60,7 @@ def mc_dfttest(
62
60
  return mc_degrain(
63
61
  clip,
64
62
  prefilter=vsdenoise.Prefilter.DFTTEST,
65
- preset=vsdenoise.MVToolsPresets.HQ_SAD,
63
+ preset=vsdenoise.MVToolsPreset.HQ_SAD,
66
64
  thsad=thSAD,
67
65
  tr=2,
68
66
  refine=3 if blksize > 16 else 2,
@@ -201,12 +199,12 @@ def magic_denoise(clip: vs.VideoNode) -> vs.VideoNode:
201
199
  thscd1=300,
202
200
  )
203
201
 
204
- return DFTTest.denoise(
202
+ return DFTTest().denoise(
205
203
  clip,
206
204
  sloc=[(0.0, 0.8), (0.06, 1.1), (0.12, 1.0), (1.0, 1.0)],
207
205
  pmax=1000000,
208
206
  pmin=1.25,
209
- ftype=FilterType.MULT_RANGE,
207
+ ftype=DFTTest.FilterType.MULT_RANGE,
210
208
  tbsize=3,
211
209
  ssystem=1,
212
210
  )
soifunc/interpolate.py ADDED
@@ -0,0 +1,149 @@
1
+ from __future__ import annotations
2
+
3
+ import platform
4
+ from typing import TYPE_CHECKING
5
+
6
+ import vstools
7
+ from vstools import vs
8
+
9
+ if TYPE_CHECKING:
10
+ from vsmlrt import backendT
11
+
12
+ __all__ = ["rate_doubler", "decimation_fixer"]
13
+
14
+
15
+ def rate_doubler(
16
+ clip: vs.VideoNode, multi: int = 2, backend: backendT | None = None
17
+ ) -> vs.VideoNode:
18
+ """
19
+ A utility to scale the framerate of a video via frame interpolation.
20
+
21
+ Probably shouldn't just go spraying this everywhere,
22
+ it's more for fun and science than anything.
23
+ """
24
+ import vsmlrt
25
+
26
+ width = clip.width
27
+ height = clip.height
28
+ matrix = vstools.Matrix.from_video(clip)
29
+ transfer = vstools.Transfer.from_video(clip)
30
+ primaries = vstools.Primaries.from_video(clip)
31
+ clip = clip.misc.SCDetect()
32
+ clip = clip.resize.Bicubic(
33
+ format=vs.RGBS,
34
+ width=next_multiple_of(64, width),
35
+ height=next_multiple_of(64, height),
36
+ )
37
+ clip = vsmlrt.RIFE(
38
+ clip,
39
+ multi=multi,
40
+ model=vsmlrt.RIFEModel.v4_25_heavy,
41
+ # Why these defaults? Because running ML stuff on AMD on Windows sucks hard.
42
+ # Trial and error led me to finally find that ORT_DML works.
43
+ backend=(
44
+ backend
45
+ if backend
46
+ else (
47
+ vsmlrt.Backend.ORT_DML()
48
+ if platform.system() == "Windows"
49
+ else vsmlrt.Backend.TRT()
50
+ )
51
+ ),
52
+ )
53
+ # TODO: Handle other chroma samplings
54
+ clip = clip.resize.Bicubic(
55
+ format=vs.YUV420P16,
56
+ width=width,
57
+ height=height,
58
+ matrix=matrix,
59
+ transfer=transfer,
60
+ primaries=primaries,
61
+ )
62
+ return clip
63
+
64
+
65
+ def decimation_fixer(
66
+ clip: vs.VideoNode, cycle: int, offset: int = 0, backend: backendT | None = None
67
+ ) -> vs.VideoNode:
68
+ """
69
+ Attempts to interpolate frames that were removed by bad decimation.
70
+ Only works with static decimation cycles.
71
+ `cycle` should be the output cycle, i.e. what did the idiot who decimated this
72
+ pass into the decimation filter to achieve this monstrosity?
73
+
74
+ Yeah, I know, "ThiS is bAd AND yOu shoUldn'T Do IT".
75
+ Maybe people shouldn't decimate clips that don't need decimation.
76
+ Sometimes you can't "just get a better source".
77
+ """
78
+ import vsmlrt
79
+
80
+ if offset >= cycle - 1:
81
+ raise Exception("offset must be less than cycle - 1")
82
+ if cycle <= 0:
83
+ raise Exception("cycle must be greater than zero")
84
+
85
+ width = clip.width
86
+ height = clip.height
87
+ fps = clip.fps
88
+ input_cycle = cycle - 1
89
+ matrix = vstools.Matrix.from_video(clip)
90
+ transfer = vstools.Transfer.from_video(clip)
91
+ primaries = vstools.Primaries.from_video(clip)
92
+ clip = clip.misc.SCDetect()
93
+ clip = clip.resize.Bicubic(
94
+ format=vs.RGBS,
95
+ width=next_multiple_of(64, width),
96
+ height=next_multiple_of(64, height),
97
+ )
98
+ doubled = vsmlrt.RIFE(
99
+ clip,
100
+ model=vsmlrt.RIFEModel.v4_25_heavy,
101
+ backend=(
102
+ backend
103
+ if backend
104
+ else (
105
+ vsmlrt.Backend.ORT_DML()
106
+ if platform.system() == "Windows"
107
+ else vsmlrt.Backend.TRT()
108
+ )
109
+ ),
110
+ )
111
+
112
+ out_clip = None
113
+ # This is the frame after our insertion point
114
+ src_frame = offset
115
+ last_src_frame = 0
116
+ # This is the frame we want to grab from the doubled clip
117
+ doub_frame = offset * 2 - 1
118
+ while src_frame < clip.num_frames:
119
+ if src_frame > 0:
120
+ interp = doubled[doub_frame]
121
+ if out_clip is None:
122
+ out_clip = clip[last_src_frame:src_frame] + interp
123
+ else:
124
+ out_clip = out_clip + clip[last_src_frame:src_frame] + interp
125
+ last_src_frame = src_frame
126
+ src_frame += input_cycle
127
+ doub_frame += input_cycle * 2
128
+ out_clip += clip[last_src_frame:]
129
+ out_clip = out_clip.std.AssumeFPS(
130
+ fpsnum=fps.numerator * cycle // input_cycle, fpsden=fps.denominator
131
+ )
132
+
133
+ # TODO: Handle other chroma samplings
134
+ out_clip = out_clip.resize.Bicubic(
135
+ format=vs.YUV420P16,
136
+ width=width,
137
+ height=height,
138
+ matrix=matrix,
139
+ transfer=transfer,
140
+ primaries=primaries,
141
+ )
142
+ return out_clip
143
+
144
+
145
+ def next_multiple_of(multiple: int, param: int) -> int:
146
+ rem = param % multiple
147
+ if rem == 0:
148
+ return param
149
+ return param + (multiple - rem)
soifunc/resize.py CHANGED
@@ -4,11 +4,11 @@ from dataclasses import dataclass
4
4
  from inspect import getfullargspec
5
5
  from typing import Any
6
6
 
7
- from vsaa.antialiasers.nnedi3 import Nnedi3SS
7
+ from vsaa.deinterlacers import NNEDI3
8
8
  from vskernels import (
9
9
  Hermite,
10
10
  Scaler,
11
- ScalerT,
11
+ ScalerLike,
12
12
  Spline36,
13
13
  )
14
14
  from vsscale import SSIM, ArtCNN, GenericScaler
@@ -58,11 +58,11 @@ def good_resize(
58
58
  if gpu:
59
59
  luma_scaler = ArtCNN()
60
60
  else:
61
- luma_scaler = Nnedi3SS(scaler=Hermite(sigmoid=True))
61
+ luma_scaler = NNEDI3(scaler=Hermite(sigmoid=True))
62
62
  else:
63
63
  luma_scaler = Hermite(sigmoid=True)
64
64
  elif is_upscale:
65
- luma_scaler = Nnedi3SS(scaler=SSIM())
65
+ luma_scaler = NNEDI3(scaler=SSIM())
66
66
  else:
67
67
  luma_scaler = SSIM()
68
68
 
@@ -73,8 +73,8 @@ def good_resize(
73
73
 
74
74
  @dataclass
75
75
  class HybridScaler(GenericScaler):
76
- luma_scaler: ScalerT
77
- chroma_scaler: ScalerT
76
+ luma_scaler: ScalerLike
77
+ chroma_scaler: ScalerLike
78
78
 
79
79
  def __post_init__(self) -> None:
80
80
  super().__post_init__()
@@ -82,7 +82,7 @@ class HybridScaler(GenericScaler):
82
82
  self._luma = Scaler.ensure_obj(self.luma_scaler)
83
83
  self._chroma = Scaler.ensure_obj(self.chroma_scaler)
84
84
 
85
- @inject_self.cached.property
85
+ @Scaler.cached_property
86
86
  def kernel_radius(self) -> int:
87
87
  return self._luma.kernel_radius
88
88
 
@@ -106,7 +106,7 @@ class HybridScaler(GenericScaler):
106
106
  return join(luma, chroma)
107
107
 
108
108
 
109
- def _get_scaler(scaler: ScalerT, **kwargs: Any) -> Scaler:
109
+ def _get_scaler(scaler: ScalerLike, **kwargs: Any) -> Scaler:
110
110
  scaler_cls = Scaler.from_param(scaler, _get_scaler)
111
111
 
112
112
  args = getfullargspec(scaler_cls).args
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: soifunc
3
- Version: 0.10.1
3
+ Version: 0.11.1
4
4
  Summary: Soichiro's VapourSynth Functions Collection
5
5
  License: MIT
6
6
  Author: Josh Holmer
@@ -11,7 +11,7 @@ Classifier: Programming Language :: Python :: 3
11
11
  Classifier: Programming Language :: Python :: 3.12
12
12
  Classifier: Programming Language :: Python :: 3.13
13
13
  Requires-Dist: vapoursynth (>=68)
14
- Requires-Dist: vsjetpack (>=0.4.0,<0.5.0)
14
+ Requires-Dist: vsjetpack (>=0.5.1,<0.6.0)
15
15
  Description-Content-Type: text/markdown
16
16
 
17
17
  ## soifunc
@@ -0,0 +1,10 @@
1
+ soifunc/__init__.py,sha256=H6BWoCLRW2ZD47wQtL72SIZvTpD6REH7cUqIYWvCn0k,174
2
+ soifunc/deband.py,sha256=nbtRwktdN8Y-OuiSsj1mVg9vzJhJlu7r6dqs_TLa6rg,1174
3
+ soifunc/denoise.py,sha256=6MY4m3x64gEIgnbVT48htFthG51sLsERN1YGbNYTdGY,6798
4
+ soifunc/interpolate.py,sha256=MNpYyO037H00vqA5d-WijeBd475oMssEvFLGXgeXPxw,4400
5
+ soifunc/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ soifunc/resize.py,sha256=PCq-nGt8ZHG4dlx3H1R_dRAebHWEc9Eu_coO3VRGlCY,3028
7
+ soifunc-0.11.1.dist-info/LICENSE,sha256=vgEDSMEV1J2nMiCgXE5_sjNtw2VT7_lP7rkAnrFKOWI,1068
8
+ soifunc-0.11.1.dist-info/METADATA,sha256=eGGA-OZ6xqMU8J8Yy806Z5vhOktA_-fxpjpMYt8957I,3364
9
+ soifunc-0.11.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
10
+ soifunc-0.11.1.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- soifunc/__init__.py,sha256=o8id_imdLYtSpVNfB-G4Pru9GtEPqdkcpyyW3yQt-6U,127
2
- soifunc/deband.py,sha256=GB9ksv-G1EOkro7mEN44p1vxLCnY2x4d4SqKhHxQ6Z8,1176
3
- soifunc/denoise.py,sha256=OaNZVEtuaVTy_onD0zMareexUvHuda0pIgcIJollFFc,6841
4
- soifunc/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- soifunc/resize.py,sha256=6t42dTVpAkVLp9p4v4O6glSrcMNfUPLwlKNSWeqWZ5E,3033
6
- soifunc-0.10.1.dist-info/LICENSE,sha256=vgEDSMEV1J2nMiCgXE5_sjNtw2VT7_lP7rkAnrFKOWI,1068
7
- soifunc-0.10.1.dist-info/METADATA,sha256=DhI2DhEjEUnVL7PJ4wUQ_1-UktuEmEsUHw83su21ka0,3364
8
- soifunc-0.10.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
9
- soifunc-0.10.1.dist-info/RECORD,,