Skip to content

scale

BaseWaifu2x dataclass

BaseWaifu2x(
    cuda: bool | Literal["trt"] | None = None,
    num_streams: int | None = None,
    fp16: bool = True,
    device_id: int = 0,
    matrix: MatrixT | None = None,
    tiles: int | tuple[int, int] | None = None,
    tilesize: int | tuple[int, int] | None = None,
    overlap: int | tuple[int, int] | None = None,
    backend_kwargs: KwargsT | None = None,
    dynamic_shape: bool | None = None,
    max_shapes: tuple[int, int] | None = (1936, 1088),
    max_instances: int = 2,
    *,
    kernel: KernelT | None = None,
    scaler: ScalerT | None = None,
    shifter: KernelT | None = None
)

Bases: _BaseWaifu2x, GenericScaler

Use Waifu2x neural network to scale clips.

backend_kwargs class-attribute instance-attribute

backend_kwargs: KwargsT | None = None

Kwargs passed to create the backend instance.

cuda class-attribute instance-attribute

cuda: bool | Literal['trt'] | None = None

Whether to run this on cpu, gpu, or use trt technology. None will pick the fastest automatically.

device_id class-attribute instance-attribute

device_id: int = 0

Id of the cuda device to use.

dynamic_shape class-attribute instance-attribute

dynamic_shape: bool | None = None

Use a single model for 0-max_shapes resolutions. None to automatically detect it. Will be True when previewing and TRT is available.

fp16 class-attribute instance-attribute

fp16: bool = True

Whether to use float16 precision if available.

func instance-attribute

func = func

kernel class-attribute instance-attribute

kernel: KernelT | None = field(default=None, kw_only=True)

Base kernel to be used for certain scaling/shifting/resampling operations. Must be specified and defaults to catrom

kwargs instance-attribute

kwargs = kwargs

matrix class-attribute instance-attribute

matrix: MatrixT | None = None

Input clip's matrix. Set only if necessary.

max_instances class-attribute instance-attribute

max_instances: int = 2

Maximum instances to spawn when scaling a variable resolution clip.

max_shapes class-attribute instance-attribute

max_shapes: tuple[int, int] | None = (1936, 1088)

Max shape for a dynamic model when using TRT and variable resolution clip. This can be overridden if the frame size is bigger.

num_streams class-attribute instance-attribute

num_streams: int | None = None

Number of gpu streams for the model.

overlap class-attribute instance-attribute

overlap: int | tuple[int, int] | None = None

Overlap for reducing blocking artifacts between tile borders.

scale_function instance-attribute

scale_function: GenericVSFunction

Scale function called internally when scaling

scaler class-attribute instance-attribute

scaler: ScalerT | None = field(default=None, kw_only=True)

Scaler used for scaling operations. Defaults to kernel.

shifter class-attribute instance-attribute

shifter: KernelT | None = field(default=None, kw_only=True)

Kernel used for shifting operations. Defaults to kernel.

tiles class-attribute instance-attribute

tiles: int | tuple[int, int] | None = None

Process in separate tiles instead of the whole frame. Use if [V]RAM limited.

tilesize class-attribute instance-attribute

tilesize: int | tuple[int, int] | None = None

Manually specify the size of a single tile.

ensure_obj classmethod

