Batch Zigvid browser wrapper
Batch Zigvid browser wrapper
Algorithm modules adapted from https://github.com/Landa233/zigvid (MIT).
calculate_gray_barcode(gray, width, height, threshold) accepts the complete FFmpeg frames.gray bytes. Frame count is inferred from byte length. The whole array is thresholded in Rust, then the existing formigram algorithm computes H0/H1 and splits intervals into the eight existing categories. White=1, foreground connectivity=8, complementary background connectivity=4, exterior background excluded. No public incremental stream API is used. calculate_barcode(binary, width, height, frame_count) remains for compatibility.
From this folder:
cargo test --lib
wasm-pack build --target web --release --out-dir ../../assets/wasm/zigvid
python3 -c 'from pathlib import Path; Path("../../assets/wasm/zigvid/.gitignore").unlink(missing_ok=True)'
From the repository root, run Node verification scripts in _tests/: ffmpeg-batch.mjs, ffmpeg-worker-cache.mjs, and ffmpeg-page.mjs.
Parallel browser formigram generation
Update Barcodes uses 2–4 independent Web Workers when hardware concurrency permits and the cached video has >16 frames and at least 1 MiB of pixels. On low-memory devices the cap is two. FFmpeg remains single-threaded; no decode is repeated. No Rayon, SharedArrayBuffer, or isolation headers are required.
Each task thresholds up to 17 cached frames and builds H0/H1 formigram fragments in Rust, without barcode reduction. Neighboring chunks overlap by exactly one frame. Connected-component IDs are deterministic, so the coordinator stitches that shared frame once and preserves all adjacent-level edges. It then runs the existing reduction on each complete global formigram. Local chunk barcodes are never combined. The original serial APIs remain available as a fallback.
The worker pool is retained for threshold updates and terminated on file replacement, release, or computation failure. Only bounded chunk copies are transferred; the full grayscale cache stays attached in the decoder worker. Console timing includes generationWorkers. Smaller videos, low core counts, and worker failures use serial computation. Worker startup and fragment transfer can outweigh the speedup on some videos. Reduction itself is still serial.
Verification: cargo test --lib exhaustively compares 4,096 three-frame binary videos with serial results. _tests/formigram-parallel.mjs runs the actual browser worker module with a Node worker adapter, checking all eight barcode collections against serial WASM at two thresholds on the sample video.
Seed generation with Rayon
compute.rs follows Zigvid’s simple/composition seed algorithm. Frames are indices into the cached binary buffer, rather than filesystem paths. Level IDs use usize to avoid u16 overflow. Native builds use Rayon’s indexed parallel iterator for connected-component generation. Formigram assembly is ordered and serial, with alternating union/intersection directions. Batches contain at most 16 levels so full-video pixel label arrays are never retained. The reduced H1 exterior removal remains unchanged. Native thread count comes from the current Rayon pool (RAYON_NUM_THREADS for the global pool, or ThreadPoolBuilder/install).
Default browser assets still use ordinary WASM instances inside the existing JS worker pool. Their local seed loop is serial; Rayon is not silently invoked on an unthreaded wasm32 build. The optional wasm-rayon feature exposes initThreadPool and selects the Rayon loop for a properly threaded WASM build. It is NOT enabled in the deployed assets. Enabling it also requires a nightly build-std build, atomics/shared-memory compiler flags, cross-origin isolation, and awaiting initThreadPool before computation. Merely adding the Cargo feature to the existing build command is insufficient. See the upstream instructions: https://github.com/RReverser/wasm-bindgen-rayon#building-rust-code