Skip to main content

Module kernels

Module kernels 

Source
Expand description

The reconstruction algorithms: features and motion evidence, region and layer learning, tracking, the pose graph, compositing with temporal conflicts, reveal, framing and the preview pyramid, plus the YUV→RGBA and PNG row kernels.

Every pixel algorithm lives here, with no FFI and no I/O. The browser reaches it through the extern "C" exports of long-screen-wasm (rust/wasm), compiled three ways: scalar, SIMD128 and SIMD128 + shared-memory threads (see scripts/build-core.sh). The TypeScript side owns browser APIs only (decoding, storage, UI); it must not reimplement anything this module provides.

This is an implementation layer, used by the engine, the driver and the web page; most users want the driver at the crate root. Its API follows what those layers need and may change in minor versions. With the rayon feature, pool::par_for chunks run on rayon’s thread pool; results do not depend on the thread count, and the WebAssembly builds leave it off.

Check a candidate motion between two grayscale frames: the second frame is the first one scrolled up by 8 pixels, and the retained block error is near zero only for the right displacement.

use long_screen::kernels::motion::{verify_translation, Gray};

let (width, height) = (192, 192);
let texture = |x: usize, y: usize| ((x * 37 + y * 101 + (x * y) % 23) % 251) as u8;
let a: Vec<u8> = (0..height).flat_map(|y| (0..width).map(move |x| texture(x, y))).collect();
let b: Vec<u8> = (0..height).flat_map(|y| (0..width).map(move |x| texture(x, y + 8))).collect();
let a = Gray { width, height, data: &a };
let b = Gray { width, height, data: &b };

let right = verify_translation(a, b, 0.0, 8.0, None);
let wrong = verify_translation(a, b, 0.0, 0.0, None);
println!("error at the right shift {right:.2}, without it {wrong:.2}");
assert!(right < wrong);

Modules§