ensure_obj(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> BaseScalerT
Source code
186
187
188
189
190
191
192
193
@classmethod
def ensure_obj(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> BaseScalerT:
    return _base_ensure_obj(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

ensure_scaler

ensure_scaler(scaler: ScalerT) -> Scaler
Source code
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
def ensure_scaler(self, scaler: ScalerT) -> Scaler:
    from dataclasses import is_dataclass, replace

    scaler_obj = Scaler.ensure_obj(scaler, self.__class__)

    if is_dataclass(scaler_obj):
        from inspect import Signature  #type: ignore[unreachable]

        kwargs = dict[str, ScalerT]()

        init_keys = Signature.from_callable(scaler_obj.__init__).parameters.keys()

        if 'kernel' in init_keys:
            kwargs.update(kernel=self.kernel or scaler_obj.kernel)

        if 'scaler' in init_keys:
            kwargs.update(scaler=self.scaler or scaler_obj.scaler)

        if 'shifter' in init_keys:
            kwargs.update(shifter=self.shifter or scaler_obj.shifter)

        if kwargs:
            scaler_obj = replace(scaler_obj, **kwargs)

    return scaler_obj

from_param classmethod

from_param(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> type[BaseScalerT]
Source code
177
178
179
180
181
182
183
184
@classmethod
def from_param(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> type[BaseScalerT]:
    return _base_from_param(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

get_clean_kwargs

get_clean_kwargs(*funcs: Callable[..., Any] | None) -> KwargsT
Source code
199
200
def get_clean_kwargs(self, *funcs: Callable[..., Any] | None) -> KwargsT:
    return _clean_self_kwargs(funcs, self)

get_implemented_funcs

get_implemented_funcs() -> tuple[Callable[..., Any], ...]
Source code
270
271
def get_implemented_funcs(self) -> tuple[Callable[..., Any], ...]:
    return (self.scale, self.multi)

get_scale_args

get_scale_args(
    clip: VideoNode,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None,
    height: int | None = None,
    *funcs: Callable[..., Any],
    **kwargs: Any
) -> KwargsT
Source code
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
@inject_kwargs_params
def get_scale_args(
    self, clip: vs.VideoNode, shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None, height: int | None = None,
    *funcs: Callable[..., Any], **kwargs: Any
) -> KwargsT:
    return (
        dict(
            src_top=shift[0],
            src_left=shift[1]
        )
        | self.get_clean_kwargs(*funcs)
        | dict(width=width, height=height)
        | kwargs
    )

kernel_radius

kernel_radius() -> int
Source code
195
196
197
@inject_self.cached.property
def kernel_radius(self) -> int:
    return _default_kernel_radius(__class__, self)  # type: ignore

multi

multi(
    clip: VideoNode,
    multi: float = 2,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
239
240
241
242
243
244
245
246
247
248
249
250
251
252
@inject_self.cached
def multi(
    self, clip: vs.VideoNode, multi: float = 2, shift: tuple[TopShift, LeftShift] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    assert check_variable_resolution(clip, self.multi)

    dst_width, dst_height = ceil(clip.width * multi), ceil(clip.height * multi)

    if max(dst_width, dst_height) <= 0.0:
        raise CustomValueError(
            'Multiplying the resolution by "multi" must result in a positive resolution!', self.multi, multi
        )

    return self.scale(clip, dst_width, dst_height, shift, **kwargs)

pretty_string

pretty_string() -> str
Source code
202
203
204
205
206
207
208
209
210
211
212
213
214
@inject_self.cached.property
def pretty_string(self) -> str:
    attrs = {}

    if hasattr(self, 'b'):
        attrs.update(b=self.b, c=self.c)
    elif hasattr(self, 'taps'):
        attrs['taps'] = self.taps

    if hasattr(self, 'kwargs'):
        attrs.update(self.kwargs)

    return f"{self.__class__.__name__}{' (' + ', '.join(f'{k}={v}' for k, v in attrs.items()) + ')' if attrs else ''}"

scale

scale(
    clip: VideoNode,
    width: int | None = None,
    height: int | None = None,
    shift: tuple[float, float] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
@inject_self.init_kwargs.clean
def scale(  # type:ignore
    self, clip: vs.VideoNode, width: int | None = None, height: int | None = None,
    shift: tuple[float, float] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    try:
        from vsmlrt import Backend
    except ModuleNotFoundError as e:
        raise DependencyNotFoundError(self.__class__, e)

    width, height = self._wh_norm(clip, width, height)

    wclip = clip

    assert check_variable_format(clip, self.scale)

    matrix = self.matrix
    is_gray = clip.format.color_family is vs.GRAY
    planes = 0 if is_gray else None

    _static_args = kwargs.pop('_static_args', self._static_args)
    force = _static_args.pop('force', False)
    do_scale = _static_args.get('scale') > 1

    bkwargs = self._bkwargs.copy()

    dynamic_shapes = self.dynamic_shape or (0 in (clip.width, clip.height)) or not bkwargs.get('static_shape', True)

    kwargs.update(tiles=self.tiles, tilesize=self.tilesize, overlap=self.overlap)

    if dynamic_shapes and self._backend is Backend.TRT:
        bkwargs.update(static_shape=False, opt_shapes=(64, 64), max_shapes=self.max_shapes)

    if (is_upscale := width > clip.width or height > clip.width or force):
        model = self._model

        if clip.format.color_family is vs.YUV:
            if not matrix:
                matrix = Matrix.from_param_or_video(matrix or self.matrix, clip, False, self.__class__)

            wclip = self._kernel.resample(wclip, vs.RGBH if self.fp16 else vs.RGBS, Matrix.RGB, matrix)
        else:
            wclip = depth(wclip, 16 if self.fp16 else 32, vs.FLOAT)

            if is_gray and model != 0:
                wclip = wclip.std.ShufflePlanes(0, vs.RGB)

        assert wclip.format

        if wclip.format.color_family is vs.RGB:
            if model == 0:
                model = 1

        wclip = Waifu2xResizeHelper(
            wclip, width, height, planes, is_gray, self._scaler,
            do_scale and self._model == Waifu2x.Cunet._model,
            KwargsT(
                **_static_args, model=model,
                preprocess=False, **kwargs
            ), self.max_instances, self._backend, bkwargs  # type: ignore[arg-type]
        ).eval_clip()

    return self._finish_scale(wclip, clip, width, height, shift, matrix, is_upscale)

DLISR dataclass

DLISR(
    scaler: ScalerT = lambda: DPID(0.5, Mitchell)(),
    matrix: MatrixT | None = None,
    device_id: int | None = None,
    *,
    kernel: KernelT | None = None,
    shifter: KernelT | None = None
)

Bases: GenericScaler

Use Nvidia NGX Technology DLISR DNN to scale up nodes. https://developer.nvidia.com/rtx/ngx

device_id class-attribute instance-attribute

device_id: int | None = None

Which cuda device to run this filter on.

func instance-attribute

func = func

kernel class-attribute instance-attribute

kernel: KernelT | None = field(default=None, kw_only=True)

Base kernel to be used for certain scaling/shifting/resampling operations. Must be specified and defaults to catrom

kwargs instance-attribute

kwargs = kwargs

matrix class-attribute instance-attribute

matrix: MatrixT | None = None

Input clip's matrix. Set only if necessary.

scale_function instance-attribute

scale_function: GenericVSFunction

Scale function called internally when scaling

scaler class-attribute instance-attribute

scaler: ScalerT = field(default_factory=lambda: DPID(0.5, Mitchell))

Scaler to use to downscale clip to desired resolution, if necessary.

shifter class-attribute instance-attribute

shifter: KernelT | None = field(default=None, kw_only=True)

Kernel used for shifting operations. Defaults to kernel.

ensure_obj classmethod

ensure_obj(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> BaseScalerT
Source code
186
187
188
189
190
191
192
193
@classmethod
def ensure_obj(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> BaseScalerT:
    return _base_ensure_obj(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

ensure_scaler

ensure_scaler(scaler: ScalerT) -> Scaler
Source code
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
def ensure_scaler(self, scaler: ScalerT) -> Scaler:
    from dataclasses import is_dataclass, replace

    scaler_obj = Scaler.ensure_obj(scaler, self.__class__)

    if is_dataclass(scaler_obj):
        from inspect import Signature  #type: ignore[unreachable]

        kwargs = dict[str, ScalerT]()

        init_keys = Signature.from_callable(scaler_obj.__init__).parameters.keys()

        if 'kernel' in init_keys:
            kwargs.update(kernel=self.kernel or scaler_obj.kernel)

        if 'scaler' in init_keys:
            kwargs.update(scaler=self.scaler or scaler_obj.scaler)

        if 'shifter' in init_keys:
            kwargs.update(shifter=self.shifter or scaler_obj.shifter)

        if kwargs:
            scaler_obj = replace(scaler_obj, **kwargs)

    return scaler_obj

from_param classmethod

from_param(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> type[BaseScalerT]
Source code
177
178
179
180
181
182
183
184
@classmethod
def from_param(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> type[BaseScalerT]:
    return _base_from_param(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

get_clean_kwargs

get_clean_kwargs(*funcs: Callable[..., Any] | None) -> KwargsT
Source code
199
200
def get_clean_kwargs(self, *funcs: Callable[..., Any] | None) -> KwargsT:
    return _clean_self_kwargs(funcs, self)

get_implemented_funcs

get_implemented_funcs() -> tuple[Callable[..., Any], ...]
Source code
270
271
def get_implemented_funcs(self) -> tuple[Callable[..., Any], ...]:
    return (self.scale, self.multi)

get_scale_args

get_scale_args(
    clip: VideoNode,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None,
    height: int | None = None,
    *funcs: Callable[..., Any],
    **kwargs: Any
) -> KwargsT
Source code
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
@inject_kwargs_params
def get_scale_args(
    self, clip: vs.VideoNode, shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None, height: int | None = None,
    *funcs: Callable[..., Any], **kwargs: Any
) -> KwargsT:
    return (
        dict(
            src_top=shift[0],
            src_left=shift[1]
        )
        | self.get_clean_kwargs(*funcs)
        | dict(width=width, height=height)
        | kwargs
    )

kernel_radius

kernel_radius() -> int
Source code
195
196
197
@inject_self.cached.property
def kernel_radius(self) -> int:
    return _default_kernel_radius(__class__, self)  # type: ignore

multi

multi(
    clip: VideoNode,
    multi: float = 2,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
239
240
241
242
243
244
245
246
247
248
249
250
251
252
@inject_self.cached
def multi(
    self, clip: vs.VideoNode, multi: float = 2, shift: tuple[TopShift, LeftShift] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    assert check_variable_resolution(clip, self.multi)

    dst_width, dst_height = ceil(clip.width * multi), ceil(clip.height * multi)

    if max(dst_width, dst_height) <= 0.0:
        raise CustomValueError(
            'Multiplying the resolution by "multi" must result in a positive resolution!', self.multi, multi
        )

    return self.scale(clip, dst_width, dst_height, shift, **kwargs)

pretty_string

pretty_string() -> str
Source code
202
203
204
205
206
207
208
209
210
211
212
213
214
@inject_self.cached.property
def pretty_string(self) -> str:
    attrs = {}

    if hasattr(self, 'b'):
        attrs.update(b=self.b, c=self.c)
    elif hasattr(self, 'taps'):
        attrs['taps'] = self.taps

    if hasattr(self, 'kwargs'):
        attrs.update(self.kwargs)

    return f"{self.__class__.__name__}{' (' + ', '.join(f'{k}={v}' for k, v in attrs.items()) + ')' if attrs else ''}"

scale

scale(
    clip: VideoNode,
    width: int | None = None,
    height: int | None = None,
    shift: tuple[float, float] = (0, 0),
    *,
    matrix: MatrixT | None = None,
    **kwargs: Any
) -> VideoNode
Source code
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
@inject_self
def scale(  # type: ignore
    self, clip: vs.VideoNode, width: int | None = None, height: int | None = None,
    shift: tuple[float, float] = (0, 0), *, matrix: MatrixT | None = None, **kwargs: Any
) -> vs.VideoNode:
    width, height = self._wh_norm(clip, width, height)

    output = clip

    assert check_variable(clip, self.__class__)

    if width > clip.width or height > clip.width:
        if not matrix:
            matrix = Matrix.from_param_or_video(matrix or self.matrix, clip, False, self.__class__)

        output = self._kernel.resample(output, vs.RGBS, Matrix.RGB, matrix)
        output = limiter(output, func=self.__class__)

        max_scale = max(ceil(width / clip.width), ceil(height / clip.height))

        output = output.akarin.DLISR(max_scale, self.device_id)

    return self._finish_scale(output, clip, width, height, shift, matrix)

DPID dataclass

DPID(
    sigma: float = 0.1,
    ref: VideoNode | ScalerT = Catrom,
    planes: PlanesT = None,
    *,
    kernel: KernelT | None = None,
    scaler: ScalerT | None = None,
    shifter: KernelT | None = None
)

Bases: GenericScaler

Rapid, Detail-Preserving Image Downscaler for VapourSynth

func instance-attribute

func = func

kernel class-attribute instance-attribute

kernel: KernelT | None = field(default=None, kw_only=True)

Base kernel to be used for certain scaling/shifting/resampling operations. Must be specified and defaults to catrom

kwargs instance-attribute

kwargs = kwargs

planes class-attribute instance-attribute

planes: PlanesT = None

Sets which planes will be processed. Any unprocessed planes will be simply copied from ref.

ref class-attribute instance-attribute

ref: VideoNode | ScalerT = Catrom

VideoNode or Scaler to obtain the downscaled reference for DPID.

scale_function instance-attribute

scale_function: GenericVSFunction

Scale function called internally when scaling

scaler class-attribute instance-attribute

scaler: ScalerT | None = field(default=None, kw_only=True)

Scaler used for scaling operations. Defaults to kernel.

shifter class-attribute instance-attribute

shifter: KernelT | None = field(default=None, kw_only=True)

Kernel used for shifting operations. Defaults to kernel.

sigma class-attribute instance-attribute

sigma: float = 0.1

The power factor of range kernel. It can be used to tune the amplification of the weights of pixels that represent detail—from a box filter over an emphasis of distinct pixels towards a selection of only the most distinct pixels.

ensure_obj classmethod

ensure_obj(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> BaseScalerT
Source code
186
187
188
189
190
191
192
193
@classmethod
def ensure_obj(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> BaseScalerT:
    return _base_ensure_obj(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

ensure_scaler

ensure_scaler(scaler: ScalerT) -> Scaler
Source code
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
def ensure_scaler(self, scaler: ScalerT) -> Scaler:
    from dataclasses import is_dataclass, replace

    scaler_obj = Scaler.ensure_obj(scaler, self.__class__)

    if is_dataclass(scaler_obj):
        from inspect import Signature  #type: ignore[unreachable]

        kwargs = dict[str, ScalerT]()

        init_keys = Signature.from_callable(scaler_obj.__init__).parameters.keys()

        if 'kernel' in init_keys:
            kwargs.update(kernel=self.kernel or scaler_obj.kernel)

        if 'scaler' in init_keys:
            kwargs.update(scaler=self.scaler or scaler_obj.scaler)

        if 'shifter' in init_keys:
            kwargs.update(shifter=self.shifter or scaler_obj.shifter)

        if kwargs:
            scaler_obj = replace(scaler_obj, **kwargs)

    return scaler_obj

from_param classmethod

from_param(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> type[BaseScalerT]
Source code
177
178
179
180
181
182
183
184
@classmethod
def from_param(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> type[BaseScalerT]:
    return _base_from_param(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

get_clean_kwargs

get_clean_kwargs(*funcs: Callable[..., Any] | None) -> KwargsT
Source code
199
200
def get_clean_kwargs(self, *funcs: Callable[..., Any] | None) -> KwargsT:
    return _clean_self_kwargs(funcs, self)

get_implemented_funcs

get_implemented_funcs() -> tuple[Callable[..., Any], ...]
Source code
270
271
def get_implemented_funcs(self) -> tuple[Callable[..., Any], ...]:
    return (self.scale, self.multi)

get_scale_args

get_scale_args(
    clip: VideoNode,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None,
    height: int | None = None,
    *funcs: Callable[..., Any],
    **kwargs: Any
) -> KwargsT
Source code
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
@inject_kwargs_params
def get_scale_args(
    self, clip: vs.VideoNode, shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None, height: int | None = None,
    *funcs: Callable[..., Any], **kwargs: Any
) -> KwargsT:
    return (
        dict(
            src_top=shift[0],
            src_left=shift[1]
        )
        | self.get_clean_kwargs(*funcs)
        | dict(width=width, height=height)
        | kwargs
    )

kernel_radius

kernel_radius() -> int
Source code
73
74
75
@inject_self.property
def kernel_radius(self) -> int:  # type: ignore
    return self._ref_scaler.kernel_radius

multi

multi(
    clip: VideoNode,
    multi: float = 2,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
239
240
241
242
243
244
245
246
247
248
249
250
251
252
@inject_self.cached
def multi(
    self, clip: vs.VideoNode, multi: float = 2, shift: tuple[TopShift, LeftShift] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    assert check_variable_resolution(clip, self.multi)

    dst_width, dst_height = ceil(clip.width * multi), ceil(clip.height * multi)

    if max(dst_width, dst_height) <= 0.0:
        raise CustomValueError(
            'Multiplying the resolution by "multi" must result in a positive resolution!', self.multi, multi
        )

    return self.scale(clip, dst_width, dst_height, shift, **kwargs)

pretty_string

pretty_string() -> str
Source code
202
203
204
205
206
207
208
209
210
211
212
213
214
@inject_self.cached.property
def pretty_string(self) -> str:
    attrs = {}

    if hasattr(self, 'b'):
        attrs.update(b=self.b, c=self.c)
    elif hasattr(self, 'taps'):
        attrs['taps'] = self.taps

    if hasattr(self, 'kwargs'):
        attrs.update(self.kwargs)

    return f"{self.__class__.__name__}{' (' + ', '.join(f'{k}={v}' for k, v in attrs.items()) + ')' if attrs else ''}"

scale

scale(
    clip: VideoNode,
    width: int | None = None,
    height: int | None = None,
    shift: tuple[float, float] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
@inject_self
def scale(  # type: ignore[override]
    self, clip: vs.VideoNode, width: int | None = None, height: int | None = None,
    shift: tuple[float, float] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    width, height = self._wh_norm(clip, width, height)

    ref = clip

    if isinstance(self.ref, vs.VideoNode):
        check_ref_clip(clip, self.ref)
        ref = self.ref

    if (ref.width, ref.height) != (width, height):
        ref = self._ref_scaler.scale(ref, width, height)

    kwargs |= {
        'lambda_': self.sigma, 'planes': self.planes,
        'src_left': shift[1], 'src_top': shift[0]
    } | kwargs | {'read_chromaloc': True}

    return core.dpid.DpidRaw(clip, ref, **kwargs)

SSIM

SSIM(
    scaler: ScalerT = Hermite,
    smooth: int | float | VSFunction | None = None,
    **kwargs: Any
)

Bases: LinearScaler

SSIM downsampler is an image downscaling technique that aims to optimize for the perceptual quality of the downscaled results.

Image downscaling is considered as an optimization problem where the difference between the input and output images is measured using famous Structural SIMilarity (SSIM) index.

The solution is derived in closed-form, which leads to the simple, efficient implementation. The downscaled images retain perceptually important features and details, resulting in an accurate and spatio-temporally consistent representation of the high resolution input.

Parameters:

  • scaler

    (ScalerT, default: Hermite ) –

    Scaler to be used for downscaling, defaults to Hermite.

  • smooth

    (int | float | VSFunction | None, default: None ) –

    Image smoothening method. If you pass an int, it specifies the "radius" of the internally-used boxfilter, i.e. the window has a size of (2smooth+1)x(2smooth+1). If you pass a float, it specifies the "sigma" of gauss_blur, i.e. the standard deviation of gaussian blur. If you pass a function, it acts as a general smoother. Default uses a gaussian blur based on the scaler's kernel radius.

Source code
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
def __init__(
    self, scaler: ScalerT = Hermite, smooth: int | float | VSFunction | None = None, **kwargs: Any
) -> None:
    """
    :param scaler:      Scaler to be used for downscaling, defaults to Hermite.
    :param smooth:      Image smoothening method.
                        If you pass an int, it specifies the "radius" of the internally-used boxfilter,
                        i.e. the window has a size of (2*smooth+1)x(2*smooth+1).
                        If you pass a float, it specifies the "sigma" of gauss_blur,
                        i.e. the standard deviation of gaussian blur.
                        If you pass a function, it acts as a general smoother.
                        Default uses a gaussian blur based on the scaler's kernel radius.
    """
    super().__init__(**kwargs)

    self.scaler = Hermite.from_param(scaler)

    if smooth is None:
        smooth = (self.scaler.kernel_radius + 1.0) / 3

    if callable(smooth):
        self.filter_func = smooth
    elif isinstance(smooth, int):
        self.filter_func = partial(box_blur, radius=smooth)
    elif isinstance(smooth, float):
        self.filter_func = partial(gauss_blur, sigma=smooth)

filter_func instance-attribute

filter_func = smooth

kwargs instance-attribute

kwargs: KwargsT = kwargs

Arguments passed to the internal scale function

scale_function instance-attribute

scale_function: GenericVSFunction

Scale function called internally when scaling

scaler instance-attribute

scaler = from_param(scaler)

ensure_obj classmethod

ensure_obj(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> BaseScalerT
Source code
186
187
188
189
190
191
192
193
@classmethod
def ensure_obj(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> BaseScalerT:
    return _base_ensure_obj(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

from_param classmethod

from_param(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> type[BaseScalerT]
Source code
177
178
179
180
181
182
183
184
@classmethod
def from_param(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> type[BaseScalerT]:
    return _base_from_param(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

get_clean_kwargs

get_clean_kwargs(*funcs: Callable[..., Any] | None) -> KwargsT
Source code
199
200
def get_clean_kwargs(self, *funcs: Callable[..., Any] | None) -> KwargsT:
    return _clean_self_kwargs(funcs, self)

get_implemented_funcs

get_implemented_funcs() -> tuple[Callable[..., Any], ...]
Source code
270
271
def get_implemented_funcs(self) -> tuple[Callable[..., Any], ...]:
    return (self.scale, self.multi)

get_scale_args

get_scale_args(
    clip: VideoNode,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None,
    height: int | None = None,
    *funcs: Callable[..., Any],
    **kwargs: Any
) -> KwargsT
Source code
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
@inject_kwargs_params
def get_scale_args(
    self, clip: vs.VideoNode, shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None, height: int | None = None,
    *funcs: Callable[..., Any], **kwargs: Any
) -> KwargsT:
    return (
        dict(
            src_top=shift[0],
            src_left=shift[1]
        )
        | self.get_clean_kwargs(*funcs)
        | dict(width=width, height=height)
        | kwargs
    )

kernel_radius

kernel_radius() -> int
Source code
143
144
145
@inject_self.property
def kernel_radius(self) -> int:  # type: ignore
    return self.scaler.kernel_radius

multi

multi(
    clip: VideoNode,
    multi: float = 2,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
239
240
241
242
243
244
245
246
247
248
249
250
251
252
@inject_self.cached
def multi(
    self, clip: vs.VideoNode, multi: float = 2, shift: tuple[TopShift, LeftShift] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    assert check_variable_resolution(clip, self.multi)

    dst_width, dst_height = ceil(clip.width * multi), ceil(clip.height * multi)

    if max(dst_width, dst_height) <= 0.0:
        raise CustomValueError(
            'Multiplying the resolution by "multi" must result in a positive resolution!', self.multi, multi
        )

    return self.scale(clip, dst_width, dst_height, shift, **kwargs)

pretty_string

pretty_string() -> str
Source code
202
203
204
205
206
207
208
209
210
211
212
213
214
@inject_self.cached.property
def pretty_string(self) -> str:
    attrs = {}

    if hasattr(self, 'b'):
        attrs.update(b=self.b, c=self.c)
    elif hasattr(self, 'taps'):
        attrs['taps'] = self.taps

    if hasattr(self, 'kwargs'):
        attrs.update(self.kwargs)

    return f"{self.__class__.__name__}{' (' + ', '.join(f'{k}={v}' for k, v in attrs.items()) + ')' if attrs else ''}"

scale

scale(
    clip: VideoNode,
    width: int | None = None,
    height: int | None = None,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    *,
    linear: bool = False,
    sigmoid: bool | tuple[Slope, Center] = False,
    **kwargs: Any
) -> VideoNode
Source code
82
83
84
85
86
87
88
89
@inject_self.cached
@inject_kwargs_params
def scale(  # type: ignore[override]
    self, clip: vs.VideoNode, width: int | None = None, height: int | None = None,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    *, linear: bool = False, sigmoid: bool | tuple[Slope, Center] = False, **kwargs: Any
) -> vs.VideoNode:
    ...

Waifu2x dataclass

Waifu2x(
    cuda: bool | Literal["trt"] | None = None,
    num_streams: int | None = None,
    fp16: bool = True,
    device_id: int = 0,
    matrix: MatrixT | None = None,
    tiles: int | tuple[int, int] | None = None,
    tilesize: int | tuple[int, int] | None = None,
    overlap: int | tuple[int, int] | None = None,
    backend_kwargs: KwargsT | None = None,
    dynamic_shape: bool | None = None,
    max_shapes: tuple[int, int] | None = (1936, 1088),
    max_instances: int = 2,
    *,
    kernel: KernelT | None = None,
    scaler: ScalerT | None = None,
    shifter: KernelT | None = None
)

Bases: BaseWaifu2x

backend_kwargs class-attribute instance-attribute

backend_kwargs: KwargsT | None = None

Kwargs passed to create the backend instance.

cuda class-attribute instance-attribute

cuda: bool | Literal['trt'] | None = None

Whether to run this on cpu, gpu, or use trt technology. None will pick the fastest automatically.

device_id class-attribute instance-attribute

device_id: int = 0

Id of the cuda device to use.

dynamic_shape class-attribute instance-attribute

dynamic_shape: bool | None = None

Use a single model for 0-max_shapes resolutions. None to automatically detect it. Will be True when previewing and TRT is available.

fp16 class-attribute instance-attribute

fp16: bool = True

Whether to use float16 precision if available.

func instance-attribute

func = func

kernel class-attribute instance-attribute

kernel: KernelT | None = field(default=None, kw_only=True)

Base kernel to be used for certain scaling/shifting/resampling operations. Must be specified and defaults to catrom

kwargs instance-attribute

kwargs = kwargs

matrix class-attribute instance-attribute

matrix: MatrixT | None = None

Input clip's matrix. Set only if necessary.

max_instances class-attribute instance-attribute

max_instances: int = 2

Maximum instances to spawn when scaling a variable resolution clip.

max_shapes class-attribute instance-attribute

max_shapes: tuple[int, int] | None = (1936, 1088)

Max shape for a dynamic model when using TRT and variable resolution clip. This can be overridden if the frame size is bigger.

num_streams class-attribute instance-attribute

num_streams: int | None = None

Number of gpu streams for the model.

overlap class-attribute instance-attribute

overlap: int | tuple[int, int] | None = None

Overlap for reducing blocking artifacts between tile borders.

scale_function instance-attribute

scale_function: GenericVSFunction

Scale function called internally when scaling

scaler class-attribute instance-attribute

scaler: ScalerT | None = field(default=None, kw_only=True)

Scaler used for scaling operations. Defaults to kernel.

shifter class-attribute instance-attribute

shifter: KernelT | None = field(default=None, kw_only=True)

Kernel used for shifting operations. Defaults to kernel.

tiles class-attribute instance-attribute

tiles: int | tuple[int, int] | None = None

Process in separate tiles instead of the whole frame. Use if [V]RAM limited.

tilesize class-attribute instance-attribute

tilesize: int | tuple[int, int] | None = None

Manually specify the size of a single tile.

AnimeStyleArt dataclass

AnimeStyleArt(
    cuda: bool | Literal["trt"] | None = None,
    num_streams: int | None = None,
    fp16: bool = True,
    device_id: int = 0,
    matrix: MatrixT | None = None,
    tiles: int | tuple[int, int] | None = None,
    tilesize: int | tuple[int, int] | None = None,
    overlap: int | tuple[int, int] | None = None,
    backend_kwargs: KwargsT | None = None,
    dynamic_shape: bool | None = None,
    max_shapes: tuple[int, int] | None = (1936, 1088),
    max_instances: int = 2,
    *,
    kernel: KernelT | None = None,
    scaler: ScalerT | None = None,
    shifter: KernelT | None = None
)

Bases: BaseWaifu2x

backend_kwargs class-attribute instance-attribute

backend_kwargs: KwargsT | None = None

Kwargs passed to create the backend instance.

cuda class-attribute instance-attribute

cuda: bool | Literal['trt'] | None = None

Whether to run this on cpu, gpu, or use trt technology. None will pick the fastest automatically.

device_id class-attribute instance-attribute

device_id: int = 0

Id of the cuda device to use.

dynamic_shape class-attribute instance-attribute

dynamic_shape: bool | None = None

Use a single model for 0-max_shapes resolutions. None to automatically detect it. Will be True when previewing and TRT is available.

fp16 class-attribute instance-attribute

fp16: bool = True

Whether to use float16 precision if available.

func instance-attribute

func = func

kernel class-attribute instance-attribute

kernel: KernelT | None = field(default=None, kw_only=True)

Base kernel to be used for certain scaling/shifting/resampling operations. Must be specified and defaults to catrom

kwargs instance-attribute

kwargs = kwargs

matrix class-attribute instance-attribute

matrix: MatrixT | None = None

Input clip's matrix. Set only if necessary.

max_instances class-attribute instance-attribute

max_instances: int = 2

Maximum instances to spawn when scaling a variable resolution clip.

max_shapes class-attribute instance-attribute

max_shapes: tuple[int, int] | None = (1936, 1088)

Max shape for a dynamic model when using TRT and variable resolution clip. This can be overridden if the frame size is bigger.

num_streams class-attribute instance-attribute

num_streams: int | None = None

Number of gpu streams for the model.

overlap class-attribute instance-attribute

overlap: int | tuple[int, int] | None = None

Overlap for reducing blocking artifacts between tile borders.

scale_function instance-attribute

scale_function: GenericVSFunction

Scale function called internally when scaling

scaler class-attribute instance-attribute

scaler: ScalerT | None = field(default=None, kw_only=True)

Scaler used for scaling operations. Defaults to kernel.

shifter class-attribute instance-attribute

shifter: KernelT | None = field(default=None, kw_only=True)

Kernel used for shifting operations. Defaults to kernel.

tiles class-attribute instance-attribute

tiles: int | tuple[int, int] | None = None

Process in separate tiles instead of the whole frame. Use if [V]RAM limited.

tilesize class-attribute instance-attribute

tilesize: int | tuple[int, int] | None = None

Manually specify the size of a single tile.

ensure_obj classmethod

ensure_obj(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> BaseScalerT
Source code
186
187
188
189
190
191
192
193
@classmethod
def ensure_obj(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> BaseScalerT:
    return _base_ensure_obj(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

ensure_scaler

ensure_scaler(scaler: ScalerT) -> Scaler
Source code
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
def ensure_scaler(self, scaler: ScalerT) -> Scaler:
    from dataclasses import is_dataclass, replace

    scaler_obj = Scaler.ensure_obj(scaler, self.__class__)

    if is_dataclass(scaler_obj):
        from inspect import Signature  #type: ignore[unreachable]

        kwargs = dict[str, ScalerT]()

        init_keys = Signature.from_callable(scaler_obj.__init__).parameters.keys()

        if 'kernel' in init_keys:
            kwargs.update(kernel=self.kernel or scaler_obj.kernel)

        if 'scaler' in init_keys:
            kwargs.update(scaler=self.scaler or scaler_obj.scaler)

        if 'shifter' in init_keys:
            kwargs.update(shifter=self.shifter or scaler_obj.shifter)

        if kwargs:
            scaler_obj = replace(scaler_obj, **kwargs)

    return scaler_obj

from_param classmethod

from_param(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> type[BaseScalerT]
Source code
177
178
179
180
181
182
183
184
@classmethod
def from_param(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> type[BaseScalerT]:
    return _base_from_param(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

get_clean_kwargs

get_clean_kwargs(*funcs: Callable[..., Any] | None) -> KwargsT
Source code
199
200
def get_clean_kwargs(self, *funcs: Callable[..., Any] | None) -> KwargsT:
    return _clean_self_kwargs(funcs, self)

get_implemented_funcs

get_implemented_funcs() -> tuple[Callable[..., Any], ...]
Source code
270
271
def get_implemented_funcs(self) -> tuple[Callable[..., Any], ...]:
    return (self.scale, self.multi)

get_scale_args

get_scale_args(
    clip: VideoNode,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None,
    height: int | None = None,
    *funcs: Callable[..., Any],
    **kwargs: Any
) -> KwargsT
Source code
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
@inject_kwargs_params
def get_scale_args(
    self, clip: vs.VideoNode, shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None, height: int | None = None,
    *funcs: Callable[..., Any], **kwargs: Any
) -> KwargsT:
    return (
        dict(
            src_top=shift[0],
            src_left=shift[1]
        )
        | self.get_clean_kwargs(*funcs)
        | dict(width=width, height=height)
        | kwargs
    )

kernel_radius

kernel_radius() -> int
Source code
195
196
197
@inject_self.cached.property
def kernel_radius(self) -> int:
    return _default_kernel_radius(__class__, self)  # type: ignore

multi

multi(
    clip: VideoNode,
    multi: float = 2,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
239
240
241
242
243
244
245
246
247
248
249
250
251
252
@inject_self.cached
def multi(
    self, clip: vs.VideoNode, multi: float = 2, shift: tuple[TopShift, LeftShift] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    assert check_variable_resolution(clip, self.multi)

    dst_width, dst_height = ceil(clip.width * multi), ceil(clip.height * multi)

    if max(dst_width, dst_height) <= 0.0:
        raise CustomValueError(
            'Multiplying the resolution by "multi" must result in a positive resolution!', self.multi, multi
        )

    return self.scale(clip, dst_width, dst_height, shift, **kwargs)

pretty_string

pretty_string() -> str
Source code
202
203
204
205
206
207
208
209
210
211
212
213
214
@inject_self.cached.property
def pretty_string(self) -> str:
    attrs = {}

    if hasattr(self, 'b'):
        attrs.update(b=self.b, c=self.c)
    elif hasattr(self, 'taps'):
        attrs['taps'] = self.taps

    if hasattr(self, 'kwargs'):
        attrs.update(self.kwargs)

    return f"{self.__class__.__name__}{' (' + ', '.join(f'{k}={v}' for k, v in attrs.items()) + ')' if attrs else ''}"

scale

scale(
    clip: VideoNode,
    width: int | None = None,
    height: int | None = None,
    shift: tuple[float, float] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
@inject_self.init_kwargs.clean
def scale(  # type:ignore
    self, clip: vs.VideoNode, width: int | None = None, height: int | None = None,
    shift: tuple[float, float] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    try:
        from vsmlrt import Backend
    except ModuleNotFoundError as e:
        raise DependencyNotFoundError(self.__class__, e)

    width, height = self._wh_norm(clip, width, height)

    wclip = clip

    assert check_variable_format(clip, self.scale)

    matrix = self.matrix
    is_gray = clip.format.color_family is vs.GRAY
    planes = 0 if is_gray else None

    _static_args = kwargs.pop('_static_args', self._static_args)
    force = _static_args.pop('force', False)
    do_scale = _static_args.get('scale') > 1

    bkwargs = self._bkwargs.copy()

    dynamic_shapes = self.dynamic_shape or (0 in (clip.width, clip.height)) or not bkwargs.get('static_shape', True)

    kwargs.update(tiles=self.tiles, tilesize=self.tilesize, overlap=self.overlap)

    if dynamic_shapes and self._backend is Backend.TRT:
        bkwargs.update(static_shape=False, opt_shapes=(64, 64), max_shapes=self.max_shapes)

    if (is_upscale := width > clip.width or height > clip.width or force):
        model = self._model

        if clip.format.color_family is vs.YUV:
            if not matrix:
                matrix = Matrix.from_param_or_video(matrix or self.matrix, clip, False, self.__class__)

            wclip = self._kernel.resample(wclip, vs.RGBH if self.fp16 else vs.RGBS, Matrix.RGB, matrix)
        else:
            wclip = depth(wclip, 16 if self.fp16 else 32, vs.FLOAT)

            if is_gray and model != 0:
                wclip = wclip.std.ShufflePlanes(0, vs.RGB)

        assert wclip.format

        if wclip.format.color_family is vs.RGB:
            if model == 0:
                model = 1

        wclip = Waifu2xResizeHelper(
            wclip, width, height, planes, is_gray, self._scaler,
            do_scale and self._model == Waifu2x.Cunet._model,
            KwargsT(
                **_static_args, model=model,
                preprocess=False, **kwargs
            ), self.max_instances, self._backend, bkwargs  # type: ignore[arg-type]
        ).eval_clip()

    return self._finish_scale(wclip, clip, width, height, shift, matrix, is_upscale)

Cunet dataclass

Cunet(
    cuda: bool | Literal["trt"] | None = None,
    num_streams: int | None = None,
    fp16: bool = True,
    device_id: int = 0,
    matrix: MatrixT | None = None,
    tiles: int | tuple[int, int] | None = None,
    tilesize: int | tuple[int, int] | None = None,
    overlap: int | tuple[int, int] | None = None,
    backend_kwargs: KwargsT | None = None,
    dynamic_shape: bool | None = None,
    max_shapes: tuple[int, int] | None = (1936, 1088),
    max_instances: int = 2,
    *,
    kernel: KernelT | None = None,
    scaler: ScalerT | None = None,
    shifter: KernelT | None = None
)

Bases: BaseWaifu2x

backend_kwargs class-attribute instance-attribute

backend_kwargs: KwargsT | None = None

Kwargs passed to create the backend instance.

cuda class-attribute instance-attribute

cuda: bool | Literal['trt'] | None = None

Whether to run this on cpu, gpu, or use trt technology. None will pick the fastest automatically.

device_id class-attribute instance-attribute

device_id: int = 0

Id of the cuda device to use.

dynamic_shape class-attribute instance-attribute

dynamic_shape: bool | None = None

Use a single model for 0-max_shapes resolutions. None to automatically detect it. Will be True when previewing and TRT is available.

fp16 class-attribute instance-attribute

fp16: bool = True

Whether to use float16 precision if available.

func instance-attribute

func = func

kernel class-attribute instance-attribute

kernel: KernelT | None = field(default=None, kw_only=True)

Base kernel to be used for certain scaling/shifting/resampling operations. Must be specified and defaults to catrom

kwargs instance-attribute

kwargs = kwargs

matrix class-attribute instance-attribute

matrix: MatrixT | None = None

Input clip's matrix. Set only if necessary.

max_instances class-attribute instance-attribute

max_instances: int = 2

Maximum instances to spawn when scaling a variable resolution clip.

max_shapes class-attribute instance-attribute

max_shapes: tuple[int, int] | None = (1936, 1088)

Max shape for a dynamic model when using TRT and variable resolution clip. This can be overridden if the frame size is bigger.

num_streams class-attribute instance-attribute

num_streams: int | None = None

Number of gpu streams for the model.

overlap class-attribute instance-attribute

overlap: int | tuple[int, int] | None = None

Overlap for reducing blocking artifacts between tile borders.

scale_function instance-attribute

scale_function: GenericVSFunction

Scale function called internally when scaling

scaler class-attribute instance-attribute

scaler: ScalerT | None = field(default=None, kw_only=True)

Scaler used for scaling operations. Defaults to kernel.

shifter class-attribute instance-attribute

shifter: KernelT | None = field(default=None, kw_only=True)

Kernel used for shifting operations. Defaults to kernel.

tiles class-attribute instance-attribute

tiles: int | tuple[int, int] | None = None

Process in separate tiles instead of the whole frame. Use if [V]RAM limited.

tilesize class-attribute instance-attribute

tilesize: int | tuple[int, int] | None = None

Manually specify the size of a single tile.

ensure_obj classmethod

ensure_obj(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> BaseScalerT
Source code
186
187
188
189
190
191
192
193
@classmethod
def ensure_obj(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> BaseScalerT:
    return _base_ensure_obj(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

ensure_scaler

ensure_scaler(scaler: ScalerT) -> Scaler
Source code
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
def ensure_scaler(self, scaler: ScalerT) -> Scaler:
    from dataclasses import is_dataclass, replace

    scaler_obj = Scaler.ensure_obj(scaler, self.__class__)

    if is_dataclass(scaler_obj):
        from inspect import Signature  #type: ignore[unreachable]

        kwargs = dict[str, ScalerT]()

        init_keys = Signature.from_callable(scaler_obj.__init__).parameters.keys()

        if 'kernel' in init_keys:
            kwargs.update(kernel=self.kernel or scaler_obj.kernel)

        if 'scaler' in init_keys:
            kwargs.update(scaler=self.scaler or scaler_obj.scaler)

        if 'shifter' in init_keys:
            kwargs.update(shifter=self.shifter or scaler_obj.shifter)

        if kwargs:
            scaler_obj = replace(scaler_obj, **kwargs)

    return scaler_obj

from_param classmethod

from_param(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> type[BaseScalerT]
Source code
177
178
179
180
181
182
183
184
@classmethod
def from_param(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> type[BaseScalerT]:
    return _base_from_param(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

get_clean_kwargs

get_clean_kwargs(*funcs: Callable[..., Any] | None) -> KwargsT
Source code
199
200
def get_clean_kwargs(self, *funcs: Callable[..., Any] | None) -> KwargsT:
    return _clean_self_kwargs(funcs, self)

get_implemented_funcs

get_implemented_funcs() -> tuple[Callable[..., Any], ...]
Source code
270
271
def get_implemented_funcs(self) -> tuple[Callable[..., Any], ...]:
    return (self.scale, self.multi)

get_scale_args

get_scale_args(
    clip: VideoNode,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None,
    height: int | None = None,
    *funcs: Callable[..., Any],
    **kwargs: Any
) -> KwargsT
Source code
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
@inject_kwargs_params
def get_scale_args(
    self, clip: vs.VideoNode, shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None, height: int | None = None,
    *funcs: Callable[..., Any], **kwargs: Any
) -> KwargsT:
    return (
        dict(
            src_top=shift[0],
            src_left=shift[1]
        )
        | self.get_clean_kwargs(*funcs)
        | dict(width=width, height=height)
        | kwargs
    )

kernel_radius

kernel_radius() -> int
Source code
195
196
197
@inject_self.cached.property
def kernel_radius(self) -> int:
    return _default_kernel_radius(__class__, self)  # type: ignore

multi

multi(
    clip: VideoNode,
    multi: float = 2,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
239
240
241
242
243
244
245
246
247
248
249
250
251
252
@inject_self.cached
def multi(
    self, clip: vs.VideoNode, multi: float = 2, shift: tuple[TopShift, LeftShift] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    assert check_variable_resolution(clip, self.multi)

    dst_width, dst_height = ceil(clip.width * multi), ceil(clip.height * multi)

    if max(dst_width, dst_height) <= 0.0:
        raise CustomValueError(
            'Multiplying the resolution by "multi" must result in a positive resolution!', self.multi, multi
        )

    return self.scale(clip, dst_width, dst_height, shift, **kwargs)

pretty_string

pretty_string() -> str
Source code
202
203
204
205
206
207
208
209
210
211
212
213
214
@inject_self.cached.property
def pretty_string(self) -> str:
    attrs = {}

    if hasattr(self, 'b'):
        attrs.update(b=self.b, c=self.c)
    elif hasattr(self, 'taps'):
        attrs['taps'] = self.taps

    if hasattr(self, 'kwargs'):
        attrs.update(self.kwargs)

    return f"{self.__class__.__name__}{' (' + ', '.join(f'{k}={v}' for k, v in attrs.items()) + ')' if attrs else ''}"

scale

scale(
    clip: VideoNode,
    width: int | None = None,
    height: int | None = None,
    shift: tuple[float, float] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
@inject_self.init_kwargs.clean
def scale(  # type:ignore
    self, clip: vs.VideoNode, width: int | None = None, height: int | None = None,
    shift: tuple[float, float] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    try:
        from vsmlrt import Backend
    except ModuleNotFoundError as e:
        raise DependencyNotFoundError(self.__class__, e)

    width, height = self._wh_norm(clip, width, height)

    wclip = clip

    assert check_variable_format(clip, self.scale)

    matrix = self.matrix
    is_gray = clip.format.color_family is vs.GRAY
    planes = 0 if is_gray else None

    _static_args = kwargs.pop('_static_args', self._static_args)
    force = _static_args.pop('force', False)
    do_scale = _static_args.get('scale') > 1

    bkwargs = self._bkwargs.copy()

    dynamic_shapes = self.dynamic_shape or (0 in (clip.width, clip.height)) or not bkwargs.get('static_shape', True)

    kwargs.update(tiles=self.tiles, tilesize=self.tilesize, overlap=self.overlap)

    if dynamic_shapes and self._backend is Backend.TRT:
        bkwargs.update(static_shape=False, opt_shapes=(64, 64), max_shapes=self.max_shapes)

    if (is_upscale := width > clip.width or height > clip.width or force):
        model = self._model

        if clip.format.color_family is vs.YUV:
            if not matrix:
                matrix = Matrix.from_param_or_video(matrix or self.matrix, clip, False, self.__class__)

            wclip = self._kernel.resample(wclip, vs.RGBH if self.fp16 else vs.RGBS, Matrix.RGB, matrix)
        else:
            wclip = depth(wclip, 16 if self.fp16 else 32, vs.FLOAT)

            if is_gray and model != 0:
                wclip = wclip.std.ShufflePlanes(0, vs.RGB)

        assert wclip.format

        if wclip.format.color_family is vs.RGB:
            if model == 0:
                model = 1

        wclip = Waifu2xResizeHelper(
            wclip, width, height, planes, is_gray, self._scaler,
            do_scale and self._model == Waifu2x.Cunet._model,
            KwargsT(
                **_static_args, model=model,
                preprocess=False, **kwargs
            ), self.max_instances, self._backend, bkwargs  # type: ignore[arg-type]
        ).eval_clip()

    return self._finish_scale(wclip, clip, width, height, shift, matrix, is_upscale)

Photo dataclass

Photo(
    cuda: bool | Literal["trt"] | None = None,
    num_streams: int | None = None,
    fp16: bool = True,
    device_id: int = 0,
    matrix: MatrixT | None = None,
    tiles: int | tuple[int, int] | None = None,
    tilesize: int | tuple[int, int] | None = None,
    overlap: int | tuple[int, int] | None = None,
    backend_kwargs: KwargsT | None = None,
    dynamic_shape: bool | None = None,
    max_shapes: tuple[int, int] | None = (1936, 1088),
    max_instances: int = 2,
    *,
    kernel: KernelT | None = None,
    scaler: ScalerT | None = None,
    shifter: KernelT | None = None
)

Bases: BaseWaifu2x

backend_kwargs class-attribute instance-attribute

backend_kwargs: KwargsT | None = None

Kwargs passed to create the backend instance.

cuda class-attribute instance-attribute

cuda: bool | Literal['trt'] | None = None

Whether to run this on cpu, gpu, or use trt technology. None will pick the fastest automatically.

device_id class-attribute instance-attribute

device_id: int = 0

Id of the cuda device to use.

dynamic_shape class-attribute instance-attribute

dynamic_shape: bool | None = None

Use a single model for 0-max_shapes resolutions. None to automatically detect it. Will be True when previewing and TRT is available.

fp16 class-attribute instance-attribute

fp16: bool = True

Whether to use float16 precision if available.

func instance-attribute

func = func

kernel class-attribute instance-attribute

kernel: KernelT | None = field(default=None, kw_only=True)

Base kernel to be used for certain scaling/shifting/resampling operations. Must be specified and defaults to catrom

kwargs instance-attribute

kwargs = kwargs

matrix class-attribute instance-attribute

matrix: MatrixT | None = None

Input clip's matrix. Set only if necessary.

max_instances class-attribute instance-attribute

max_instances: int = 2

Maximum instances to spawn when scaling a variable resolution clip.

max_shapes class-attribute instance-attribute

max_shapes: tuple[int, int] | None = (1936, 1088)

Max shape for a dynamic model when using TRT and variable resolution clip. This can be overridden if the frame size is bigger.

num_streams class-attribute instance-attribute

num_streams: int | None = None

Number of gpu streams for the model.

overlap class-attribute instance-attribute

overlap: int | tuple[int, int] | None = None

Overlap for reducing blocking artifacts between tile borders.

scale_function instance-attribute

scale_function: GenericVSFunction

Scale function called internally when scaling

scaler class-attribute instance-attribute

scaler: ScalerT | None = field(default=None, kw_only=True)

Scaler used for scaling operations. Defaults to kernel.

shifter class-attribute instance-attribute

shifter: KernelT | None = field(default=None, kw_only=True)

Kernel used for shifting operations. Defaults to kernel.

tiles class-attribute instance-attribute

tiles: int | tuple[int, int] | None = None

Process in separate tiles instead of the whole frame. Use if [V]RAM limited.

tilesize class-attribute instance-attribute

tilesize: int | tuple[int, int] | None = None

Manually specify the size of a single tile.

ensure_obj classmethod

ensure_obj(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> BaseScalerT
Source code
186
187
188
189
190
191
192
193
@classmethod
def ensure_obj(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> BaseScalerT:
    return _base_ensure_obj(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

ensure_scaler

ensure_scaler(scaler: ScalerT) -> Scaler
Source code
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
def ensure_scaler(self, scaler: ScalerT) -> Scaler:
    from dataclasses import is_dataclass, replace

    scaler_obj = Scaler.ensure_obj(scaler, self.__class__)

    if is_dataclass(scaler_obj):
        from inspect import Signature  #type: ignore[unreachable]

        kwargs = dict[str, ScalerT]()

        init_keys = Signature.from_callable(scaler_obj.__init__).parameters.keys()

        if 'kernel' in init_keys:
            kwargs.update(kernel=self.kernel or scaler_obj.kernel)

        if 'scaler' in init_keys:
            kwargs.update(scaler=self.scaler or scaler_obj.scaler)

        if 'shifter' in init_keys:
            kwargs.update(shifter=self.shifter or scaler_obj.shifter)

        if kwargs:
            scaler_obj = replace(scaler_obj, **kwargs)

    return scaler_obj

from_param classmethod

from_param(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> type[BaseScalerT]
Source code
177
178
179
180
181
182
183
184
@classmethod
def from_param(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> type[BaseScalerT]:
    return _base_from_param(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

get_clean_kwargs

get_clean_kwargs(*funcs: Callable[..., Any] | None) -> KwargsT
Source code
199
200
def get_clean_kwargs(self, *funcs: Callable[..., Any] | None) -> KwargsT:
    return _clean_self_kwargs(funcs, self)

get_implemented_funcs

get_implemented_funcs() -> tuple[Callable[..., Any], ...]
Source code
270
271
def get_implemented_funcs(self) -> tuple[Callable[..., Any], ...]:
    return (self.scale, self.multi)

get_scale_args

get_scale_args(
    clip: VideoNode,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None,
    height: int | None = None,
    *funcs: Callable[..., Any],
    **kwargs: Any
) -> KwargsT
Source code
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
@inject_kwargs_params
def get_scale_args(
    self, clip: vs.VideoNode, shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None, height: int | None = None,
    *funcs: Callable[..., Any], **kwargs: Any
) -> KwargsT:
    return (
        dict(
            src_top=shift[0],
            src_left=shift[1]
        )
        | self.get_clean_kwargs(*funcs)
        | dict(width=width, height=height)
        | kwargs
    )

kernel_radius

kernel_radius() -> int
Source code
195
196
197
@inject_self.cached.property
def kernel_radius(self) -> int:
    return _default_kernel_radius(__class__, self)  # type: ignore

multi

multi(
    clip: VideoNode,
    multi: float = 2,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
239
240
241
242
243
244
245
246
247
248
249
250
251
252
@inject_self.cached
def multi(
    self, clip: vs.VideoNode, multi: float = 2, shift: tuple[TopShift, LeftShift] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    assert check_variable_resolution(clip, self.multi)

    dst_width, dst_height = ceil(clip.width * multi), ceil(clip.height * multi)

    if max(dst_width, dst_height) <= 0.0:
        raise CustomValueError(
            'Multiplying the resolution by "multi" must result in a positive resolution!', self.multi, multi
        )

    return self.scale(clip, dst_width, dst_height, shift, **kwargs)

pretty_string

pretty_string() -> str
Source code
202
203
204
205
206
207
208
209
210
211
212
213
214
@inject_self.cached.property
def pretty_string(self) -> str:
    attrs = {}

    if hasattr(self, 'b'):
        attrs.update(b=self.b, c=self.c)
    elif hasattr(self, 'taps'):
        attrs['taps'] = self.taps

    if hasattr(self, 'kwargs'):
        attrs.update(self.kwargs)

    return f"{self.__class__.__name__}{' (' + ', '.join(f'{k}={v}' for k, v in attrs.items()) + ')' if attrs else ''}"

scale

scale(
    clip: VideoNode,
    width: int | None = None,
    height: int | None = None,
    shift: tuple[float, float] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
@inject_self.init_kwargs.clean
def scale(  # type:ignore
    self, clip: vs.VideoNode, width: int | None = None, height: int | None = None,
    shift: tuple[float, float] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    try:
        from vsmlrt import Backend
    except ModuleNotFoundError as e:
        raise DependencyNotFoundError(self.__class__, e)

    width, height = self._wh_norm(clip, width, height)

    wclip = clip

    assert check_variable_format(clip, self.scale)

    matrix = self.matrix
    is_gray = clip.format.color_family is vs.GRAY
    planes = 0 if is_gray else None

    _static_args = kwargs.pop('_static_args', self._static_args)
    force = _static_args.pop('force', False)
    do_scale = _static_args.get('scale') > 1

    bkwargs = self._bkwargs.copy()

    dynamic_shapes = self.dynamic_shape or (0 in (clip.width, clip.height)) or not bkwargs.get('static_shape', True)

    kwargs.update(tiles=self.tiles, tilesize=self.tilesize, overlap=self.overlap)

    if dynamic_shapes and self._backend is Backend.TRT:
        bkwargs.update(static_shape=False, opt_shapes=(64, 64), max_shapes=self.max_shapes)

    if (is_upscale := width > clip.width or height > clip.width or force):
        model = self._model

        if clip.format.color_family is vs.YUV:
            if not matrix:
                matrix = Matrix.from_param_or_video(matrix or self.matrix, clip, False, self.__class__)

            wclip = self._kernel.resample(wclip, vs.RGBH if self.fp16 else vs.RGBS, Matrix.RGB, matrix)
        else:
            wclip = depth(wclip, 16 if self.fp16 else 32, vs.FLOAT)

            if is_gray and model != 0:
                wclip = wclip.std.ShufflePlanes(0, vs.RGB)

        assert wclip.format

        if wclip.format.color_family is vs.RGB:
            if model == 0:
                model = 1

        wclip = Waifu2xResizeHelper(
            wclip, width, height, planes, is_gray, self._scaler,
            do_scale and self._model == Waifu2x.Cunet._model,
            KwargsT(
                **_static_args, model=model,
                preprocess=False, **kwargs
            ), self.max_instances, self._backend, bkwargs  # type: ignore[arg-type]
        ).eval_clip()

    return self._finish_scale(wclip, clip, width, height, shift, matrix, is_upscale)

SwinUnetArt dataclass

SwinUnetArt(
    cuda: bool | Literal["trt"] | None = None,
    num_streams: int | None = None,
    fp16: bool = True,
    device_id: int = 0,
    matrix: MatrixT | None = None,
    tiles: int | tuple[int, int] | None = None,
    tilesize: int | tuple[int, int] | None = None,
    overlap: int | tuple[int, int] | None = None,
    backend_kwargs: KwargsT | None = None,
    dynamic_shape: bool | None = None,
    max_shapes: tuple[int, int] | None = (1936, 1088),
    max_instances: int = 2,
    *,
    kernel: KernelT | None = None,
    scaler: ScalerT | None = None,
    shifter: KernelT | None = None
)

Bases: BaseWaifu2x

backend_kwargs class-attribute instance-attribute

backend_kwargs: KwargsT | None = None

Kwargs passed to create the backend instance.

cuda class-attribute instance-attribute

cuda: bool | Literal['trt'] | None = None

Whether to run this on cpu, gpu, or use trt technology. None will pick the fastest automatically.

device_id class-attribute instance-attribute

device_id: int = 0

Id of the cuda device to use.

dynamic_shape class-attribute instance-attribute

dynamic_shape: bool | None = None

Use a single model for 0-max_shapes resolutions. None to automatically detect it. Will be True when previewing and TRT is available.

fp16 class-attribute instance-attribute

fp16: bool = True

Whether to use float16 precision if available.

func instance-attribute

func = func

kernel class-attribute instance-attribute

kernel: KernelT | None = field(default=None, kw_only=True)

Base kernel to be used for certain scaling/shifting/resampling operations. Must be specified and defaults to catrom

kwargs instance-attribute

kwargs = kwargs

matrix class-attribute instance-attribute

matrix: MatrixT | None = None

Input clip's matrix. Set only if necessary.

max_instances class-attribute instance-attribute

max_instances: int = 2

Maximum instances to spawn when scaling a variable resolution clip.

max_shapes class-attribute instance-attribute

max_shapes: tuple[int, int] | None = (1936, 1088)

Max shape for a dynamic model when using TRT and variable resolution clip. This can be overridden if the frame size is bigger.

num_streams class-attribute instance-attribute

num_streams: int | None = None

Number of gpu streams for the model.

overlap class-attribute instance-attribute

overlap: int | tuple[int, int] | None = None

Overlap for reducing blocking artifacts between tile borders.

scale_function instance-attribute

scale_function: GenericVSFunction

Scale function called internally when scaling

scaler class-attribute instance-attribute

scaler: ScalerT | None = field(default=None, kw_only=True)

Scaler used for scaling operations. Defaults to kernel.

shifter class-attribute instance-attribute

shifter: KernelT | None = field(default=None, kw_only=True)

Kernel used for shifting operations. Defaults to kernel.

tiles class-attribute instance-attribute

tiles: int | tuple[int, int] | None = None

Process in separate tiles instead of the whole frame. Use if [V]RAM limited.

tilesize class-attribute instance-attribute

tilesize: int | tuple[int, int] | None = None

Manually specify the size of a single tile.

ensure_obj classmethod

ensure_obj(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> BaseScalerT
Source code
186
187
188
189
190
191
192
193
@classmethod
def ensure_obj(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> BaseScalerT:
    return _base_ensure_obj(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

ensure_scaler

ensure_scaler(scaler: ScalerT) -> Scaler
Source code
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
def ensure_scaler(self, scaler: ScalerT) -> Scaler:
    from dataclasses import is_dataclass, replace

    scaler_obj = Scaler.ensure_obj(scaler, self.__class__)

    if is_dataclass(scaler_obj):
        from inspect import Signature  #type: ignore[unreachable]

        kwargs = dict[str, ScalerT]()

        init_keys = Signature.from_callable(scaler_obj.__init__).parameters.keys()

        if 'kernel' in init_keys:
            kwargs.update(kernel=self.kernel or scaler_obj.kernel)

        if 'scaler' in init_keys:
            kwargs.update(scaler=self.scaler or scaler_obj.scaler)

        if 'shifter' in init_keys:
            kwargs.update(shifter=self.shifter or scaler_obj.shifter)

        if kwargs:
            scaler_obj = replace(scaler_obj, **kwargs)

    return scaler_obj

from_param classmethod

from_param(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> type[BaseScalerT]
Source code
177
178
179
180
181
182
183
184
@classmethod
def from_param(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> type[BaseScalerT]:
    return _base_from_param(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

get_clean_kwargs

get_clean_kwargs(*funcs: Callable[..., Any] | None) -> KwargsT
Source code
199
200
def get_clean_kwargs(self, *funcs: Callable[..., Any] | None) -> KwargsT:
    return _clean_self_kwargs(funcs, self)

get_implemented_funcs

get_implemented_funcs() -> tuple[Callable[..., Any], ...]
Source code
270
271
def get_implemented_funcs(self) -> tuple[Callable[..., Any], ...]:
    return (self.scale, self.multi)

get_scale_args

get_scale_args(
    clip: VideoNode,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None,
    height: int | None = None,
    *funcs: Callable[..., Any],
    **kwargs: Any
) -> KwargsT
Source code
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
@inject_kwargs_params
def get_scale_args(
    self, clip: vs.VideoNode, shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None, height: int | None = None,
    *funcs: Callable[..., Any], **kwargs: Any
) -> KwargsT:
    return (
        dict(
            src_top=shift[0],
            src_left=shift[1]
        )
        | self.get_clean_kwargs(*funcs)
        | dict(width=width, height=height)
        | kwargs
    )

kernel_radius

kernel_radius() -> int
Source code
195
196
197
@inject_self.cached.property
def kernel_radius(self) -> int:
    return _default_kernel_radius(__class__, self)  # type: ignore

multi

multi(
    clip: VideoNode,
    multi: float = 2,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
239
240
241
242
243
244
245
246
247
248
249
250
251
252
@inject_self.cached
def multi(
    self, clip: vs.VideoNode, multi: float = 2, shift: tuple[TopShift, LeftShift] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    assert check_variable_resolution(clip, self.multi)

    dst_width, dst_height = ceil(clip.width * multi), ceil(clip.height * multi)

    if max(dst_width, dst_height) <= 0.0:
        raise CustomValueError(
            'Multiplying the resolution by "multi" must result in a positive resolution!', self.multi, multi
        )

    return self.scale(clip, dst_width, dst_height, shift, **kwargs)

pretty_string

pretty_string() -> str
Source code
202
203
204
205
206
207
208
209
210
211
212
213
214
@inject_self.cached.property
def pretty_string(self) -> str:
    attrs = {}

    if hasattr(self, 'b'):
        attrs.update(b=self.b, c=self.c)
    elif hasattr(self, 'taps'):
        attrs['taps'] = self.taps

    if hasattr(self, 'kwargs'):
        attrs.update(self.kwargs)

    return f"{self.__class__.__name__}{' (' + ', '.join(f'{k}={v}' for k, v in attrs.items()) + ')' if attrs else ''}"

scale

scale(
    clip: VideoNode,
    width: int | None = None,
    height: int | None = None,
    shift: tuple[float, float] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
@inject_self.init_kwargs.clean
def scale(  # type:ignore
    self, clip: vs.VideoNode, width: int | None = None, height: int | None = None,
    shift: tuple[float, float] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    try:
        from vsmlrt import Backend
    except ModuleNotFoundError as e:
        raise DependencyNotFoundError(self.__class__, e)

    width, height = self._wh_norm(clip, width, height)

    wclip = clip

    assert check_variable_format(clip, self.scale)

    matrix = self.matrix
    is_gray = clip.format.color_family is vs.GRAY
    planes = 0 if is_gray else None

    _static_args = kwargs.pop('_static_args', self._static_args)
    force = _static_args.pop('force', False)
    do_scale = _static_args.get('scale') > 1

    bkwargs = self._bkwargs.copy()

    dynamic_shapes = self.dynamic_shape or (0 in (clip.width, clip.height)) or not bkwargs.get('static_shape', True)

    kwargs.update(tiles=self.tiles, tilesize=self.tilesize, overlap=self.overlap)

    if dynamic_shapes and self._backend is Backend.TRT:
        bkwargs.update(static_shape=False, opt_shapes=(64, 64), max_shapes=self.max_shapes)

    if (is_upscale := width > clip.width or height > clip.width or force):
        model = self._model

        if clip.format.color_family is vs.YUV:
            if not matrix:
                matrix = Matrix.from_param_or_video(matrix or self.matrix, clip, False, self.__class__)

            wclip = self._kernel.resample(wclip, vs.RGBH if self.fp16 else vs.RGBS, Matrix.RGB, matrix)
        else:
            wclip = depth(wclip, 16 if self.fp16 else 32, vs.FLOAT)

            if is_gray and model != 0:
                wclip = wclip.std.ShufflePlanes(0, vs.RGB)

        assert wclip.format

        if wclip.format.color_family is vs.RGB:
            if model == 0:
                model = 1

        wclip = Waifu2xResizeHelper(
            wclip, width, height, planes, is_gray, self._scaler,
            do_scale and self._model == Waifu2x.Cunet._model,
            KwargsT(
                **_static_args, model=model,
                preprocess=False, **kwargs
            ), self.max_instances, self._backend, bkwargs  # type: ignore[arg-type]
        ).eval_clip()

    return self._finish_scale(wclip, clip, width, height, shift, matrix, is_upscale)

SwinUnetArtScan dataclass

SwinUnetArtScan(
    cuda: bool | Literal["trt"] | None = None,
    num_streams: int | None = None,
    fp16: bool = True,
    device_id: int = 0,
    matrix: MatrixT | None = None,
    tiles: int | tuple[int, int] | None = None,
    tilesize: int | tuple[int, int] | None = None,
    overlap: int | tuple[int, int] | None = None,
    backend_kwargs: KwargsT | None = None,
    dynamic_shape: bool | None = None,
    max_shapes: tuple[int, int] | None = (1936, 1088),
    max_instances: int = 2,
    *,
    kernel: KernelT | None = None,
    scaler: ScalerT | None = None,
    shifter: KernelT | None = None
)

Bases: BaseWaifu2x

backend_kwargs class-attribute instance-attribute

backend_kwargs: KwargsT | None = None

Kwargs passed to create the backend instance.

cuda class-attribute instance-attribute

cuda: bool | Literal['trt'] | None = None

Whether to run this on cpu, gpu, or use trt technology. None will pick the fastest automatically.

device_id class-attribute instance-attribute

device_id: int = 0

Id of the cuda device to use.

dynamic_shape class-attribute instance-attribute

dynamic_shape: bool | None = None

Use a single model for 0-max_shapes resolutions. None to automatically detect it. Will be True when previewing and TRT is available.

fp16 class-attribute instance-attribute

fp16: bool = True

Whether to use float16 precision if available.

func instance-attribute

func = func

kernel class-attribute instance-attribute

kernel: KernelT | None = field(default=None, kw_only=True)

Base kernel to be used for certain scaling/shifting/resampling operations. Must be specified and defaults to catrom

kwargs instance-attribute

kwargs = kwargs

matrix class-attribute instance-attribute

matrix: MatrixT | None = None

Input clip's matrix. Set only if necessary.

max_instances class-attribute instance-attribute

max_instances: int = 2

Maximum instances to spawn when scaling a variable resolution clip.

max_shapes class-attribute instance-attribute

max_shapes: tuple[int, int] | None = (1936, 1088)

Max shape for a dynamic model when using TRT and variable resolution clip. This can be overridden if the frame size is bigger.

num_streams class-attribute instance-attribute

num_streams: int | None = None

Number of gpu streams for the model.

overlap class-attribute instance-attribute

overlap: int | tuple[int, int] | None = None

Overlap for reducing blocking artifacts between tile borders.

scale_function instance-attribute

scale_function: GenericVSFunction

Scale function called internally when scaling

scaler class-attribute instance-attribute

scaler: ScalerT | None = field(default=None, kw_only=True)

Scaler used for scaling operations. Defaults to kernel.

shifter class-attribute instance-attribute

shifter: KernelT | None = field(default=None, kw_only=True)

Kernel used for shifting operations. Defaults to kernel.

tiles class-attribute instance-attribute

tiles: int | tuple[int, int] | None = None

Process in separate tiles instead of the whole frame. Use if [V]RAM limited.

tilesize class-attribute instance-attribute

tilesize: int | tuple[int, int] | None = None

Manually specify the size of a single tile.

ensure_obj classmethod

ensure_obj(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> BaseScalerT
Source code
186
187
188
189
190
191
192
193
@classmethod
def ensure_obj(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> BaseScalerT:
    return _base_ensure_obj(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

ensure_scaler

ensure_scaler(scaler: ScalerT) -> Scaler
Source code
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
def ensure_scaler(self, scaler: ScalerT) -> Scaler:
    from dataclasses import is_dataclass, replace

    scaler_obj = Scaler.ensure_obj(scaler, self.__class__)

    if is_dataclass(scaler_obj):
        from inspect import Signature  #type: ignore[unreachable]

        kwargs = dict[str, ScalerT]()

        init_keys = Signature.from_callable(scaler_obj.__init__).parameters.keys()

        if 'kernel' in init_keys:
            kwargs.update(kernel=self.kernel or scaler_obj.kernel)

        if 'scaler' in init_keys:
            kwargs.update(scaler=self.scaler or scaler_obj.scaler)

        if 'shifter' in init_keys:
            kwargs.update(shifter=self.shifter or scaler_obj.shifter)

        if kwargs:
            scaler_obj = replace(scaler_obj, **kwargs)

    return scaler_obj

from_param classmethod

from_param(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> type[BaseScalerT]
Source code
177
178
179
180
181
182
183
184
@classmethod
def from_param(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> type[BaseScalerT]:
    return _base_from_param(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

get_clean_kwargs

get_clean_kwargs(*funcs: Callable[..., Any] | None) -> KwargsT
Source code
199
200
def get_clean_kwargs(self, *funcs: Callable[..., Any] | None) -> KwargsT:
    return _clean_self_kwargs(funcs, self)

get_implemented_funcs

get_implemented_funcs() -> tuple[Callable[..., Any], ...]
Source code
270
271
def get_implemented_funcs(self) -> tuple[Callable[..., Any], ...]:
    return (self.scale, self.multi)

get_scale_args

get_scale_args(
    clip: VideoNode,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None,
    height: int | None = None,
    *funcs: Callable[..., Any],
    **kwargs: Any
) -> KwargsT
Source code
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
@inject_kwargs_params
def get_scale_args(
    self, clip: vs.VideoNode, shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None, height: int | None = None,
    *funcs: Callable[..., Any], **kwargs: Any
) -> KwargsT:
    return (
        dict(
            src_top=shift[0],
            src_left=shift[1]
        )
        | self.get_clean_kwargs(*funcs)
        | dict(width=width, height=height)
        | kwargs
    )

kernel_radius

kernel_radius() -> int
Source code
195
196
197
@inject_self.cached.property
def kernel_radius(self) -> int:
    return _default_kernel_radius(__class__, self)  # type: ignore

multi

multi(
    clip: VideoNode,
    multi: float = 2,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
239
240
241
242
243
244
245
246
247
248
249
250
251
252
@inject_self.cached
def multi(
    self, clip: vs.VideoNode, multi: float = 2, shift: tuple[TopShift, LeftShift] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    assert check_variable_resolution(clip, self.multi)

    dst_width, dst_height = ceil(clip.width * multi), ceil(clip.height * multi)

    if max(dst_width, dst_height) <= 0.0:
        raise CustomValueError(
            'Multiplying the resolution by "multi" must result in a positive resolution!', self.multi, multi
        )

    return self.scale(clip, dst_width, dst_height, shift, **kwargs)

pretty_string

pretty_string() -> str
Source code
202
203
204
205
206
207
208
209
210
211
212
213
214
@inject_self.cached.property
def pretty_string(self) -> str:
    attrs = {}

    if hasattr(self, 'b'):
        attrs.update(b=self.b, c=self.c)
    elif hasattr(self, 'taps'):
        attrs['taps'] = self.taps

    if hasattr(self, 'kwargs'):
        attrs.update(self.kwargs)

    return f"{self.__class__.__name__}{' (' + ', '.join(f'{k}={v}' for k, v in attrs.items()) + ')' if attrs else ''}"

scale

scale(
    clip: VideoNode,
    width: int | None = None,
    height: int | None = None,
    shift: tuple[float, float] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
@inject_self.init_kwargs.clean
def scale(  # type:ignore
    self, clip: vs.VideoNode, width: int | None = None, height: int | None = None,
    shift: tuple[float, float] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    try:
        from vsmlrt import Backend
    except ModuleNotFoundError as e:
        raise DependencyNotFoundError(self.__class__, e)

    width, height = self._wh_norm(clip, width, height)

    wclip = clip

    assert check_variable_format(clip, self.scale)

    matrix = self.matrix
    is_gray = clip.format.color_family is vs.GRAY
    planes = 0 if is_gray else None

    _static_args = kwargs.pop('_static_args', self._static_args)
    force = _static_args.pop('force', False)
    do_scale = _static_args.get('scale') > 1

    bkwargs = self._bkwargs.copy()

    dynamic_shapes = self.dynamic_shape or (0 in (clip.width, clip.height)) or not bkwargs.get('static_shape', True)

    kwargs.update(tiles=self.tiles, tilesize=self.tilesize, overlap=self.overlap)

    if dynamic_shapes and self._backend is Backend.TRT:
        bkwargs.update(static_shape=False, opt_shapes=(64, 64), max_shapes=self.max_shapes)

    if (is_upscale := width > clip.width or height > clip.width or force):
        model = self._model

        if clip.format.color_family is vs.YUV:
            if not matrix:
                matrix = Matrix.from_param_or_video(matrix or self.matrix, clip, False, self.__class__)

            wclip = self._kernel.resample(wclip, vs.RGBH if self.fp16 else vs.RGBS, Matrix.RGB, matrix)
        else:
            wclip = depth(wclip, 16 if self.fp16 else 32, vs.FLOAT)

            if is_gray and model != 0:
                wclip = wclip.std.ShufflePlanes(0, vs.RGB)

        assert wclip.format

        if wclip.format.color_family is vs.RGB:
            if model == 0:
                model = 1

        wclip = Waifu2xResizeHelper(
            wclip, width, height, planes, is_gray, self._scaler,
            do_scale and self._model == Waifu2x.Cunet._model,
            KwargsT(
                **_static_args, model=model,
                preprocess=False, **kwargs
            ), self.max_instances, self._backend, bkwargs  # type: ignore[arg-type]
        ).eval_clip()

    return self._finish_scale(wclip, clip, width, height, shift, matrix, is_upscale)

SwinUnetPhoto dataclass

SwinUnetPhoto(
    cuda: bool | Literal["trt"] | None = None,
    num_streams: int | None = None,
    fp16: bool = True,
    device_id: int = 0,
    matrix: MatrixT | None = None,
    tiles: int | tuple[int, int] | None = None,
    tilesize: int | tuple[int, int] | None = None,
    overlap: int | tuple[int, int] | None = None,
    backend_kwargs: KwargsT | None = None,
    dynamic_shape: bool | None = None,
    max_shapes: tuple[int, int] | None = (1936, 1088),
    max_instances: int = 2,
    *,
    kernel: KernelT | None = None,
    scaler: ScalerT | None = None,
    shifter: KernelT | None = None
)

Bases: BaseWaifu2x

backend_kwargs class-attribute instance-attribute

backend_kwargs: KwargsT | None = None

Kwargs passed to create the backend instance.

cuda class-attribute instance-attribute

cuda: bool | Literal['trt'] | None = None

Whether to run this on cpu, gpu, or use trt technology. None will pick the fastest automatically.

device_id class-attribute instance-attribute

device_id: int = 0

Id of the cuda device to use.

dynamic_shape class-attribute instance-attribute

dynamic_shape: bool | None = None

Use a single model for 0-max_shapes resolutions. None to automatically detect it. Will be True when previewing and TRT is available.

fp16 class-attribute instance-attribute

fp16: bool = True

Whether to use float16 precision if available.

func instance-attribute

func = func

kernel class-attribute instance-attribute

kernel: KernelT | None = field(default=None, kw_only=True)

Base kernel to be used for certain scaling/shifting/resampling operations. Must be specified and defaults to catrom

kwargs instance-attribute

kwargs = kwargs

matrix class-attribute instance-attribute

matrix: MatrixT | None = None

Input clip's matrix. Set only if necessary.

max_instances class-attribute instance-attribute

max_instances: int = 2

Maximum instances to spawn when scaling a variable resolution clip.

max_shapes class-attribute instance-attribute

max_shapes: tuple[int, int] | None = (1936, 1088)

Max shape for a dynamic model when using TRT and variable resolution clip. This can be overridden if the frame size is bigger.

num_streams class-attribute instance-attribute

num_streams: int | None = None

Number of gpu streams for the model.

overlap class-attribute instance-attribute

overlap: int | tuple[int, int] | None = None

Overlap for reducing blocking artifacts between tile borders.

scale_function instance-attribute

scale_function: GenericVSFunction

Scale function called internally when scaling

scaler class-attribute instance-attribute

scaler: ScalerT | None = field(default=None, kw_only=True)

Scaler used for scaling operations. Defaults to kernel.

shifter class-attribute instance-attribute

shifter: KernelT | None = field(default=None, kw_only=True)

Kernel used for shifting operations. Defaults to kernel.

tiles class-attribute instance-attribute

tiles: int | tuple[int, int] | None = None

Process in separate tiles instead of the whole frame. Use if [V]RAM limited.

tilesize class-attribute instance-attribute

tilesize: int | tuple[int, int] | None = None

Manually specify the size of a single tile.

ensure_obj classmethod

ensure_obj(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> BaseScalerT
Source code
186
187
188
189
190
191
192
193
@classmethod
def ensure_obj(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> BaseScalerT:
    return _base_ensure_obj(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

ensure_scaler

ensure_scaler(scaler: ScalerT) -> Scaler
Source code
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
def ensure_scaler(self, scaler: ScalerT) -> Scaler:
    from dataclasses import is_dataclass, replace

    scaler_obj = Scaler.ensure_obj(scaler, self.__class__)

    if is_dataclass(scaler_obj):
        from inspect import Signature  #type: ignore[unreachable]

        kwargs = dict[str, ScalerT]()

        init_keys = Signature.from_callable(scaler_obj.__init__).parameters.keys()

        if 'kernel' in init_keys:
            kwargs.update(kernel=self.kernel or scaler_obj.kernel)

        if 'scaler' in init_keys:
            kwargs.update(scaler=self.scaler or scaler_obj.scaler)

        if 'shifter' in init_keys:
            kwargs.update(shifter=self.shifter or scaler_obj.shifter)

        if kwargs:
            scaler_obj = replace(scaler_obj, **kwargs)

    return scaler_obj

from_param classmethod

from_param(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> type[BaseScalerT]
Source code
177
178
179
180
181
182
183
184
@classmethod
def from_param(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> type[BaseScalerT]:
    return _base_from_param(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

get_clean_kwargs

get_clean_kwargs(*funcs: Callable[..., Any] | None) -> KwargsT
Source code
199
200
def get_clean_kwargs(self, *funcs: Callable[..., Any] | None) -> KwargsT:
    return _clean_self_kwargs(funcs, self)

get_implemented_funcs

get_implemented_funcs() -> tuple[Callable[..., Any], ...]
Source code
270
271
def get_implemented_funcs(self) -> tuple[Callable[..., Any], ...]:
    return (self.scale, self.multi)

get_scale_args

get_scale_args(
    clip: VideoNode,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None,
    height: int | None = None,
    *funcs: Callable[..., Any],
    **kwargs: Any
) -> KwargsT
Source code
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
@inject_kwargs_params
def get_scale_args(
    self, clip: vs.VideoNode, shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None, height: int | None = None,
    *funcs: Callable[..., Any], **kwargs: Any
) -> KwargsT:
    return (
        dict(
            src_top=shift[0],
            src_left=shift[1]
        )
        | self.get_clean_kwargs(*funcs)
        | dict(width=width, height=height)
        | kwargs
    )

kernel_radius

kernel_radius() -> int
Source code
195
196
197
@inject_self.cached.property
def kernel_radius(self) -> int:
    return _default_kernel_radius(__class__, self)  # type: ignore

multi

multi(
    clip: VideoNode,
    multi: float = 2,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
239
240
241
242
243
244
245
246
247
248
249
250
251
252
@inject_self.cached
def multi(
    self, clip: vs.VideoNode, multi: float = 2, shift: tuple[TopShift, LeftShift] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    assert check_variable_resolution(clip, self.multi)

    dst_width, dst_height = ceil(clip.width * multi), ceil(clip.height * multi)

    if max(dst_width, dst_height) <= 0.0:
        raise CustomValueError(
            'Multiplying the resolution by "multi" must result in a positive resolution!', self.multi, multi
        )

    return self.scale(clip, dst_width, dst_height, shift, **kwargs)

pretty_string

pretty_string() -> str
Source code
202
203
204
205
206
207
208
209
210
211
212
213
214
@inject_self.cached.property
def pretty_string(self) -> str:
    attrs = {}

    if hasattr(self, 'b'):
        attrs.update(b=self.b, c=self.c)
    elif hasattr(self, 'taps'):
        attrs['taps'] = self.taps

    if hasattr(self, 'kwargs'):
        attrs.update(self.kwargs)

    return f"{self.__class__.__name__}{' (' + ', '.join(f'{k}={v}' for k, v in attrs.items()) + ')' if attrs else ''}"

scale

scale(
    clip: VideoNode,
    width: int | None = None,
    height: int | None = None,
    shift: tuple[float, float] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
@inject_self.init_kwargs.clean
def scale(  # type:ignore
    self, clip: vs.VideoNode, width: int | None = None, height: int | None = None,
    shift: tuple[float, float] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    try:
        from vsmlrt import Backend
    except ModuleNotFoundError as e:
        raise DependencyNotFoundError(self.__class__, e)

    width, height = self._wh_norm(clip, width, height)

    wclip = clip

    assert check_variable_format(clip, self.scale)

    matrix = self.matrix
    is_gray = clip.format.color_family is vs.GRAY
    planes = 0 if is_gray else None

    _static_args = kwargs.pop('_static_args', self._static_args)
    force = _static_args.pop('force', False)
    do_scale = _static_args.get('scale') > 1

    bkwargs = self._bkwargs.copy()

    dynamic_shapes = self.dynamic_shape or (0 in (clip.width, clip.height)) or not bkwargs.get('static_shape', True)

    kwargs.update(tiles=self.tiles, tilesize=self.tilesize, overlap=self.overlap)

    if dynamic_shapes and self._backend is Backend.TRT:
        bkwargs.update(static_shape=False, opt_shapes=(64, 64), max_shapes=self.max_shapes)

    if (is_upscale := width > clip.width or height > clip.width or force):
        model = self._model

        if clip.format.color_family is vs.YUV:
            if not matrix:
                matrix = Matrix.from_param_or_video(matrix or self.matrix, clip, False, self.__class__)

            wclip = self._kernel.resample(wclip, vs.RGBH if self.fp16 else vs.RGBS, Matrix.RGB, matrix)
        else:
            wclip = depth(wclip, 16 if self.fp16 else 32, vs.FLOAT)

            if is_gray and model != 0:
                wclip = wclip.std.ShufflePlanes(0, vs.RGB)

        assert wclip.format

        if wclip.format.color_family is vs.RGB:
            if model == 0:
                model = 1

        wclip = Waifu2xResizeHelper(
            wclip, width, height, planes, is_gray, self._scaler,
            do_scale and self._model == Waifu2x.Cunet._model,
            KwargsT(
                **_static_args, model=model,
                preprocess=False, **kwargs
            ), self.max_instances, self._backend, bkwargs  # type: ignore[arg-type]
        ).eval_clip()

    return self._finish_scale(wclip, clip, width, height, shift, matrix, is_upscale)

SwinUnetPhotoV2 dataclass

SwinUnetPhotoV2(
    cuda: bool | Literal["trt"] | None = None,
    num_streams: int | None = None,
    fp16: bool = True,
    device_id: int = 0,
    matrix: MatrixT | None = None,
    tiles: int | tuple[int, int] | None = None,
    tilesize: int | tuple[int, int] | None = None,
    overlap: int | tuple[int, int] | None = None,
    backend_kwargs: KwargsT | None = None,
    dynamic_shape: bool | None = None,
    max_shapes: tuple[int, int] | None = (1936, 1088),
    max_instances: int = 2,
    *,
    kernel: KernelT | None = None,
    scaler: ScalerT | None = None,
    shifter: KernelT | None = None
)

Bases: BaseWaifu2x

backend_kwargs class-attribute instance-attribute

backend_kwargs: KwargsT | None = None

Kwargs passed to create the backend instance.

cuda class-attribute instance-attribute

cuda: bool | Literal['trt'] | None = None

Whether to run this on cpu, gpu, or use trt technology. None will pick the fastest automatically.

device_id class-attribute instance-attribute

device_id: int = 0

Id of the cuda device to use.

dynamic_shape class-attribute instance-attribute

dynamic_shape: bool | None = None

Use a single model for 0-max_shapes resolutions. None to automatically detect it. Will be True when previewing and TRT is available.

fp16 class-attribute instance-attribute

fp16: bool = True

Whether to use float16 precision if available.

func instance-attribute

func = func

kernel class-attribute instance-attribute

kernel: KernelT | None = field(default=None, kw_only=True)

Base kernel to be used for certain scaling/shifting/resampling operations. Must be specified and defaults to catrom

kwargs instance-attribute

kwargs = kwargs

matrix class-attribute instance-attribute

matrix: MatrixT | None = None

Input clip's matrix. Set only if necessary.

max_instances class-attribute instance-attribute

max_instances: int = 2

Maximum instances to spawn when scaling a variable resolution clip.

max_shapes class-attribute instance-attribute

max_shapes: tuple[int, int] | None = (1936, 1088)

Max shape for a dynamic model when using TRT and variable resolution clip. This can be overridden if the frame size is bigger.

num_streams class-attribute instance-attribute

num_streams: int | None = None

Number of gpu streams for the model.

overlap class-attribute instance-attribute

overlap: int | tuple[int, int] | None = None

Overlap for reducing blocking artifacts between tile borders.

scale_function instance-attribute

scale_function: GenericVSFunction

Scale function called internally when scaling

scaler class-attribute instance-attribute

scaler: ScalerT | None = field(default=None, kw_only=True)

Scaler used for scaling operations. Defaults to kernel.

shifter class-attribute instance-attribute

shifter: KernelT | None = field(default=None, kw_only=True)

Kernel used for shifting operations. Defaults to kernel.

tiles class-attribute instance-attribute

tiles: int | tuple[int, int] | None = None

Process in separate tiles instead of the whole frame. Use if [V]RAM limited.

tilesize class-attribute instance-attribute

tilesize: int | tuple[int, int] | None = None

Manually specify the size of a single tile.

ensure_obj classmethod

ensure_obj(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> BaseScalerT
Source code
186
187
188
189
190
191
192
193
@classmethod
def ensure_obj(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> BaseScalerT:
    return _base_ensure_obj(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

ensure_scaler

ensure_scaler(scaler: ScalerT) -> Scaler
Source code
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
def ensure_scaler(self, scaler: ScalerT) -> Scaler:
    from dataclasses import is_dataclass, replace

    scaler_obj = Scaler.ensure_obj(scaler, self.__class__)

    if is_dataclass(scaler_obj):
        from inspect import Signature  #type: ignore[unreachable]

        kwargs = dict[str, ScalerT]()

        init_keys = Signature.from_callable(scaler_obj.__init__).parameters.keys()

        if 'kernel' in init_keys:
            kwargs.update(kernel=self.kernel or scaler_obj.kernel)

        if 'scaler' in init_keys:
            kwargs.update(scaler=self.scaler or scaler_obj.scaler)

        if 'shifter' in init_keys:
            kwargs.update(shifter=self.shifter or scaler_obj.shifter)

        if kwargs:
            scaler_obj = replace(scaler_obj, **kwargs)

    return scaler_obj

from_param classmethod

from_param(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> type[BaseScalerT]
Source code
177
178
179
180
181
182
183
184
@classmethod
def from_param(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> type[BaseScalerT]:
    return _base_from_param(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

get_clean_kwargs

get_clean_kwargs(*funcs: Callable[..., Any] | None) -> KwargsT
Source code
199
200
def get_clean_kwargs(self, *funcs: Callable[..., Any] | None) -> KwargsT:
    return _clean_self_kwargs(funcs, self)

get_implemented_funcs

get_implemented_funcs() -> tuple[Callable[..., Any], ...]
Source code
270
271
def get_implemented_funcs(self) -> tuple[Callable[..., Any], ...]:
    return (self.scale, self.multi)

get_scale_args

get_scale_args(
    clip: VideoNode,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None,
    height: int | None = None,
    *funcs: Callable[..., Any],
    **kwargs: Any
) -> KwargsT
Source code
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
@inject_kwargs_params
def get_scale_args(
    self, clip: vs.VideoNode, shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None, height: int | None = None,
    *funcs: Callable[..., Any], **kwargs: Any
) -> KwargsT:
    return (
        dict(
            src_top=shift[0],
            src_left=shift[1]
        )
        | self.get_clean_kwargs(*funcs)
        | dict(width=width, height=height)
        | kwargs
    )

kernel_radius

kernel_radius() -> int
Source code
195
196
197
@inject_self.cached.property
def kernel_radius(self) -> int:
    return _default_kernel_radius(__class__, self)  # type: ignore

multi

multi(
    clip: VideoNode,
    multi: float = 2,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
239
240
241
242
243
244
245
246
247
248
249
250
251
252
@inject_self.cached
def multi(
    self, clip: vs.VideoNode, multi: float = 2, shift: tuple[TopShift, LeftShift] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    assert check_variable_resolution(clip, self.multi)

    dst_width, dst_height = ceil(clip.width * multi), ceil(clip.height * multi)

    if max(dst_width, dst_height) <= 0.0:
        raise CustomValueError(
            'Multiplying the resolution by "multi" must result in a positive resolution!', self.multi, multi
        )

    return self.scale(clip, dst_width, dst_height, shift, **kwargs)

pretty_string

pretty_string() -> str
Source code
202
203
204
205
206
207
208
209
210
211
212
213
214
@inject_self.cached.property
def pretty_string(self) -> str:
    attrs = {}

    if hasattr(self, 'b'):
        attrs.update(b=self.b, c=self.c)
    elif hasattr(self, 'taps'):
        attrs['taps'] = self.taps

    if hasattr(self, 'kwargs'):
        attrs.update(self.kwargs)

    return f"{self.__class__.__name__}{' (' + ', '.join(f'{k}={v}' for k, v in attrs.items()) + ')' if attrs else ''}"

scale

scale(
    clip: VideoNode,
    width: int | None = None,
    height: int | None = None,
    shift: tuple[float, float] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
@inject_self.init_kwargs.clean
def scale(  # type:ignore
    self, clip: vs.VideoNode, width: int | None = None, height: int | None = None,
    shift: tuple[float, float] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    try:
        from vsmlrt import Backend
    except ModuleNotFoundError as e:
        raise DependencyNotFoundError(self.__class__, e)

    width, height = self._wh_norm(clip, width, height)

    wclip = clip

    assert check_variable_format(clip, self.scale)

    matrix = self.matrix
    is_gray = clip.format.color_family is vs.GRAY
    planes = 0 if is_gray else None

    _static_args = kwargs.pop('_static_args', self._static_args)
    force = _static_args.pop('force', False)
    do_scale = _static_args.get('scale') > 1

    bkwargs = self._bkwargs.copy()

    dynamic_shapes = self.dynamic_shape or (0 in (clip.width, clip.height)) or not bkwargs.get('static_shape', True)

    kwargs.update(tiles=self.tiles, tilesize=self.tilesize, overlap=self.overlap)

    if dynamic_shapes and self._backend is Backend.TRT:
        bkwargs.update(static_shape=False, opt_shapes=(64, 64), max_shapes=self.max_shapes)

    if (is_upscale := width > clip.width or height > clip.width or force):
        model = self._model

        if clip.format.color_family is vs.YUV:
            if not matrix:
                matrix = Matrix.from_param_or_video(matrix or self.matrix, clip, False, self.__class__)

            wclip = self._kernel.resample(wclip, vs.RGBH if self.fp16 else vs.RGBS, Matrix.RGB, matrix)
        else:
            wclip = depth(wclip, 16 if self.fp16 else 32, vs.FLOAT)

            if is_gray and model != 0:
                wclip = wclip.std.ShufflePlanes(0, vs.RGB)

        assert wclip.format

        if wclip.format.color_family is vs.RGB:
            if model == 0:
                model = 1

        wclip = Waifu2xResizeHelper(
            wclip, width, height, planes, is_gray, self._scaler,
            do_scale and self._model == Waifu2x.Cunet._model,
            KwargsT(
                **_static_args, model=model,
                preprocess=False, **kwargs
            ), self.max_instances, self._backend, bkwargs  # type: ignore[arg-type]
        ).eval_clip()

    return self._finish_scale(wclip, clip, width, height, shift, matrix, is_upscale)

UpConv7AnimeStyleArt dataclass

UpConv7AnimeStyleArt(
    cuda: bool | Literal["trt"] | None = None,
    num_streams: int | None = None,
    fp16: bool = True,
    device_id: int = 0,
    matrix: MatrixT | None = None,
    tiles: int | tuple[int, int] | None = None,
    tilesize: int | tuple[int, int] | None = None,
    overlap: int | tuple[int, int] | None = None,
    backend_kwargs: KwargsT | None = None,
    dynamic_shape: bool | None = None,
    max_shapes: tuple[int, int] | None = (1936, 1088),
    max_instances: int = 2,
    *,
    kernel: KernelT | None = None,
    scaler: ScalerT | None = None,
    shifter: KernelT | None = None
)

Bases: BaseWaifu2x

backend_kwargs class-attribute instance-attribute

backend_kwargs: KwargsT | None = None

Kwargs passed to create the backend instance.

cuda class-attribute instance-attribute

cuda: bool | Literal['trt'] | None = None

Whether to run this on cpu, gpu, or use trt technology. None will pick the fastest automatically.

device_id class-attribute instance-attribute

device_id: int = 0

Id of the cuda device to use.

dynamic_shape class-attribute instance-attribute

dynamic_shape: bool | None = None

Use a single model for 0-max_shapes resolutions. None to automatically detect it. Will be True when previewing and TRT is available.

fp16 class-attribute instance-attribute

fp16: bool = True

Whether to use float16 precision if available.

func instance-attribute

func = func

kernel class-attribute instance-attribute

kernel: KernelT | None = field(default=None, kw_only=True)

Base kernel to be used for certain scaling/shifting/resampling operations. Must be specified and defaults to catrom

kwargs instance-attribute

kwargs = kwargs

matrix class-attribute instance-attribute

matrix: MatrixT | None = None

Input clip's matrix. Set only if necessary.

max_instances class-attribute instance-attribute

max_instances: int = 2

Maximum instances to spawn when scaling a variable resolution clip.

max_shapes class-attribute instance-attribute

max_shapes: tuple[int, int] | None = (1936, 1088)

Max shape for a dynamic model when using TRT and variable resolution clip. This can be overridden if the frame size is bigger.

num_streams class-attribute instance-attribute

num_streams: int | None = None

Number of gpu streams for the model.

overlap class-attribute instance-attribute

overlap: int | tuple[int, int] | None = None

Overlap for reducing blocking artifacts between tile borders.

scale_function instance-attribute

scale_function: GenericVSFunction

Scale function called internally when scaling

scaler class-attribute instance-attribute

scaler: ScalerT | None = field(default=None, kw_only=True)

Scaler used for scaling operations. Defaults to kernel.

shifter class-attribute instance-attribute

shifter: KernelT | None = field(default=None, kw_only=True)

Kernel used for shifting operations. Defaults to kernel.

tiles class-attribute instance-attribute

tiles: int | tuple[int, int] | None = None

Process in separate tiles instead of the whole frame. Use if [V]RAM limited.

tilesize class-attribute instance-attribute

tilesize: int | tuple[int, int] | None = None

Manually specify the size of a single tile.

ensure_obj classmethod

ensure_obj(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> BaseScalerT
Source code
186
187
188
189
190
191
192
193
@classmethod
def ensure_obj(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> BaseScalerT:
    return _base_ensure_obj(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

ensure_scaler

ensure_scaler(scaler: ScalerT) -> Scaler
Source code
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
def ensure_scaler(self, scaler: ScalerT) -> Scaler:
    from dataclasses import is_dataclass, replace

    scaler_obj = Scaler.ensure_obj(scaler, self.__class__)

    if is_dataclass(scaler_obj):
        from inspect import Signature  #type: ignore[unreachable]

        kwargs = dict[str, ScalerT]()

        init_keys = Signature.from_callable(scaler_obj.__init__).parameters.keys()

        if 'kernel' in init_keys:
            kwargs.update(kernel=self.kernel or scaler_obj.kernel)

        if 'scaler' in init_keys:
            kwargs.update(scaler=self.scaler or scaler_obj.scaler)

        if 'shifter' in init_keys:
            kwargs.update(shifter=self.shifter or scaler_obj.shifter)

        if kwargs:
            scaler_obj = replace(scaler_obj, **kwargs)

    return scaler_obj

from_param classmethod

from_param(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> type[BaseScalerT]
Source code
177
178
179
180
181
182
183
184
@classmethod
def from_param(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> type[BaseScalerT]:
    return _base_from_param(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

get_clean_kwargs

get_clean_kwargs(*funcs: Callable[..., Any] | None) -> KwargsT
Source code
199
200
def get_clean_kwargs(self, *funcs: Callable[..., Any] | None) -> KwargsT:
    return _clean_self_kwargs(funcs, self)

get_implemented_funcs

get_implemented_funcs() -> tuple[Callable[..., Any], ...]
Source code
270
271
def get_implemented_funcs(self) -> tuple[Callable[..., Any], ...]:
    return (self.scale, self.multi)

get_scale_args

get_scale_args(
    clip: VideoNode,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None,
    height: int | None = None,
    *funcs: Callable[..., Any],
    **kwargs: Any
) -> KwargsT
Source code
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
@inject_kwargs_params
def get_scale_args(
    self, clip: vs.VideoNode, shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None, height: int | None = None,
    *funcs: Callable[..., Any], **kwargs: Any
) -> KwargsT:
    return (
        dict(
            src_top=shift[0],
            src_left=shift[1]
        )
        | self.get_clean_kwargs(*funcs)
        | dict(width=width, height=height)
        | kwargs
    )

kernel_radius

kernel_radius() -> int
Source code
195
196
197
@inject_self.cached.property
def kernel_radius(self) -> int:
    return _default_kernel_radius(__class__, self)  # type: ignore

multi

multi(
    clip: VideoNode,
    multi: float = 2,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
239
240
241
242
243
244
245
246
247
248
249
250
251
252
@inject_self.cached
def multi(
    self, clip: vs.VideoNode, multi: float = 2, shift: tuple[TopShift, LeftShift] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    assert check_variable_resolution(clip, self.multi)

    dst_width, dst_height = ceil(clip.width * multi), ceil(clip.height * multi)

    if max(dst_width, dst_height) <= 0.0:
        raise CustomValueError(
            'Multiplying the resolution by "multi" must result in a positive resolution!', self.multi, multi
        )

    return self.scale(clip, dst_width, dst_height, shift, **kwargs)

pretty_string

pretty_string() -> str
Source code
202
203
204
205
206
207
208
209
210
211
212
213
214
@inject_self.cached.property
def pretty_string(self) -> str:
    attrs = {}

    if hasattr(self, 'b'):
        attrs.update(b=self.b, c=self.c)
    elif hasattr(self, 'taps'):
        attrs['taps'] = self.taps

    if hasattr(self, 'kwargs'):
        attrs.update(self.kwargs)

    return f"{self.__class__.__name__}{' (' + ', '.join(f'{k}={v}' for k, v in attrs.items()) + ')' if attrs else ''}"

scale

scale(
    clip: VideoNode,
    width: int | None = None,
    height: int | None = None,
    shift: tuple[float, float] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
@inject_self.init_kwargs.clean
def scale(  # type:ignore
    self, clip: vs.VideoNode, width: int | None = None, height: int | None = None,
    shift: tuple[float, float] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    try:
        from vsmlrt import Backend
    except ModuleNotFoundError as e:
        raise DependencyNotFoundError(self.__class__, e)

    width, height = self._wh_norm(clip, width, height)

    wclip = clip

    assert check_variable_format(clip, self.scale)

    matrix = self.matrix
    is_gray = clip.format.color_family is vs.GRAY
    planes = 0 if is_gray else None

    _static_args = kwargs.pop('_static_args', self._static_args)
    force = _static_args.pop('force', False)
    do_scale = _static_args.get('scale') > 1

    bkwargs = self._bkwargs.copy()

    dynamic_shapes = self.dynamic_shape or (0 in (clip.width, clip.height)) or not bkwargs.get('static_shape', True)

    kwargs.update(tiles=self.tiles, tilesize=self.tilesize, overlap=self.overlap)

    if dynamic_shapes and self._backend is Backend.TRT:
        bkwargs.update(static_shape=False, opt_shapes=(64, 64), max_shapes=self.max_shapes)

    if (is_upscale := width > clip.width or height > clip.width or force):
        model = self._model

        if clip.format.color_family is vs.YUV:
            if not matrix:
                matrix = Matrix.from_param_or_video(matrix or self.matrix, clip, False, self.__class__)

            wclip = self._kernel.resample(wclip, vs.RGBH if self.fp16 else vs.RGBS, Matrix.RGB, matrix)
        else:
            wclip = depth(wclip, 16 if self.fp16 else 32, vs.FLOAT)

            if is_gray and model != 0:
                wclip = wclip.std.ShufflePlanes(0, vs.RGB)

        assert wclip.format

        if wclip.format.color_family is vs.RGB:
            if model == 0:
                model = 1

        wclip = Waifu2xResizeHelper(
            wclip, width, height, planes, is_gray, self._scaler,
            do_scale and self._model == Waifu2x.Cunet._model,
            KwargsT(
                **_static_args, model=model,
                preprocess=False, **kwargs
            ), self.max_instances, self._backend, bkwargs  # type: ignore[arg-type]
        ).eval_clip()

    return self._finish_scale(wclip, clip, width, height, shift, matrix, is_upscale)

UpConv7Photo dataclass

UpConv7Photo(
    cuda: bool | Literal["trt"] | None = None,
    num_streams: int | None = None,
    fp16: bool = True,
    device_id: int = 0,
    matrix: MatrixT | None = None,
    tiles: int | tuple[int, int] | None = None,
    tilesize: int | tuple[int, int] | None = None,
    overlap: int | tuple[int, int] | None = None,
    backend_kwargs: KwargsT | None = None,
    dynamic_shape: bool | None = None,
    max_shapes: tuple[int, int] | None = (1936, 1088),
    max_instances: int = 2,
    *,
    kernel: KernelT | None = None,
    scaler: ScalerT | None = None,
    shifter: KernelT | None = None
)

Bases: BaseWaifu2x

backend_kwargs class-attribute instance-attribute

backend_kwargs: KwargsT | None = None

Kwargs passed to create the backend instance.

cuda class-attribute instance-attribute

cuda: bool | Literal['trt'] | None = None

Whether to run this on cpu, gpu, or use trt technology. None will pick the fastest automatically.

device_id class-attribute instance-attribute

device_id: int = 0

Id of the cuda device to use.

dynamic_shape class-attribute instance-attribute

dynamic_shape: bool | None = None

Use a single model for 0-max_shapes resolutions. None to automatically detect it. Will be True when previewing and TRT is available.

fp16 class-attribute instance-attribute

fp16: bool = True

Whether to use float16 precision if available.

func instance-attribute

func = func

kernel class-attribute instance-attribute

kernel: KernelT | None = field(default=None, kw_only=True)

Base kernel to be used for certain scaling/shifting/resampling operations. Must be specified and defaults to catrom

kwargs instance-attribute

kwargs = kwargs

matrix class-attribute instance-attribute

matrix: MatrixT | None = None

Input clip's matrix. Set only if necessary.

max_instances class-attribute instance-attribute

max_instances: int = 2

Maximum instances to spawn when scaling a variable resolution clip.

max_shapes class-attribute instance-attribute

max_shapes: tuple[int, int] | None = (1936, 1088)

Max shape for a dynamic model when using TRT and variable resolution clip. This can be overridden if the frame size is bigger.

num_streams class-attribute instance-attribute

num_streams: int | None = None

Number of gpu streams for the model.

overlap class-attribute instance-attribute

overlap: int | tuple[int, int] | None = None

Overlap for reducing blocking artifacts between tile borders.

scale_function instance-attribute

scale_function: GenericVSFunction

Scale function called internally when scaling

scaler class-attribute instance-attribute

scaler: ScalerT | None = field(default=None, kw_only=True)

Scaler used for scaling operations. Defaults to kernel.

shifter class-attribute instance-attribute

shifter: KernelT | None = field(default=None, kw_only=True)

Kernel used for shifting operations. Defaults to kernel.

tiles class-attribute instance-attribute

tiles: int | tuple[int, int] | None = None

Process in separate tiles instead of the whole frame. Use if [V]RAM limited.

tilesize class-attribute instance-attribute

tilesize: int | tuple[int, int] | None = None

Manually specify the size of a single tile.

ensure_obj classmethod

ensure_obj(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> BaseScalerT
Source code
186
187
188
189
190
191
192
193
@classmethod
def ensure_obj(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> BaseScalerT:
    return _base_ensure_obj(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

ensure_scaler

ensure_scaler(scaler: ScalerT) -> Scaler
Source code
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
def ensure_scaler(self, scaler: ScalerT) -> Scaler:
    from dataclasses import is_dataclass, replace

    scaler_obj = Scaler.ensure_obj(scaler, self.__class__)

    if is_dataclass(scaler_obj):
        from inspect import Signature  #type: ignore[unreachable]

        kwargs = dict[str, ScalerT]()

        init_keys = Signature.from_callable(scaler_obj.__init__).parameters.keys()

        if 'kernel' in init_keys:
            kwargs.update(kernel=self.kernel or scaler_obj.kernel)

        if 'scaler' in init_keys:
            kwargs.update(scaler=self.scaler or scaler_obj.scaler)

        if 'shifter' in init_keys:
            kwargs.update(shifter=self.shifter or scaler_obj.shifter)

        if kwargs:
            scaler_obj = replace(scaler_obj, **kwargs)

    return scaler_obj

from_param classmethod

from_param(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> type[BaseScalerT]
Source code
177
178
179
180
181
182
183
184
@classmethod
def from_param(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> type[BaseScalerT]:
    return _base_from_param(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

get_clean_kwargs

get_clean_kwargs(*funcs: Callable[..., Any] | None) -> KwargsT
Source code
199
200
def get_clean_kwargs(self, *funcs: Callable[..., Any] | None) -> KwargsT:
    return _clean_self_kwargs(funcs, self)

get_implemented_funcs

get_implemented_funcs() -> tuple[Callable[..., Any], ...]
Source code
270
271
def get_implemented_funcs(self) -> tuple[Callable[..., Any], ...]:
    return (self.scale, self.multi)

get_scale_args

get_scale_args(
    clip: VideoNode,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None,
    height: int | None = None,
    *funcs: Callable[..., Any],
    **kwargs: Any
) -> KwargsT
Source code
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
@inject_kwargs_params
def get_scale_args(
    self, clip: vs.VideoNode, shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None, height: int | None = None,
    *funcs: Callable[..., Any], **kwargs: Any
) -> KwargsT:
    return (
        dict(
            src_top=shift[0],
            src_left=shift[1]
        )
        | self.get_clean_kwargs(*funcs)
        | dict(width=width, height=height)
        | kwargs
    )

kernel_radius

kernel_radius() -> int
Source code
195
196
197
@inject_self.cached.property
def kernel_radius(self) -> int:
    return _default_kernel_radius(__class__, self)  # type: ignore

multi

multi(
    clip: VideoNode,
    multi: float = 2,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
239
240
241
242
243
244
245
246
247
248
249
250
251
252
@inject_self.cached
def multi(
    self, clip: vs.VideoNode, multi: float = 2, shift: tuple[TopShift, LeftShift] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    assert check_variable_resolution(clip, self.multi)

    dst_width, dst_height = ceil(clip.width * multi), ceil(clip.height * multi)

    if max(dst_width, dst_height) <= 0.0:
        raise CustomValueError(
            'Multiplying the resolution by "multi" must result in a positive resolution!', self.multi, multi
        )

    return self.scale(clip, dst_width, dst_height, shift, **kwargs)

pretty_string

pretty_string() -> str
Source code
202
203
204
205
206
207
208
209
210
211
212
213
214
@inject_self.cached.property
def pretty_string(self) -> str:
    attrs = {}

    if hasattr(self, 'b'):
        attrs.update(b=self.b, c=self.c)
    elif hasattr(self, 'taps'):
        attrs['taps'] = self.taps

    if hasattr(self, 'kwargs'):
        attrs.update(self.kwargs)

    return f"{self.__class__.__name__}{' (' + ', '.join(f'{k}={v}' for k, v in attrs.items()) + ')' if attrs else ''}"

scale

scale(
    clip: VideoNode,
    width: int | None = None,
    height: int | None = None,
    shift: tuple[float, float] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
@inject_self.init_kwargs.clean
def scale(  # type:ignore
    self, clip: vs.VideoNode, width: int | None = None, height: int | None = None,
    shift: tuple[float, float] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    try:
        from vsmlrt import Backend
    except ModuleNotFoundError as e:
        raise DependencyNotFoundError(self.__class__, e)

    width, height = self._wh_norm(clip, width, height)

    wclip = clip

    assert check_variable_format(clip, self.scale)

    matrix = self.matrix
    is_gray = clip.format.color_family is vs.GRAY
    planes = 0 if is_gray else None

    _static_args = kwargs.pop('_static_args', self._static_args)
    force = _static_args.pop('force', False)
    do_scale = _static_args.get('scale') > 1

    bkwargs = self._bkwargs.copy()

    dynamic_shapes = self.dynamic_shape or (0 in (clip.width, clip.height)) or not bkwargs.get('static_shape', True)

    kwargs.update(tiles=self.tiles, tilesize=self.tilesize, overlap=self.overlap)

    if dynamic_shapes and self._backend is Backend.TRT:
        bkwargs.update(static_shape=False, opt_shapes=(64, 64), max_shapes=self.max_shapes)

    if (is_upscale := width > clip.width or height > clip.width or force):
        model = self._model

        if clip.format.color_family is vs.YUV:
            if not matrix:
                matrix = Matrix.from_param_or_video(matrix or self.matrix, clip, False, self.__class__)

            wclip = self._kernel.resample(wclip, vs.RGBH if self.fp16 else vs.RGBS, Matrix.RGB, matrix)
        else:
            wclip = depth(wclip, 16 if self.fp16 else 32, vs.FLOAT)

            if is_gray and model != 0:
                wclip = wclip.std.ShufflePlanes(0, vs.RGB)

        assert wclip.format

        if wclip.format.color_family is vs.RGB:
            if model == 0:
                model = 1

        wclip = Waifu2xResizeHelper(
            wclip, width, height, planes, is_gray, self._scaler,
            do_scale and self._model == Waifu2x.Cunet._model,
            KwargsT(
                **_static_args, model=model,
                preprocess=False, **kwargs
            ), self.max_instances, self._backend, bkwargs  # type: ignore[arg-type]
        ).eval_clip()

    return self._finish_scale(wclip, clip, width, height, shift, matrix, is_upscale)

UpResNet10 dataclass

UpResNet10(
    cuda: bool | Literal["trt"] | None = None,
    num_streams: int | None = None,
    fp16: bool = True,
    device_id: int = 0,
    matrix: MatrixT | None = None,
    tiles: int | tuple[int, int] | None = None,
    tilesize: int | tuple[int, int] | None = None,
    overlap: int | tuple[int, int] | None = None,
    backend_kwargs: KwargsT | None = None,
    dynamic_shape: bool | None = None,
    max_shapes: tuple[int, int] | None = (1936, 1088),
    max_instances: int = 2,
    *,
    kernel: KernelT | None = None,
    scaler: ScalerT | None = None,
    shifter: KernelT | None = None
)

Bases: BaseWaifu2x

backend_kwargs class-attribute instance-attribute

backend_kwargs: KwargsT | None = None

Kwargs passed to create the backend instance.

cuda class-attribute instance-attribute

cuda: bool | Literal['trt'] | None = None

Whether to run this on cpu, gpu, or use trt technology. None will pick the fastest automatically.

device_id class-attribute instance-attribute

device_id: int = 0

Id of the cuda device to use.

dynamic_shape class-attribute instance-attribute

dynamic_shape: bool | None = None

Use a single model for 0-max_shapes resolutions. None to automatically detect it. Will be True when previewing and TRT is available.

fp16 class-attribute instance-attribute

fp16: bool = True

Whether to use float16 precision if available.

func instance-attribute

func = func

kernel class-attribute instance-attribute

kernel: KernelT | None = field(default=None, kw_only=True)

Base kernel to be used for certain scaling/shifting/resampling operations. Must be specified and defaults to catrom

kwargs instance-attribute

kwargs = kwargs

matrix class-attribute instance-attribute

matrix: MatrixT | None = None

Input clip's matrix. Set only if necessary.

max_instances class-attribute instance-attribute

max_instances: int = 2

Maximum instances to spawn when scaling a variable resolution clip.

max_shapes class-attribute instance-attribute

max_shapes: tuple[int, int] | None = (1936, 1088)

Max shape for a dynamic model when using TRT and variable resolution clip. This can be overridden if the frame size is bigger.

num_streams class-attribute instance-attribute

num_streams: int | None = None

Number of gpu streams for the model.

overlap class-attribute instance-attribute

overlap: int | tuple[int, int] | None = None

Overlap for reducing blocking artifacts between tile borders.

scale_function instance-attribute

scale_function: GenericVSFunction

Scale function called internally when scaling

scaler class-attribute instance-attribute

scaler: ScalerT | None = field(default=None, kw_only=True)

Scaler used for scaling operations. Defaults to kernel.

shifter class-attribute instance-attribute

shifter: KernelT | None = field(default=None, kw_only=True)

Kernel used for shifting operations. Defaults to kernel.

tiles class-attribute instance-attribute

tiles: int | tuple[int, int] | None = None

Process in separate tiles instead of the whole frame. Use if [V]RAM limited.

tilesize class-attribute instance-attribute

tilesize: int | tuple[int, int] | None = None

Manually specify the size of a single tile.

ensure_obj classmethod

ensure_obj(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> BaseScalerT
Source code
186
187
188
189
190
191
192
193
@classmethod
def ensure_obj(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> BaseScalerT:
    return _base_ensure_obj(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

ensure_scaler

ensure_scaler(scaler: ScalerT) -> Scaler
Source code
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
def ensure_scaler(self, scaler: ScalerT) -> Scaler:
    from dataclasses import is_dataclass, replace

    scaler_obj = Scaler.ensure_obj(scaler, self.__class__)

    if is_dataclass(scaler_obj):
        from inspect import Signature  #type: ignore[unreachable]

        kwargs = dict[str, ScalerT]()

        init_keys = Signature.from_callable(scaler_obj.__init__).parameters.keys()

        if 'kernel' in init_keys:
            kwargs.update(kernel=self.kernel or scaler_obj.kernel)

        if 'scaler' in init_keys:
            kwargs.update(scaler=self.scaler or scaler_obj.scaler)

        if 'shifter' in init_keys:
            kwargs.update(shifter=self.shifter or scaler_obj.shifter)

        if kwargs:
            scaler_obj = replace(scaler_obj, **kwargs)

    return scaler_obj

from_param classmethod

from_param(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> type[BaseScalerT]
Source code
177
178
179
180
181
182
183
184
@classmethod
def from_param(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> type[BaseScalerT]:
    return _base_from_param(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

get_clean_kwargs

get_clean_kwargs(*funcs: Callable[..., Any] | None) -> KwargsT
Source code
199
200
def get_clean_kwargs(self, *funcs: Callable[..., Any] | None) -> KwargsT:
    return _clean_self_kwargs(funcs, self)

get_implemented_funcs

get_implemented_funcs() -> tuple[Callable[..., Any], ...]
Source code
270
271
def get_implemented_funcs(self) -> tuple[Callable[..., Any], ...]:
    return (self.scale, self.multi)

get_scale_args

get_scale_args(
    clip: VideoNode,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None,
    height: int | None = None,
    *funcs: Callable[..., Any],
    **kwargs: Any
) -> KwargsT
Source code
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
@inject_kwargs_params
def get_scale_args(
    self, clip: vs.VideoNode, shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None, height: int | None = None,
    *funcs: Callable[..., Any], **kwargs: Any
) -> KwargsT:
    return (
        dict(
            src_top=shift[0],
            src_left=shift[1]
        )
        | self.get_clean_kwargs(*funcs)
        | dict(width=width, height=height)
        | kwargs
    )

kernel_radius

kernel_radius() -> int
Source code
195
196
197
@inject_self.cached.property
def kernel_radius(self) -> int:
    return _default_kernel_radius(__class__, self)  # type: ignore

multi

multi(
    clip: VideoNode,
    multi: float = 2,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
239
240
241
242
243
244
245
246
247
248
249
250
251
252
@inject_self.cached
def multi(
    self, clip: vs.VideoNode, multi: float = 2, shift: tuple[TopShift, LeftShift] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    assert check_variable_resolution(clip, self.multi)

    dst_width, dst_height = ceil(clip.width * multi), ceil(clip.height * multi)

    if max(dst_width, dst_height) <= 0.0:
        raise CustomValueError(
            'Multiplying the resolution by "multi" must result in a positive resolution!', self.multi, multi
        )

    return self.scale(clip, dst_width, dst_height, shift, **kwargs)

pretty_string

pretty_string() -> str
Source code
202
203
204
205
206
207
208
209
210
211
212
213
214
@inject_self.cached.property
def pretty_string(self) -> str:
    attrs = {}

    if hasattr(self, 'b'):
        attrs.update(b=self.b, c=self.c)
    elif hasattr(self, 'taps'):
        attrs['taps'] = self.taps

    if hasattr(self, 'kwargs'):
        attrs.update(self.kwargs)

    return f"{self.__class__.__name__}{' (' + ', '.join(f'{k}={v}' for k, v in attrs.items()) + ')' if attrs else ''}"

scale

scale(
    clip: VideoNode,
    width: int | None = None,
    height: int | None = None,
    shift: tuple[float, float] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
@inject_self.init_kwargs.clean
def scale(  # type:ignore
    self, clip: vs.VideoNode, width: int | None = None, height: int | None = None,
    shift: tuple[float, float] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    try:
        from vsmlrt import Backend
    except ModuleNotFoundError as e:
        raise DependencyNotFoundError(self.__class__, e)

    width, height = self._wh_norm(clip, width, height)

    wclip = clip

    assert check_variable_format(clip, self.scale)

    matrix = self.matrix
    is_gray = clip.format.color_family is vs.GRAY
    planes = 0 if is_gray else None

    _static_args = kwargs.pop('_static_args', self._static_args)
    force = _static_args.pop('force', False)
    do_scale = _static_args.get('scale') > 1

    bkwargs = self._bkwargs.copy()

    dynamic_shapes = self.dynamic_shape or (0 in (clip.width, clip.height)) or not bkwargs.get('static_shape', True)

    kwargs.update(tiles=self.tiles, tilesize=self.tilesize, overlap=self.overlap)

    if dynamic_shapes and self._backend is Backend.TRT:
        bkwargs.update(static_shape=False, opt_shapes=(64, 64), max_shapes=self.max_shapes)

    if (is_upscale := width > clip.width or height > clip.width or force):
        model = self._model

        if clip.format.color_family is vs.YUV:
            if not matrix:
                matrix = Matrix.from_param_or_video(matrix or self.matrix, clip, False, self.__class__)

            wclip = self._kernel.resample(wclip, vs.RGBH if self.fp16 else vs.RGBS, Matrix.RGB, matrix)
        else:
            wclip = depth(wclip, 16 if self.fp16 else 32, vs.FLOAT)

            if is_gray and model != 0:
                wclip = wclip.std.ShufflePlanes(0, vs.RGB)

        assert wclip.format

        if wclip.format.color_family is vs.RGB:
            if model == 0:
                model = 1

        wclip = Waifu2xResizeHelper(
            wclip, width, height, planes, is_gray, self._scaler,
            do_scale and self._model == Waifu2x.Cunet._model,
            KwargsT(
                **_static_args, model=model,
                preprocess=False, **kwargs
            ), self.max_instances, self._backend, bkwargs  # type: ignore[arg-type]
        ).eval_clip()

    return self._finish_scale(wclip, clip, width, height, shift, matrix, is_upscale)

ensure_obj classmethod

ensure_obj(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> BaseScalerT
Source code
186
187
188
189
190
191
192
193
@classmethod
def ensure_obj(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> BaseScalerT:
    return _base_ensure_obj(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

ensure_scaler

ensure_scaler(scaler: ScalerT) -> Scaler
Source code
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
def ensure_scaler(self, scaler: ScalerT) -> Scaler:
    from dataclasses import is_dataclass, replace

    scaler_obj = Scaler.ensure_obj(scaler, self.__class__)

    if is_dataclass(scaler_obj):
        from inspect import Signature  #type: ignore[unreachable]

        kwargs = dict[str, ScalerT]()

        init_keys = Signature.from_callable(scaler_obj.__init__).parameters.keys()

        if 'kernel' in init_keys:
            kwargs.update(kernel=self.kernel or scaler_obj.kernel)

        if 'scaler' in init_keys:
            kwargs.update(scaler=self.scaler or scaler_obj.scaler)

        if 'shifter' in init_keys:
            kwargs.update(shifter=self.shifter or scaler_obj.shifter)

        if kwargs:
            scaler_obj = replace(scaler_obj, **kwargs)

    return scaler_obj

from_param classmethod

from_param(
    scaler: str | type[BaseScalerT] | BaseScalerT | None = None,
    /,
    func_except: FuncExceptT | None = None,
) -> type[BaseScalerT]
Source code
177
178
179
180
181
182
183
184
@classmethod
def from_param(
    cls: type[BaseScalerT], scaler: str | type[BaseScalerT] | BaseScalerT | None = None, /,
    func_except: FuncExceptT | None = None
) -> type[BaseScalerT]:
    return _base_from_param(
        cls, (mro := cls.mro())[mro.index(BaseScaler) - 1], scaler, cls._err_class, [], func_except
    )

get_clean_kwargs

get_clean_kwargs(*funcs: Callable[..., Any] | None) -> KwargsT
Source code
199
200
def get_clean_kwargs(self, *funcs: Callable[..., Any] | None) -> KwargsT:
    return _clean_self_kwargs(funcs, self)

get_implemented_funcs

get_implemented_funcs() -> tuple[Callable[..., Any], ...]
Source code
270
271
def get_implemented_funcs(self) -> tuple[Callable[..., Any], ...]:
    return (self.scale, self.multi)

get_scale_args

get_scale_args(
    clip: VideoNode,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None,
    height: int | None = None,
    *funcs: Callable[..., Any],
    **kwargs: Any
) -> KwargsT
Source code
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
@inject_kwargs_params
def get_scale_args(
    self, clip: vs.VideoNode, shift: tuple[TopShift, LeftShift] = (0, 0),
    width: int | None = None, height: int | None = None,
    *funcs: Callable[..., Any], **kwargs: Any
) -> KwargsT:
    return (
        dict(
            src_top=shift[0],
            src_left=shift[1]
        )
        | self.get_clean_kwargs(*funcs)
        | dict(width=width, height=height)
        | kwargs
    )

kernel_radius

kernel_radius() -> int
Source code
195
196
197
@inject_self.cached.property
def kernel_radius(self) -> int:
    return _default_kernel_radius(__class__, self)  # type: ignore

multi

multi(
    clip: VideoNode,
    multi: float = 2,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
239
240
241
242
243
244
245
246
247
248
249
250
251
252
@inject_self.cached
def multi(
    self, clip: vs.VideoNode, multi: float = 2, shift: tuple[TopShift, LeftShift] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    assert check_variable_resolution(clip, self.multi)

    dst_width, dst_height = ceil(clip.width * multi), ceil(clip.height * multi)

    if max(dst_width, dst_height) <= 0.0:
        raise CustomValueError(
            'Multiplying the resolution by "multi" must result in a positive resolution!', self.multi, multi
        )

    return self.scale(clip, dst_width, dst_height, shift, **kwargs)

pretty_string

pretty_string() -> str
Source code
202
203
204
205
206
207
208
209
210
211
212
213
214
@inject_self.cached.property
def pretty_string(self) -> str:
    attrs = {}

    if hasattr(self, 'b'):
        attrs.update(b=self.b, c=self.c)
    elif hasattr(self, 'taps'):
        attrs['taps'] = self.taps

    if hasattr(self, 'kwargs'):
        attrs.update(self.kwargs)

    return f"{self.__class__.__name__}{' (' + ', '.join(f'{k}={v}' for k, v in attrs.items()) + ')' if attrs else ''}"

scale

scale(
    clip: VideoNode,
    width: int | None = None,
    height: int | None = None,
    shift: tuple[float, float] = (0, 0),
    **kwargs: Any
) -> VideoNode
Source code
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
@inject_self.init_kwargs.clean
def scale(  # type:ignore
    self, clip: vs.VideoNode, width: int | None = None, height: int | None = None,
    shift: tuple[float, float] = (0, 0), **kwargs: Any
) -> vs.VideoNode:
    try:
        from vsmlrt import Backend
    except ModuleNotFoundError as e:
        raise DependencyNotFoundError(self.__class__, e)

    width, height = self._wh_norm(clip, width, height)

    wclip = clip

    assert check_variable_format(clip, self.scale)

    matrix = self.matrix
    is_gray = clip.format.color_family is vs.GRAY
    planes = 0 if is_gray else None

    _static_args = kwargs.pop('_static_args', self._static_args)
    force = _static_args.pop('force', False)
    do_scale = _static_args.get('scale') > 1

    bkwargs = self._bkwargs.copy()

    dynamic_shapes = self.dynamic_shape or (0 in (clip.width, clip.height)) or not bkwargs.get('static_shape', True)

    kwargs.update(tiles=self.tiles, tilesize=self.tilesize, overlap=self.overlap)

    if dynamic_shapes and self._backend is Backend.TRT:
        bkwargs.update(static_shape=False, opt_shapes=(64, 64), max_shapes=self.max_shapes)

    if (is_upscale := width > clip.width or height > clip.width or force):
        model = self._model

        if clip.format.color_family is vs.YUV:
            if not matrix:
                matrix = Matrix.from_param_or_video(matrix or self.matrix, clip, False, self.__class__)

            wclip = self._kernel.resample(wclip, vs.RGBH if self.fp16 else vs.RGBS, Matrix.RGB, matrix)
        else:
            wclip = depth(wclip, 16 if self.fp16 else 32, vs.FLOAT)

            if is_gray and model != 0:
                wclip = wclip.std.ShufflePlanes(0, vs.RGB)

        assert wclip.format

        if wclip.format.color_family is vs.RGB:
            if model == 0:
                model = 1

        wclip = Waifu2xResizeHelper(
            wclip, width, height, planes, is_gray, self._scaler,
            do_scale and self._model == Waifu2x.Cunet._model,
            KwargsT(
                **_static_args, model=model,
                preprocess=False, **kwargs
            ), self.max_instances, self._backend, bkwargs  # type: ignore[arg-type]
        ).eval_clip()

    return self._finish_scale(wclip, clip, width, height, shift, matrix, is_upscale)

Waifu2xCropHelper

Bases: ProcessVariableClip[tuple[int, int, int, int, int, int]]

get_key

get_key(frame: VideoFrame) -> tuple[int, int, int, int, int, int]
Source code
196
197
def get_key(self, frame: vs.VideoFrame) -> tuple[int, int, int, int, int, int]:
    return (frame.width, frame.height, *get_prop(frame, '_PadValues', list))

normalize

normalize(
    clip: VideoNode, cast_to: tuple[int, int, int, int, int, int]
) -> VideoNode
Source code
199
200
201
202
203
204
def normalize(self, clip: vs.VideoNode, cast_to: tuple[int, int, int, int, int, int]) -> vs.VideoNode:
    width, height, *padding = cast_to

    return ProcessVariableResClip.normalize(
        self, clip, (width, height)).std.Crop(*(p * 2 for p in padding)  # type: ignore[arg-type]
    )

Waifu2xPadHelper

Bases: ProcessVariableResClip

normalize

normalize(clip: VideoNode, cast_to: tuple[int, int]) -> VideoNode
Source code
189
190
191
192
def normalize(self, clip: vs.VideoNode, cast_to: tuple[int, int]) -> vs.VideoNode:
    padding = padder.mod_padding(cast_to)

    return padder.MIRROR(super().normalize(clip, cast_to), *padding).std.SetFrameProp('_PadValues', padding)

Waifu2xResizeHelper

Waifu2xResizeHelper(
    clip: VideoNode,
    width: int,
    height: int,
    planes: PlanesT,
    is_gray: bool,
    scaler: Scaler,
    do_padding: bool,
    w2x_kwargs: KwargsT,
    w2x_cache_size: int,
    backend: type,
    backend_kwargs: KwargsT,
)

Bases: ProcessVariableResClip

Source code
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
def __init__(
    self, clip: vs.VideoNode, width: int, height: int, planes: PlanesT, is_gray: bool,
    scaler: Scaler, do_padding: bool, w2x_kwargs: KwargsT, w2x_cache_size: int,
    backend: type, backend_kwargs: KwargsT
) -> None:
    super().__init__(clip, (width, height))

    self.width = width
    self.height = height
    self.planes = planes
    self.is_gray = is_gray
    self.scaler = scaler
    self.do_padding = do_padding
    self.w2x_kwargs = w2x_kwargs
    self.w2x_cache_size = w2x_cache_size
    self.backend = backend
    self.backend_kwargs = backend_kwargs.copy()

backend instance-attribute

backend = backend

backend_kwargs instance-attribute

backend_kwargs = copy()

do_padding instance-attribute

do_padding = do_padding

height instance-attribute

height = height

is_gray instance-attribute

is_gray = is_gray

planes instance-attribute

planes = planes

scaler instance-attribute

scaler = scaler

w2x_cache_size instance-attribute

w2x_cache_size = w2x_cache_size

w2x_kwargs instance-attribute

w2x_kwargs = w2x_kwargs

width instance-attribute

width = width

normalize

normalize(wclip: VideoNode, cast_to: tuple[int, int]) -> VideoNode
Source code
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
def normalize(self, wclip: vs.VideoNode, cast_to: tuple[int, int]) -> vs.VideoNode:
    mult = max(int(log2(ceil(size))) for size in (self.width / cast_to[0], self.height / cast_to[1]))

    try:
        wclip = limiter(wclip, func=self.__class__)
    except vs.Error:
        wclip = norm_expr(wclip, 'x 0 1 clamp', planes=self.planes)

    for _ in range(mult):
        if self.do_padding:
            wclip = Waifu2xPadHelper.from_clip(wclip)

        wclip = Waifu2xScaleHelper(
            wclip, self.backend, self.backend_kwargs, self.w2x_kwargs, self.w2x_cache_size
        ).eval_clip()

        if self.do_padding:
            cropped = Waifu2xCropHelper.from_clip(wclip)

            try:
                wclip = norm_expr(cropped, 'x 0.5 255 / + 0 1 clamp', planes=self.planes)
            except RuntimeError:
                wclip = norm_expr(depth(cropped, 32), 'x 0.5 255 / + 0 max 1 min', planes=self.planes)

    return wclip

process

process(wclip: VideoNode) -> VideoNode
Source code
274
275
276
277
278
def process(self, wclip: vs.VideoNode) -> vs.VideoNode:
    if self.is_gray:
        wclip = wclip.std.ShufflePlanes(0, vs.GRAY)

    return self.scaler.scale(wclip, self.width, self.height)

Waifu2xScaleHelper

Waifu2xScaleHelper(
    clip: VideoNode,
    backend: type,
    backend_kwargs: KwargsT,
    kwargs: KwargsT,
    cache_size: int,
)

Bases: ProcessVariableResClip

Source code
208
209
210
211
212
213
214
215
def __init__(
    self, clip: vs.VideoNode, backend: type, backend_kwargs: KwargsT, kwargs: KwargsT, cache_size: int
) -> None:
    super().__init__(clip, cache_size=cache_size)

    self.kwargs = kwargs
    self.backend = backend
    self.backend_kwargs = backend_kwargs

backend instance-attribute

backend = backend

backend_kwargs instance-attribute

backend_kwargs = backend_kwargs

kwargs instance-attribute

kwargs = kwargs

normalize

normalize(clip: VideoNode, cast_to: tuple[int, int]) -> VideoNode
Source code
217
218
219
220
221
222
223
224
225
226
def normalize(self, clip: vs.VideoNode, cast_to: tuple[int, int]) -> vs.VideoNode:
    from vsmlrt import Waifu2x as MlrtWaifu2x  # type: ignore

    if (max_shapes := self.backend_kwargs.get('max_shapes', None)):
        if cast_to[0] > max_shapes[0] or cast_to[1] > max_shapes[1]:
            self.backend_kwargs.update(max_shapes=cast_to)

    return MlrtWaifu2x(  # type: ignore
        super().normalize(clip, cast_to), backend=self.backend(**self.backend_kwargs), **self.kwargs
    )