soifunc 0.10.0__py3-none-any.whl → 0.11.0__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,146 @@
1
+ from __future__ import annotations
2
+
3
+ import platform
4
+
5
+ import vstools
6
+ from vsmlrt import backendT
7
+ from vstools import vs
8
+
9
+ __all__ = ["rate_doubler", "decimation_fixer"]
10
+
11
+
12
+ def rate_doubler(
13
+ clip: vs.VideoNode, multi: int = 2, backend: backendT | None = None
14
+ ) -> vs.VideoNode:
15
+ """
16
+ A utility to scale the framerate of a video via frame interpolation.
17
+
18
+ Probably shouldn't just go spraying this everywhere,
19
+ it's more for fun and science than anything.
20
+ """
21
+ import vsmlrt
22
+
23
+ width = clip.width
24
+ height = clip.height
25
+ matrix = vstools.Matrix.from_video(clip)
26
+ transfer = vstools.Transfer.from_video(clip)
27
+ primaries = vstools.Primaries.from_video(clip)
28
+ clip = clip.misc.SCDetect()
29
+ clip = clip.resize.Bicubic(
30
+ format=vs.RGBS,
31
+ width=next_multiple_of(64, width),
32
+ height=next_multiple_of(64, height),
33
+ )
34
+ clip = vsmlrt.RIFE(
35
+ clip,
36
+ multi=multi,
37
+ model=vsmlrt.RIFEModel.v4_25_heavy,
38
+ # Why these defaults? Because running ML stuff on AMD on Windows sucks hard.
39
+ # Trial and error led me to finally find that ORT_DML works.
40
+ backend=(
41
+ backend
42
+ if backend
43
+ else (
44
+ vsmlrt.Backend.ORT_DML()
45
+ if platform.system() == "Windows"
46
+ else vsmlrt.Backend.TRT_RTX()
47
+ )
48
+ ),
49
+ )
50
+ # TODO: Handle other chroma samplings
51
+ clip = clip.resize.Bicubic(
52
+ format=vs.YUV420P16,
53
+ width=width,
54
+ height=height,
55
+ matrix=matrix,
56
+ transfer=transfer,
57
+ primaries=primaries,
58
+ )
59
+ return clip
60
+
61
+
62
+ def decimation_fixer(
63
+ clip: vs.VideoNode, cycle: int, offset: int = 0, backend: backendT | None = None
64
+ ) -> vs.VideoNode:
65
+ """
66
+ Attempts to interpolate frames that were removed by bad decimation.
67
+ Only works with static decimation cycles.
68
+ `cycle` should be the output cycle, i.e. what did the idiot who decimated this
69
+ pass into the decimation filter to achieve this monstrosity?
70
+
71
+ Yeah, I know, "ThiS is bAd AND yOu shoUldn'T Do IT".
72
+ Maybe people shouldn't decimate clips that don't need decimation.
73
+ Sometimes you can't "just get a better source".
74
+ """
75
+ import vsmlrt
76
+
77
+ if offset >= cycle - 1:
78
+ raise Exception("offset must be less than cycle - 1")
79
+ if cycle <= 0:
80
+ raise Exception("cycle must be greater than zero")
81
+
82
+ width = clip.width
83
+ height = clip.height
84
+ fps = clip.fps
85
+ input_cycle = cycle - 1
86
+ matrix = vstools.Matrix.from_video(clip)
87
+ transfer = vstools.Transfer.from_video(clip)
88
+ primaries = vstools.Primaries.from_video(clip)
89
+ clip = clip.misc.SCDetect()
90
+ clip = clip.resize.Bicubic(
91
+ format=vs.RGBS,
92
+ width=next_multiple_of(64, width),
93
+ height=next_multiple_of(64, height),
94
+ )
95
+ doubled = vsmlrt.RIFE(
96
+ clip,
97
+ model=vsmlrt.RIFEModel.v4_25_heavy,
98
+ backend=(
99
+ backend
100
+ if backend
101
+ else (
102
+ vsmlrt.Backend.ORT_DML()
103
+ if platform.system() == "Windows"
104
+ else vsmlrt.Backend.TRT_RTX()
105
+ )
106
+ ),
107
+ )
108
+
109
+ out_clip = None
110
+ # This is the frame after our insertion point
111
+ src_frame = offset
112
+ last_src_frame = 0
113
+ # This is the frame we want to grab from the doubled clip
114
+ doub_frame = offset * 2 - 1
115
+ while src_frame < clip.num_frames:
116
+ if src_frame > 0:
117
+ interp = doubled[doub_frame]
118
+ if out_clip is None:
119
+ out_clip = clip[last_src_frame:src_frame] + interp
120
+ else:
121
+ out_clip = out_clip + clip[last_src_frame:src_frame] + interp
122
+ last_src_frame = src_frame
123
+ src_frame += input_cycle
124
+ doub_frame += input_cycle * 2
125
+ out_clip += clip[last_src_frame:]
126
+ out_clip = out_clip.std.AssumeFPS(
127
+ fpsnum=fps.numerator * cycle // input_cycle, fpsden=fps.denominator
128
+ )
129
+
130
+ # TODO: Handle other chroma samplings
131
+ out_clip = out_clip.resize.Bicubic(
132
+ format=vs.YUV420P16,
133
+ width=width,
134
+ height=height,
135
+ matrix=matrix,
136
+ transfer=transfer,
137
+ primaries=primaries,
138
+ )
139
+ return out_clip
140
+
141
+
142
+ def next_multiple_of(multiple: int, param: int) -> int:
143
+ rem = param % multiple
144
+ if rem == 0:
145
+ return param
146
+ return param + (multiple - rem)
soifunc/resize.py CHANGED
@@ -4,18 +4,15 @@ 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
- Catrom,
10
- EwaLanczos,
11
9
  Hermite,
