Skip to main content

nativeres

nativeres is a set of descale analysis tools for VapourSynth.

It combines and supersedes the following tools:

The package provides:

  • A CLI for frame analysis
  • A Python API for VapourSynth scripts and tooling
  • An optional VSView plugin

What it does

nativeres helps answer three common descale questions:

  • getnative: What native resolution was this frame likely upscaled from?
  • getscaler: Which scaler most likely produced this upscale?
  • getfreq: Does the frame's frequency distribution show likely scaling artifacts or native-resolution clues?

Installation

# Install the package with `pip`
pip install nativeres
# Or with `uv`
uv tool install nativeres

VSView plugin

This repository also contains a VSView plugin package.

pip install nativeres[plugin]
# Or with uv
uv add nativeres[plugin]

The plugin registers as a VSView tool panel and tool dock under Native Resolution.

Usage can be found in the plugin README.

Usage

CLI

nativeres accepts regular media files, images, and VapourSynth scripts (.vpy / .py). For scripts, the first VapourSynth output is used.

  • Displays a plot to determine the native resolution height for the frame 15000 with the Bilinear kernel:

    nativeres getnative file.m2ts --frame 15000 --dim-mode height --kernel bilinear
    

    nativeres getnative

    Right-click the plot to open the context menu, where you can reset zoom and copy or export the plot as PNG, SVG, JSON, or CSV.

  • Displays a table showing the errors of the inverse scalers at height 800 for frame 15000.

    nativeres getscaler file.m2ts 800 --frame 15000 --dim-mode height
    

    nativeres getscaler

  • Compute and display a DCT-based frequency plot for the selected frame.

    nativeres getfreq file.m2ts --frame 15000
    

    nativeres getfreq

    The frequency plot uses the same right-click context menu for reset zoom plus copy/export actions.

Python

from nativeres import getnative
from vskernels import Bilinear

clip = ...  # Your VapourSynth clip

results = getnative(
    clip,
    frame_num=15000,
    dimensions=((clip.width, h) for h in range(540, 901)),
    kernel=Bilinear(),
)

best = min(results, key=lambda result: result.error)
print(best.dim.height, best.error)

CLI Reference

Main help:

nativeres --help

getnative help:

nativeres getnative --help

getscaler help:

nativeres getscaler --help

getfreq help:

nativeres getfreq --help

Python API

function getnative

getnative(
    clip: VideoNode,
    frame_num: int,
    dimensions: Iterable[tuple[float, float]],
    kernel: ComplexKernelLike,
    crop: tuple[LeftCrop, RightCrop, TopCrop, BottomCrop] | None = None,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    metric_mode: MetricMode = 'MAE',
    borders_aware: bool | int | tuple[LeftCrop, RightCrop, TopCrop, BottomCrop] = 8,
    progress_cb: Callable[[int, int], None] | None = None,
    func: FuncExcept | None = None,
    **kwargs: Any
) -> list[GetNativeResult]

Determine the best (fractional) native resolution for a selected frame.

This checks a list of candidate resolutions by descaling the selected frame using kernel and comparing the result to the source frame using metric_mode.

Args:

  • clip: Source clip.
  • frame_num: Frame index in clip to evaluate.
  • dimensions: Iterable of candidate resolutions to test. Each item may be a (width, height) tuple.
  • kernel: Kernel used to perform each descale attempt.
  • crop: Optional crop to apply before descaling. Aspect ratio is preserved.
  • shift: Optional pixel shift applied during descaling: (top_shift, left_shift).
  • metric_mode: Error metric to use: "MSE", "MAE", or "RMSE".
  • borders_aware: Amount (or crop tuple) to ignore at image borders to avoid edge noise when computing the metric.
  • progress_cb: Optional progress callback called as progress_cb(current, total).
  • func: Function returned for custom error handling.
  • kwargs: Additional arguments passed to the Rescale class.

Returns: A list of GetNativeResult items. Each item contains the tested fractional resolution (dim) and its associated error.


function getscaler

getscaler(
    clip: VideoNode,
    frame_num: int,
    width: float,
    height: float,
    kernels: ComplexKernelLike | Sequence[ComplexKernelLike],
    base_width: int | None = None,
    base_height: int | None = None,
    crop: tuple[LeftCrop, RightCrop, TopCrop, BottomCrop] | None = None,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    metric_mode: MetricMode = 'MAE',
    mask: MaskLike | None = None,
    borders_aware: bool | int | tuple[LeftCrop, RightCrop, TopCrop, BottomCrop] = 8,
    func: FuncExcept | None = None,
    **kwargs: Any
)  list[GetScalerResult]

Find the best inverse scaler (kernel) for a given frame of a clip.

Each supplied kernel is tested by descaling the selected frame to the provided (width, height) and computing an error metric.