chrome
Screen-fixed chrome evidence on native frames (src/core/layers.ts::stationaryBoundary, stickyOcclusions): a persistent appearance edge within a stationary band, and the per-observation sticky header band whose native texture agrees with zero motion and disagrees with the accepted page translation. Thresholds, sampling steps and the “return the carried bands” fallbacks are the historical ones.
compositor
Pixel-ownership compositing of one placement into one tile (docs/ARCHITECTURE.md §六–七).
consistency
World-consistency mask for one moving-region placement (docs/ARCHITECTURE.md §七).
features
Corner detection and binary descriptors on analysis-resolution grey images.
fixed_history
What one screen-fixed region showed at the start of the recording, without its transients (docs/ARCHITECTURE.md §七 “屏幕固定区域”).
framing
Presentation canvas synthesis (src/core/framing.ts): layout/coordinate mapping, background-extension statistics, and the two per-tile passes buildFramedCanvas drives (chrome/content copy, then source-tile evidence fold). Tile-cache traversal, the O(perimeter) candidate pre-check and KV writes stay in TS.
geometry
Integer/float conventions shared with the adapter. JavaScript’s Math.round rounds halves toward +∞ and Math.floor(x + .5) does not (it fails just below a half), so the exact form is spelled out.
layers
Per-frame layer-learning evidence (originally LayerLearner.add/addNative in TS, now frozen verbatim as the parity oracle at tests/support/reference/layers.ts): screen-space motion discontinuities accumulated across the WHOLE recording. finish() — the one-shot region construction that reads these accumulators — stays with the adapter for now; every per-frame pixel loop lives here.
motion
Photometric motion evidence on analysis and native images: hypothesis generation from matches, patch errors, audits and integer refinement. Every threshold is the historical one; tie-breaking (first minimum, distance to the guess) is preserved so reconstructions stay reproducible.
overscroll
Elastic overscroll (docs/ARCHITECTURE.md §十 “合成与瞬态像素”): where a canvas’s page ends, read from how its placements move, and how much of one frame past that end is the background the browser shows there.
png
PNG scanline reconstruction (unfilter) and filtering, used by the streaming single-PNG export path (src/codec/png.ts::encodePNG/decodePNG’s legacy row helpers). The tile codec itself (rust/wasm/src/png.rs::ls_png_encode/ls_png_decode) uses the png crate end to end instead.
pool
Data-parallel for over independent chunks, run on helper Web Workers that share this module’s memory, or on rayon’s thread pool in a native build.
pose_graph
Pose-graph relaxation (src/core/pose-graph.ts::PoseGraph.optimize/residual computation). A Gauss-Seidel-style relaxation over a graph handed in as plain arrays: node positions/pinned flags plus a CSR adjacency list the TS side builds from its Map iteration order — this module never sees string ids, only indices, so node identity/ordering questions stay where the KV layout lives (pose-graph.ts). Alternating forward/reverse node-visitation order matches optimize()’s odd/even iteration parity (iterations % 2 === 1).
pyramid
Pyramid parent-tile assembly: four child tiles (2×2, possibly with holes where a child tile was never observed) halved and packed into one size × size parent tile. The halving itself is raster::halve_rgba (alpha-weighted 2:1 reduction); this module only adds the “which quadrant” bookkeeping TileStore.buildPyramid (src/storage/tiles.ts) does in TS, one Rust call per parent instead of one per child.
raster
Native-frame raster kernels: luma, box-filter analysis downscale, preview halving.
region
Region membership: rect, exclusions, optional native crop, and an analysis-resolution mask looked up at floor(x / factor) (or by ratio for masks built without a factor).
regions
Region construction (src/core/layers.ts::LayerLearner.finish and RegionAtlas’s pixel-labelling constructor), ported stage by stage from the frozen TS oracle in tests/support/reference/layers.ts. Per-frame accumulation (rust/long-screen/src/kernels/layers.rs) already runs here; this module turns the accumulators the adapter reads back into Regions, once per run, and then labels every native pixel by first-containing-region-wins.
reveal
Overlay-aware source selection (docs/ARCHITECTURE.md §七).
temporal
Temporal-conflict compositing: pure algorithms behind Compositor (src/core/compositor.ts) that do not themselves touch KV storage. components, the pixel-write half of overwritePatch (overwrite_tile), the in-memory temporal index (TemporalIndex) and resolveTemporal’s decision (TemporalIndex::decide + mask_complete + TemporalIndex::commit) all live here (see docs/ARCHITECTURE.md §十 “合成与瞬态像素” for the invariants they keep — complete means “rewrote every previously covered pixel of the block”, maskComplete is all-or-nothing over the whole connected component, frozen blocks still heal provisional pixels).
track
Per-region tracking kernels: translation evidence, keyframe scoring and stateless verdicts. Stateful sequencing and registration-window lifetime belong to engine::solve; these kernels do no I/O. phase supplies the additional evidence and geometry support used only after a phase rescue is needed. The historical TS implementations remain parity references for unchanged paths.
voting
Displacement-spread consistency voting (docs/ARCHITECTURE.md §七): a bounded ring of recent analysis-resolution frames, one region-local box-gray per moving region, compared against several partners whose world displacement clears dmin. This is the stateful solve()-side half of the world-consistency evidence; consistency.rs consumes the finalised verdicts during rendering.
yuv
Decoded-frame layouts (planar and semi-planar YUV) to RGBA, for browsers whose VideoFrame.copyTo cannot convert to RGB itself (Safari, through at least 27). The arithmetic is libyuv’s C reference (row_common.cc: YuvPixel, x86 form) with its YuvConstants, which is what Chrome’s own copyTo({ format: 'RGBA' }) runs on a software-decoded frame; chroma is point-sampled like libyuv’s I4xxToARGBRow_C. Rows are split across the pool; every output byte depends only on its own inputs. Planes coding an HDR signal (PQ or HLG) go through hdr instead, which also undoes the transfer.