Repository navigation
VapourBox 1.7.0: AI add-ons, audio restoration, new filters, deps 1.16.0 - #154
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
run-debug-macos.sh and run-debug-linux.sh copied only pipe_source.py and spotless.py beside the debug worker. pipe_source_dir() picks the first templates directory holding pipe_source.py, so every other vendored module (deflicker, mclean, temporaldegrain2, …, and now ai_runtime) was missing in a debug run and only worked from worker/templates/. Copy *.py, as the packaging scripts already do. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every AI model is to ship as an optional add-on, never in the deps bundle.
This is the shared groundwork.
Manifest add-ons: one JSON per add-on in app/assets/addons/ (format in
docs/ADDONS.md). Kind "files" is a model pack (plain files, or archive
members each checked by its own hash); kind "python" is wheels unpacked into
addons/<id>/site-packages/. ManifestAddonInstaller downloads and verifies
every file, stages in addons/<id>.new, writes a .vapourbox-addon.json marker
(id, version, platform) and renames into place; a manifest version bump
makes the old install count as missing. Platforms come from the manifest's
table, with minOs checked against the running macOS. AddonService finds every
manifest through the asset manifest; AddonInfo gains additionalCredits for
add-ons made of several separately licensed components.
VAPOURBOX_ADDON_MIRROR=<dir> takes files from a local directory (still
size- and hash-checked) so add-ons can be tested before upload.
The worker compiles the same manifests in (build.rs -> addons.rs): install
state, addon_dir, require() with a message naming the add-on and
Settings -> Add-ons, and --list-addons. ProcessingPipeline::required_addons()
is where a pass declares what it needs; ScriptGenerator refuses the job unless
it is installed and emits the {{#AI_RUNTIME}} block (both templates) when the
AI runtime is needed. WorkerHarness.ensureAddon() installs through the app's
own installer.
ai-runtime: ONNX Runtime + NumPy 2.5.4 for the deps Python 3.12, pinned by
URL and SHA-256 from PyPI: onnxruntime 1.31.1 (macOS arm64, Linux x64/arm64),
onnxruntime-directml 1.24.4 (Windows), 1.23.2 on Intel Macs (macOS 13+, the
last Intel wheel). Nothing else is needed at run time (checked). Passes use
templates/ai_runtime.py: setup() puts site-packages on sys.path itself (the
Windows embeddable Python ignores PYTHONPATH), session() picks TensorRT /
CUDA / DirectML / Core ML / CPU with a CPU fallback (VAPOURBOX_AI_FORCE_CPU),
and frame <-> NCHW helpers with map_frames(). --probe-ai-runtime runs a
committed 172-byte self-test model through that path and reports the
provider; positive results are cached per boot. Credited in NOTICES, the
About dialog and the README (ONNX Runtime MIT, NumPy BSD-3-Clause, DirectML
under Microsoft's licence on Windows).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs/ADDONS.md: the manifest fields, what an install looks like, the VAPOURBOX_ADDON_MIRROR test mirror, the addon-models-v1 hosting convention and the addon-staging/ conversion venv, the worker and template API (addons.rs, required_addons, the AI_RUNTIME block, ai_runtime.py), the --probe-ai-runtime probe, and the checklist for adding an add-on. CLAUDE.md's Add-ons section, key files and structure, BUILDING.md's structure, and an ENGINEERING_NOTES entry with the wheel facts the ai-runtime manifest rests on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The root .gitignore's 'addons/' (the downloaded add-ons directory) also matched app/assets/addons/, so the manifest was never committed and the worker's build.rs found no manifests outside the worktree that wrote it. Anchor the rule to the repository root. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Scripts/models/convert_realesrgan.py defines SRVGGNetCompact and RRDBNet (no basicsr needed), loads xinntao's checkpoints pinned by URL and SHA-256, and exports ONNX in the shape VSNCNN already runs (input/output, NCHW RGB float, dynamic batch/height/width, opset 13, IR 7). x2plus's pixel_unshuffle becomes the equivalent one-hot stride-2 convolution, which ncnn can import (checked exactly equal). Parity against PyTorch is printed; two runs are byte-identical. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…worker Three new Crop & Resize methods, run on VSNCNN like the bundled anime models, with their models in two manifest add-ons: - upscale-general: Real-ESRGAN General (realesr-general-x4v3 and its denoise variant, converted, to be hosted on addon-models-v1) and jcj83429's 2xLiveActionV1_SPAN (Apache-2.0, upstream's ONNX pinned at commit 5d8cdd2e). - upscale-esrgan-plus: Real-ESRGAN x4plus / x2plus (converted). Factor rules: General is 4x only, so 2x resamples its result down (Spline36, in float RGB, before the conversion back); SPAN is 2x only, so 4x runs it twice; x2plus/x4plus by factor. x4plus runs in 384-pixel tiles: whole-frame at 720x576 lost the Vulkan device on an M1 Pro and 512 tiles thrashed. ProcessingPipeline::required_addons() declares the add-on, so a job without it is refused naming it and Settings -> Add-ons; only macOS arm64, Windows x64 and Linux x64 (where VSNCNN ships) are offered. aiStrength (0-1, default 1) blends any AI upscale with a Spline36 upscale of the same frame in one std.Merge at the clip's format; at 1.0 nothing is emitted and the script is unchanged. Tests 185-187. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- vszip 22.1.0 -> 24.0.0 (first release with CPU NLMeans; WNNM since 22.0.0). macOS x64 builds the sdist with Zig 0.17.0 (-Doptimize=fast; the headerpad patch now matches the 8-space use_llvm inside if (build_vs)). Linux wheel pinned by hash. - SangNom 45.0 (PyPI wheels, pinned by hash) for Anti-aliasing's SangNom method. SSE2 only on x64: one file serves both CPU tiers. - deps-expected-plugins.json lists SangNom on every platform and tier; vapoursynth_integration_test requires sangnom and vszip.NLMeans. - Credits: SangNom (MIT source, GPL-2.0 binaries, as upstream states) and vs-jetpack (MIT, for the ported functions) in NOTICES, About and README. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A new audio_restoration module renders the output's soundtrack for one source stream before the video encode: channel fix, sync offset (either sign), drift correction from the encoded picture's FrameMap length, declip/declick/rumble/hum notches/afftdn (its 25 ms delay trimmed), DeepFilterNet (add-on), two-pass loudnorm and a latency-compensated limiter, all chosen in one place with one -af per ffmpeg run. The encoder maps the rendered track first and keeps the other audio streams; subtitles transcribe the rendered track. --audio-plan prints the plan. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The pass sits with Subtitles in an 'Audio & Subtitles' stage (it runs first: the transcript is of the restored sound), schema-driven like the others. Manifest add-on files can now be marked executable: the installer sets the bit and, on macOS, signs an unsigned program. DeepFilterNet is credited in NOTICES, About and the README. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…esize Three new Upscale Method options (Real-ESRGAN General, Live Action SPAN, Real-ESRGAN x4plus; NEW since 1.7.0), a General Denoise switch and an AI Strength slider for every AI method. Choosing an add-on method prompts for its add-on through AddonPrompt.ensure (moving between two methods of one add-on asks once), and the panel shows the add-on's terms with a Download button while it is missing: the AnimeJaNai notice is now the general UpscaleAddonNotice. upscaleMethodAddons mirrors the worker's UpscaleMethod::addon. The SPAN description says it cannot handle VHS damage, as its author does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…models NOTICES, About tiles and README Acknowledgments for the Real-ESRGAN general model and x4plus/x2plus models (BSD-3-Clause, Copyright (c) 2021 Xintao Wang, from upstream's LICENSE) and 2xLiveActionV1_SPAN (Apache-2.0, Copyright 2025 jcj83429, its NOTICE reproduced), each saying it is an add-on. README also describes the live-action upscalers and AI Strength. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…stream; tests The first heavy run found atempo moving every click ~20 ms early, afftdn taking 0.7 dB off -39 dB hiss at its default floor (13.6 dB with the measured one; its noise tracking undid it), and per-stream metadata mapping dropping the other streams' tags. Drift is now an exact resample (aresample up, integer asetrate, aresample back), afftdn gets the source's measured noise floor, and every audio stream's tags are mapped. Adds the push-gate --audio-plan test, the heavy encode tests (dead channel, +/- offset, trim, drift, hum, afftdn, loudness, late audio start, several streams, DeepFilterNet), unit tests, and an 'audio' progress phase. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e add-on models A tile larger than the frame in either direction segfaults VSNCNN. The template tiled whenever the area passed its threshold, so a wide, short picture (800x200 with x4plus's 384 tiles, or any frame above 720x576 in area but under 512 lines) crashed. Tiles are now min(tile, width/height). Tests: script generation for AI strength and the upscale-general models in the push gate (GPU rule; installs the add-on with the app's installer), and in the heavy suite every add-on model at 2x and 4x by pixels against Spline36 (size, count, preview = encode, flat colour within measured bounds, bar centre within 0.75 px), AI strength 0.5 landing half-way, and x4plus on an 800x200 source. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…GAN and CodeFormer to ONNX Conversion scripts for the face restoration add-ons: each pins the upstream checkpoint by URL and SHA-256 and the network source by commit, exports static-shape opset 17 / IR 8 graphs (loadable by ONNX Runtime 1.23.2), and records parity with PyTorch. GFPGAN exports with its fixed noise buffers (randomize_noise=False) so it is a pure function of its input; CodeFormer's fidelity w is a graph input (exact at w=0, where the fused branch adds zero). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
face_restore.py (NumPy on ONNX Runtime from the ai-runtime add-on, no OpenCV): RetinaFace detection with priors and NMS, five-point similarity alignment to the FFHQ 512 template, RestoreFormer++ / GFPGAN / CodeFormer, a feathered BiSeNet mask of the face itself, and an inverse warp back at the clip's own resolution. Temporally stabilised as a pure function of the neighbours (landmarks smoothed with hysteresis and gap filling, restored faces blended in aligned space with motion-adaptive weights), and merged in the source format so every pixel outside the faces is bit-exact. Runs after Crop & Resize, before Sharpen, in both templates; the add-ons (face-restoration, face-gfpgan, face-codeformer, all requiring ai-runtime) are declared through required_addons(), and the preview reads twice the smoothing radius either side. Generic helpers (to_rgbs/from_rgbs, shifted, FrameMemo) go to ai_runtime.py. Fixture: a VHS-degraded clip of NASA public-domain footage. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…offset CLAUDE.md (Audio Restoration section, the subtitle and -af rules), README, docs/ADDONS.md (executable files), ENGINEERING_NOTES and the report docs/reports/2026-11-audio-restoration: afftdn's 25 ms delay and noise floor, atempo's ~20 ms shift, alimiter's latency and auto-level, the late-start gap, hum notch depth, loudness accuracy, DeepFilterNet's delay. Adds the heavy test that Whisper's cues move with a 2 s sync offset, and WorkerHarness.ensureWhisper for running it locally. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Schema (model, strength, CodeFormer fidelity, steady-faces toggle; detection settings advanced-only; the VapourSynth call and models shown in advanced mode), Dart model, pipeline and converter wiring, the pass row as the first of the Finishing stage, and the add-on prompt when the pass is switched on or its model changes, with GFPGAN's and CodeFormer's non-commercial terms shown whenever they are chosen. Credits for RestoreFormer++, RetinaFace, BiSeNet, facexlib, GFPGAN and CodeFormer in NOTICES, the About dialog and the README, each from the upstream LICENSE. No built-in preset turns the pass on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e memo, heavy test Concurrent Core ML predictions from VapourSynth's threads ran the GPU out of memory; ai_runtime.Runner serialises a pass's model runs (one lock for the detector, parser and restorer) and retries a failed GPU run on the CPU. The per-frame memo now holds only the region the faces reach, not whole RGB frames. The script logs which provider the restorer runs on. integration_face_restore_test.dart (heavy): RestoreFormer++ changes the face and leaves every sample outside it bit-exact (8- and 10-bit), strength 0 is the input, GFPGAN and CodeFormer run with and without smoothing, and the preview is the encode's frame. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…TC fade fix - Anti-aliasing: SangNom method (2x supersample, SangNom per axis, back down; aa in 8-bit units, scaled by the plugin). havsfunc's santiag(type=sangnom) stays pinned off: it calls SangNom(order=0), which r45 treats as double-rate and refuses without _FieldBased. - Noise Reduction: NLMeans (CPU) advanced method on vszip 24's NLMeans, sharing the KNLMeans settings (same algorithm and output). The KNLMeans no-device message now names it as the way out. - Ports from vs-jetpack 3.0.0 (MIT) into both templates, through _expr() and _nnedi3(): vine_dehalo as an advanced Dehalo method, mpeg2stinx as an advanced Deblock method (whole frame, never per field; preview radius 1), and FixInterlacedFades as an IVTC option (average/match) right after VFM. mpeg2stinx and the fade fix match vs-jetpack to 0.04 / 0.00 levels. - Tests: Rust test_200-205; Flutter script-gen cases, the high-bit-depth parity passes, and a new heavy integration_classical_filters_test (fade fix closes the field gap 4.12 -> 0.06; NLMeans == KNLMeansCL to 0.0003). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
HuggingFace serves ggml-small.bin at 487,601,967 bytes and ggml-large-v3-turbo.bin at 1,624,555,275 (x-linked-size). The app only uses the size for progress, but WorkerHarness's downloader enforces it, so ensureWhisper failed on the small model. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…HS2HD probe docs/reports/2026-11-ai-upscale-addons: conversion parity (PyTorch vs ONNX <= 0.017 levels; VSNCNN fp32 vs ONNX Runtime <= 0.012), PSNR on a restored broadcast frame (and why General's 2x keeps Spline36), crops, flat-colour drift and bar position per model, AI strength, speed and x4plus tiling on an M1 Pro, the tile-larger-than-frame segfault, and why 2xVHS2HD (RealPLKSR) can't run on ncnn. Scripts reproduce every number. ENGINEERING_NOTES entry, reports index row, CLAUDE.md rules, and a note in docs/ADDONS.md that VSNCNN-run add-ons need no ai-runtime. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-ons Keeps both sides in README, ENGINEERING_NOTES and the reports index; the upscale tests are renumbered 186-188 after audio's test_185. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keeps both passes everywhere they meet; face restoration's Rust tests are renumbered 186/187 (185 is audio's), the copyWith model count is 23, and the README pipeline table puts Face Restoration at 19 with the rows below renumbered. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
make_colorize_ddcolor.py exports piddnad/DDColor's ddcolor_paper_tiny checkpoint (Apache-2.0); make_colorize_deoldify.py rebuilds DeOldify's DynamicUnetWide generator in plain PyTorch (fastai v1 no longer installs) and loads ColorizeVideo_gen.pth (MIT) with strict=True, verified against FaceFusion's independent export of the same weights to 1.8e-6. Both take one grey channel in [0, 1] with dynamic height/width and are reproducible byte for byte. Spectral/weight norms are baked in, and ReplicationPad2d, Tensor.repeat and DDColor's einsum are rewritten as exact equivalents Core ML can take, so each graph is one Core ML partition (DDColor ran 4x faster). colorize_provider_bench.py times them per provider and size. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
colorize.py (on the ai-runtime add-on): DDColor-T or DeOldify Video sees the luma stretched to a square render size; DDColor's CIELAB a/b are recombined with the frame's own lightness through std.Expr stages (OpenCV's constants, exact sRGB curve), DeOldify's RGB is scaled up as upstream does; either becomes YUV with the source's matrix, and only U/V are taken, so the Y plane is bit-exact at every depth. Temporal smoothing averages each frame's prediction with its neighbours' (shifted + FrameMemo), weighted to zero where the grey picture moved. Runs between Chroma Fixes and Color Correction in both templates; the add-ons (colorize-ddcolor, colorize-deoldify, each requiring ai-runtime) are declared through required_addons(); the preview reads temporal_radius frames either side and runs DDColor on the CPU, since Core ML compiles it for over a minute per process. ai_runtime.session/Runner take dims= (free dimension overrides) so one dynamic-shape file gives Core ML static shapes. Fixture: 5 s of 'Diary of a Sergeant' (1945, US War Department, public domain). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Schema (DDColor / DeOldify Video as methods, each gating its own render size; colour strength 0-1.5; steady colour 0-4 frames), Dart model, pipeline and converter wiring, the pass row between Chroma Fixes and Color Correction in the Detail & Color stage, and the add-on prompt when the pass is switched on or its model changes. Credits for DDColor (Apache-2.0) and DeOldify (MIT, Jason Antic) in NOTICES, the About dialog and the README, from the upstream LICENSE files and model cards. No built-in preset turns the pass on. Unit tests, script-generation coverage and a heavy end-to-end test (luma bit-exact at 8 and 10 bits and on a colour source, strength 0 = input, both models, preview = encode). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
test_93 requires every vendored module that evaluates expressions to use the same helper shape as the templates (akarin where present, an explicit core.std.Expr fallback). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tion Colourisation keeps only the luma, so the colour Chroma Denoise cleaned never reaches the result. Advisory only, on the Chroma Denoise row. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs/reports/2026-11-colourisation: licences read upstream, conversion parity and the DeOldify verification, the Core ML rewrites (one partition, 2.6x faster) and compile times, the CIELAB chain against OpenCV and the exact formulas, colour flicker with and without smoothing and motion weighting (84% less at radius 2 for both models), speed on Core ML and the CPU at SD and 1080p, and the position, already-colour and preset decisions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # README.md # docs/ENGINEERING_NOTES.md
The deps 1.16.0 builds failed three times during a GitHub incident (timeouts for unauthenticated users): release downloads came back as 92-byte 504 pages or cut short, curl -L saved them as the archive, and the build died later on "not in gzip format". Every curl now runs with --fail and six spaced retries; Windows downloads (and its PyPI metadata lookups) go through a retry loop. What gets built is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
vszip 24.0.0 and SangNom r45 on every platform. All eight zips and their sidecars are on the release candidate; release.sh refuses to cut an app release while this names an -rc tag. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
As 1.15.0-rc1 did: the app reinstalls only when the version string changes, so an RC built as plain 1.16.0 would leave anyone who installed it on the RC's contents after the real 1.16.0 (or an rc2) shipped. CI also derives the asset version from the tag, which could not find the 1.16.0-named zips. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- face/colorize parameter tests read the Rust source with CRLF on a Windows checkout; normalise line endings before matching. - AudioFixtures.plan decoded the worker's UTF-8 stdout with the Windows code page (the app itself decodes UTF-8), mangling the arrow in 'Settings → Add-ons'. - The executable add-on test copied /bin/echo, which is arm64e: macOS 15 kills an arm64e binary once Apple's signature is gone, ad-hoc signed or not. Compile a plain C program instead, as DeepFilterNet's binary is. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s 4x - ai_runtime_test matched the self-test literal with '\n' against a CRLF checkout on Windows; normalise first. - realEsrganPlus_4x (five frames and a preview of the heaviest network) took 18 min on Linux lavapipe and ran past its 20 min budget on Windows' lavapipe; give that one case 50 min. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…gate frame - WorkerHarness killed only the worker on a timeout. On Windows that left its vspipe running Real-CUGAN on every core, so the next GPU tests (AnimeJaNai) timed out as well. Use the app's ProcessTree.killTree. - The push gate's upscale frame is cropped to 120x96: a 240x192 Real-CUGAN frame took 2.5 to over 5 min on Windows lavapipe. - Face Restoration and Colourisation encodes allow 1200 s before the stall watchdog: on the Intel-Mac VMs Core ML's virtual GPU fails and CodeFormer's first frame took ~10 min on the CPU. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tests that run RIFE or AI upscaling through ncnn need a Vulkan device, so they are tagged `gpu` and both workflows exclude the tag (push gate: --exclude-tags heavy,gpu; nightly: --tags heavy --exclude-tags gpu). The lavapipe provisioning is removed: on a CPU Vulkan driver the timings measured the runner, not the GPU path, and Windows kept running past every budget. CI keeps the probe-answer and refusal tests, which need no device. Run `VAPOURBOX_EXPECT_VULKAN=1 flutter test --tags gpu` on a machine with a GPU (CLAUDE.md, docs/BUILDING.md, ENGINEERING_NOTES). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On the Intel-Mac v2 runner Core ML falls back to the CPU and the Face Restoration preview hit the harness's 5 min default; give both AI passes' previews the encode's 20 min and stall budget. On linux-x64-v2 Whisper's small model reached 82% of a 30 s clip in the default 5 min; the subtitle offset test's encodes get 15. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A file's name (or an archive member's) may now be a relative path of plain names joined by '/'. Every segment is checked like a plain name, so nothing can land outside the add-on's directory, and the installer creates the parent directories in the download, staging and extraction steps. It exists for RIFE, whose plugin reads the model version and its padding from substrings of the model directory's path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The last AI models in the deps bundle move out, so "every AI model is an add-on" has no exceptions. The plugins (librife, VSNCNN, MoltenVK) stay. - frame-rate-rife: RIFE 4.26's ncnn model (11 MB), fetched from the plugin's repository at the commit the deps scripts pinned, installed as rife-v4.26_ensembleFalse/flownet.* because the plugin reads the model version and padding from that path. - upscale-anime: vs-mlrt's Real-ESRGAN animevideo 2x/4x and Real-CUGAN 2x ONNX files (20 MB), byte for byte, hosted by this project on the deps-v1.16.0-rc1 release (vs-mlrt publishes them only in an ~810 MB archive). Worker: both are declared in required_addons() and refused through addons::require; scripts read the models from the add-ons directory. AiModel::Bundled and gpu_plugin::UPSCALE_MODELS are gone. The probes no longer need any model: VSNCNN runs a 264-byte committed self-test ONNX handed over as bytes (path_is_serialization), RIFE a weightless two-layer stand-in written beside the probe script, and both check the answer (a new WrongResult reason). A stand-in that fails to load is LoadFailed. App: the panels show the add-on notice and prompt on choosing RIFE or an anime upscaler, and on switching Frame Rate / Crop & Resize on with one chosen. Deps scripts stop fetching models; deps-expected-plugins.json no longer lists them, and attribution_test fails if a model reappears. Credits say the models are separate downloads. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Samples 24 pairs of consecutive frames (12 above 1080p) across the source, decoded in its own format and depth, and measures luma in plain Rust: - noise: motion-compensated frame difference (16x16 blocks, +-10 px, match chosen on smoothed pictures), 10th percentile of blocks, 25th percentile of pairs; per field when interlaced. Sees tape-like and grain noise a spatial high-pass misses, and cancels moving texture. - halo: per-edge two-sided overshoot beside isolated step edges followed over 7 lines of one field, mean over edges, % of the step; a one-sided outline scores 0. The worker decides the thresholds (noise sigma >= 3.5, halo >= 6.0) and reports noiseHigh / haloHigh. Calibrated in docs/reports/2026-11-noise-halo-scores. crop_detect's sampling decode becomes decode_samples, shared by both detectors. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
After a source is analysed, MainViewModel measures it in the background (--detect-noise-halo, one source at a time, whole source not the trim) and keeps the report on QueueItem.noiseHalo. relevanceFor badges Noise Reduction / Dehalo as recommended only on the worker's noiseHigh / haloHigh verdicts; unmeasured, low or failed stays neutral, and nothing else in the pass list changes. Tests: pass_relevance_test cases (unmeasured, below, failed, above, other passes unchanged, restraint with a measurement); heavy integration_noise_halo_test on the VHS capture (clean, sigma 6 noise at 8 and 10 bit) and the DVB-T broadcast (clean, sharpened). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs/reports/2026-11-noise-halo-scores: 154 fixtures with known noise and sharpening (Kodak pans, NASA 1080p, synthetic animation, a 1968 film scan, the repo's VHS and DVB-T clips; dark, letterbox, interlaced, 10-bit and sub-pixel-texture traps), every candidate measured, the worker checked against the NumPy reference, timings. VCG's signalstats TOUT / halo ratio and a spatial Immerkaer noise score were measured and rejected. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Dehalo Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> # Conflicts: # docs/ENGINEERING_NOTES.md
rc2 is rc1 without RIFE's model and the Real-ESRGAN anime / Real-CUGAN models, which are now the frame-rate-rife and upscale-anime add-ons. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
deps-version.json points at deps-v1.16.0, the tested rc2 bundles with only the version changed (Scripts/promote-deps-rc.py, now committed). Every self-hosted add-on model downloads from addon-models-v1, where each sits beside its upstream licence text, so no manifest names an -rc tag. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
update-version.sh now edits Info.plist with sed only: PlistBuddy rewrote the whole file and dropped its comments, including the one explaining why Impeller is forced off (issue #91). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Nov 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
VapourBox 1.7.0: the "ship on every platform" work. It adds AI passes as opt-in downloads, audio restoration, new classical filters and source analysis, on deps 1.16.0.
New for users
Autoby default). This converts the matrix only; primaries keep the source's.Add-ons
app/assets/addons/, read by both the app and the worker.ai-runtime(ONNX Runtime)frame-rate-rifeupscale-animeaddon-models-v1, each beside its upstream licence text. Nothing points at an-rctag.Dependencies
Scripts/promote-deps-rc.py):Testing
024325a, against the final deps 1.16.0 andaddon-models-v1. The version bump since then changes no code; the push gate passes locally (1431 tests).gpuand left out of CI, since the runners have none. They pass on an M1 Pro withVAPOURBOX_EXPECT_VULKAN=1.docs/reports/(face restoration, colourisation, audio restoration, AI upscale add-ons, classical filters, crop detection + 709, noise/halo scores).Before merging
VAPOURBOX_EXPECT_VULKAN=1 flutter test --tags gpu(plus--tags heavyfor the encodes) on a Windows and a Linux machine with a GPU. Nothing in CI proves RIFE and VSNCNN run in those bundles, or that the new model add-ons install there.Autoby default.🤖 Generated with Claude Code