Args:

  • clip: Source clip.
  • frame_num: Frame index in clip to evaluate.
  • width: Width to be descaled to. If passed as a float, a fractional descale is performed.
  • height: Height to be descaled to. If passed as a float, a fractional descale is performed.
  • kernels: A single kernel or a sequence of kernels to evaluate.
  • base_width: Optional integer height to contain the clip within.
  • base_height: Optional integer width to contain the clip within.
  • crop: Optional crop to apply before descaling. Aspect ratio is preserved.
  • shift: Pixel shifts applied during descaling: (top_shift, left_shift).
  • metric_mode: Error metric to use: "MSE", "MAE", or "RMSE".
  • mask: Optional edge-detection mask to reduce noise influence on the metric.
  • borders_aware: Amount (or crop tuple) to ignore at image borders to avoid edge noise when computing the metric.
  • func: Function returned for custom error handling.
  • kwargs: Additional arguments passed to the Rescale class.

Returns: A list of GetScalerResult items. Each item contains the evaluated kernel and its associated error.


function get_descale_error

get_descale_error(
    clip: VideoNode,
    frame_num: int,
    width: float,
    height: float,
    kernel: ComplexKernelLike,
    base_width: int | None = None,
    base_height: int | None = None,
    crop: tuple[LeftCrop, RightCrop, TopCrop, BottomCrop] | None = None,
    shift: tuple[TopShift, LeftShift] = (0, 0),
    metric_mode: MetricMode = 'MAE',
    mask: MaskLike | None = None,
    borders_aware: bool | int | tuple[LeftCrop, RightCrop, TopCrop, BottomCrop] = 8,
    func: FuncExcept | None = None,
    **kwargs: Any
)  float

Compute the descale error for a selected frame using a specific kernel.

Args:

  • clip: Source clip.
  • frame_num: Frame index in clip to evaluate.
  • width: Width to be descaled to. If passed as a float, a fractional descale is performed.
  • height: Height to be descaled to. If passed as a float, a fractional descale is performed.
  • kernel: Kernel used for the descale operation.
  • base_width: Optional integer height to contain the clip within.
  • base_height: Optional integer width to contain the clip within.
  • crop: Optional crop to apply before descaling. Aspect ratio is preserved.
  • shift: Pixel shifts applied during descaling: (top_shift, left_shift).
  • metric_mode: Error metric to use: "MSE", "MAE", or "RMSE".
  • mask: Optional edge-detection mask to reduce noise influence on the metric.
  • borders_aware: Amount (or crop tuple) to ignore at image borders to avoid edge noise when computing the metric.
  • func: Function returned for custom error handling.
  • kwargs: Additional arguments passed to the Rescale class.

Returns: The computed error as a float. Lower values indicate a better descale match.


function get_dct_distribution

get_dct_distribution(
    clip: VideoNode,
    frame_num: int,
    cull_rate: float = 3.0,
    func: FuncExcept | None = None
)  tuple[NpFloatArray1D, NpFloatArray1D]

Calculate DCT frequency distribution for both horizontal and vertical dimensions of a selected frame.

Args:

  • clip: Source clip.
  • frame_num: Frame index in clip to analyze.
  • cull_rate: Cull rate for DCT coefficients.
  • func: Function returned for custom error handling.

Returns: A tuple of (dct_h, dct_v).


class GetNativeResult

Result for getnative, pairing a fractional resolution with an error metric.


class GetScalerResult

Result for getscaler, pairing a kernel with its error.


class ResolutionFrac

Fractional resolution expressed as floating-point width and height.

Notes

  • You should always visually verify the results on multiple frames before committing to a descale setup.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nativeres-0.3.0.tar.gz (39.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nativeres-0.3.0-py3-none-any.whl (24.1 kB view details)

Uploaded Python 3

File details

Details for the file nativeres-0.3.0.tar.gz.

File metadata

  • Download URL: nativeres-0.3.0.tar.gz
  • Upload date:
  • Size: 39.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for nativeres-0.3.0.tar.gz
Algorithm Hash digest
SHA256 479f265160f6a674bd33c152fc34a2402e5a8680b7b55fcc8e8696273f11fd5f
MD5 798a4e9481ff195179eac05087571eb2
BLAKE2b-256 20f4cf0e7731235a823286bf944b0df9eaff7baf5ddbcbc36fd9ab9214c2b434

See more details on using hashes here.

Provenance

The following attestation bundles were made for nativeres-0.3.0.tar.gz:

Publisher: pypipublish.yml on Jaded-Encoding-Thaumaturgy/nativeres

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nativeres-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: nativeres-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 24.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for nativeres-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a3939ca2cc1c619354eeebdc0fc3a8d5f3032db4134c256a87bbec1922b3642a
MD5 952f55ca302cb68986ddea756d0a1031
BLAKE2b-256 b5d459d787babb6e5880464e57eb020db6cd6da440b184e211460fb0f24c118b

See more details on using hashes here.

Provenance

The following attestation bundles were made for nativeres-0.3.0-py3-none-any.whl:

Publisher: pypipublish.yml on Jaded-Encoding-Thaumaturgy/nativeres

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.4.0

2 files

This release

0.3.0 This release

2 files

0.2.0

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page