12
- KeepArScaler,
13
10
  Scaler,
14
- ScalerT,
11
+ ScalerLike,
15
12
  Spline36,
16
13
  )
17
- from vsscale import SSIM, ArtCNN, GenericScaler, Waifu2x
18
- from vstools import check_variable_format, is_gpu_available, join, vs
14
+ from vsscale import SSIM, ArtCNN, GenericScaler
15
+ from vstools import check_variable_format, inject_self, is_gpu_available, join, vs
19
16
 
20
17
  __all__ = [
21
18
  "good_resize",
@@ -61,11 +58,11 @@ def good_resize(
61
58
  if gpu:
62
59
  luma_scaler = ArtCNN()
63
60
  else:
64
- luma_scaler = Nnedi3SS(scaler=Hermite(sigmoid=True))
61
+ luma_scaler = NNEDI3(scaler=Hermite(sigmoid=True))
65
62
  else:
66
63
  luma_scaler = Hermite(sigmoid=True)
67
64
  elif is_upscale:
68
- luma_scaler = EwaLanczos()
65
+ luma_scaler = NNEDI3(scaler=SSIM())
69
66
  else:
70
67
  luma_scaler = SSIM()
71
68
 
@@ -76,8 +73,8 @@ def good_resize(
76
73
 
77
74
  @dataclass
78
75
  class HybridScaler(GenericScaler):
79
- luma_scaler: ScalerT
80
- chroma_scaler: ScalerT
76
+ luma_scaler: ScalerLike
77
+ chroma_scaler: ScalerLike
81
78
 
82
79
  def __post_init__(self) -> None:
83
80
  super().__post_init__()
@@ -85,7 +82,7 @@ class HybridScaler(GenericScaler):
85
82
  self._luma = Scaler.ensure_obj(self.luma_scaler)
86
83
  self._chroma = Scaler.ensure_obj(self.chroma_scaler)
87
84
 
88
- @property
85
+ @Scaler.cached_property
89
86
  def kernel_radius(self) -> int:
90
87
  return self._luma.kernel_radius
91
88
 
@@ -109,7 +106,7 @@ class HybridScaler(GenericScaler):
109
106
  return join(luma, chroma)
110
107
 
111
108
 
112
- def _get_scaler(scaler: ScalerT, **kwargs: Any) -> Scaler:
109
+ def _get_scaler(scaler: ScalerLike, **kwargs: Any) -> Scaler:
113
110
  scaler_cls = Scaler.from_param(scaler, _get_scaler)
114
111
 
115
112
  args = getfullargspec(scaler_cls).args
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: soifunc
3
- Version: 0.10.0
3
+ Version: 0.11.0
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.3.4,<0.4.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=PZIVcozHOMUOo7vZj1Q9vwByJ5d9lJvnCp_GRxgPZK0,4352
5
+ soifunc/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ soifunc/resize.py,sha256=PCq-nGt8ZHG4dlx3H1R_dRAebHWEc9Eu_coO3VRGlCY,3028
7
+ soifunc-0.11.0.dist-info/LICENSE,sha256=vgEDSMEV1J2nMiCgXE5_sjNtw2VT7_lP7rkAnrFKOWI,1068
8
+ soifunc-0.11.0.dist-info/METADATA,sha256=lnqZaM7DdbWgC4dbBfZGCcHt5f5UWYfLl0xv3LmSyak,3364
9
+ soifunc-0.11.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
10
+ soifunc-0.11.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.1.2
2
+ Generator: poetry-core 2.1.3
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -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=E7tiiqvfvt_PMsJFSlZrr9heuYVuySQiZXEbQ7Kjacs,3045
6
- soifunc-0.10.0.dist-info/LICENSE,sha256=vgEDSMEV1J2nMiCgXE5_sjNtw2VT7_lP7rkAnrFKOWI,1068
7
- soifunc-0.10.0.dist-info/METADATA,sha256=_C-g7OvcdJNIBTbrc5NDFqznt2-Wnjp_7IKYUNZu8x0,3364
8
- soifunc-0.10.0.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
9
- soifunc-0.10.0.dist-info/RECORD,,