-
Notifications
You must be signed in to change notification settings - Fork 2
Home
Welcome to the vapoursynth-zipcl wiki!
vszipcl is a VapourSynth plugin written in Zig that provides OpenCL-accelerated video
filters. Every filter shares one architecture (a shared cl_context, a prewarmed per-stream
resource pool, and a num_streams knob that actually scales), and each is a faithful port of
an established reference — verified bit-exact where the reference allows.
All filters accept 8/16-bit integer, 16-bit half, and 32-bit float input (except where noted) and are multi-plane (Gray / YUV / RGB, subsampled chroma).
- Bilateral: OpenCL port of VapourSynth-BilateralGPU — bit-exact on integer input.
-
Deband: OpenCL port of
placebo.Deband(libplacebo'spl_shader_deband). - EEDI3 / EEDI3H: Edge-directed interpolation (vertical / horizontal), same numeric core as the vapoursynth-zip CPU EEDI3.
- GaussBlur: Separable Gaussian blur.
- NLMeans: Non-local means denoiser, matching KNLMeansCL.
- Pipeline: JSON-driven on-GPU chain of the ops above — upload once → bilateral/gaussblur/deband → download once (~2× f32 vs chaining the standalone filters).
-
MSuper / MAnalyse / MDegrain: OpenCL port of the mvtools motion-compensation trio (
mvu.Super/Analyse/Degrain) — bit-exact to the CPU reference. Super & Degrain are GPU-fast; the exact motion search is a bit-exact reference (slow — see MAnalyse). GPL-2.0 (see below).
Licensing: the MV* filters are derived from GPL-2.0 mvtools code, so a compiled
vszipcl.dllthat includes them is distributable under the GPL-2.0-or-later (LICENSE.GPL2). The rest of the plugin is MIT.
📊 See Benchmarks — vszipcl vs each reference at 1080p YUV420 (u16/f16/f32, num_streams 1 & 2).
Every filter takes these two optional arguments:
-
device_id (int, default: 0):
OpenCL device index (platform 0). Out-of-range or negative values are rejected. -
num_streams (int, default: 1, range: 1..32):
Number of concurrent per-frame resource sets. The default of 1 serializes to one frame at a time; raise it to overlap more frames on the GPU (up to what the kernel/transfer mix can hide — 2 already captures most of the scaling). Output is bit-identical at any stream count.
RTX 3070 Ti, 1080p, decode-inclusive (bs.VideoSource), 300 frames. vszipcl wire-format
support (u8/u16/f16) halves or quarters the PCIe transfer vs f32, so integer clips are often
the fastest path.
# Bilateral (YUV420P8) — bit-exact vs bilateralgpu, ~1.75x faster (on-device convert, 1 byte/sample)
src.vszipcl.Bilateral() # ~405 fps
src.bilateralgpu.Bilateral() # ~231 fps
# NLMeans (YUV420P8, channels="Y", d=1, s=4)
src.vszipcl.NLMeans(channels="Y", d=1, s=4) # u8 ~173 fps | f32 ~133 fps
src.knlm.KNLMeansCL(channels="Y", d=1, s=4) # u8 ~80 fps
# Deband / GaussBlur (GRAY, transfer-bound — u8 ~2x f32)
src.vszipcl.Deband() # u8 ~880 fps | f16 ~600 | f32 ~383
src.vszipcl.GaussBlur() # u8 ~800 fps | f16 ~575 | f32 ~380