mirror of
https://github.com/YusufB5/ASCILINE.git
synced 2026-06-20 22:38:06 +02:00
feat: adaptive raw/zlib/delta frame codec (opt-in, backward compatible)
The binary protocol re-sent the full grid every frame. This adds an opt-in
per-frame codec that picks the smallest of three encodings and tags it in a
1-byte header, without changing the rendered output:
0 RAW framebuffer as-is (legacy)
1 ZLIB zlib(framebuffer)
2 DELTA only the cells changed since the previous frame, patched on top
Clients opt in via /ws?codec=adaptive; omitting it yields the original protocol
byte-for-byte, so existing clients are unaffected. A keyframe is forced
periodically for resync. codec.js is shared by the browser and the Node test,
so the shipped decode path is the tested one.
Optional --quality {lossless,high,balanced,low} enables lossy temporal delta
(conditional replenishment): a colour cell is only re-sent once it drifts past a
tolerance from what the viewer already sees; the character plane stays exact.
Default lossless = bit-exact.
Measured wire savings (mode 5, 200x80): static screen 0.3% of legacy (~375x),
pixel mode 11.6%, high-motion 63% (never worse). Encoder tuned (zlib level 3,
smart candidate selection) to stay well under the frame budget.
Verified bit-exact two independent ways: Python->Node vectors and a live
adaptive-vs-legacy WebSocket diff. (A fuller mutation + Autobahn conformance
harness exists on request.)
This commit is contained in:
parent
8c60ef12a0
commit
e3f282910d
10 changed files with 478 additions and 10 deletions
39
README.md
39
README.md
|
|
@ -34,6 +34,45 @@
|
|||
2. **Frontend (Vanilla JS)**: Receives binary frames via WebSockets, manages a jitter buffer, and renders to a Canvas grid.
|
||||
3. **Communication**: Optimized WebSocket protocol with a custom `INIT` handshake for dynamic resolution/FPS adjustment.
|
||||
|
||||
## 🗜️ Adaptive Frame Codec (opt-in, backward compatible)
|
||||
|
||||
The original binary protocol re-sends the full grid every frame. An opt-in
|
||||
adaptive codec picks the smallest of three encodings per frame and tags it in a
|
||||
1-byte header — **without changing the rendered output**:
|
||||
|
||||
| tag | encoding | best for |
|
||||
| :-- | :------- | :------- |
|
||||
| `0` RAW | framebuffer as-is (legacy) | incompressible frames |
|
||||
| `1` ZLIB | `zlib(framebuffer)` | general motion |
|
||||
| `2` DELTA | only the cells that changed since the last frame | static / low-motion |
|
||||
|
||||
Clients opt in with `/ws?codec=adaptive`; omit it and you get the **original
|
||||
protocol byte-for-byte**, so existing clients are unaffected. A keyframe is
|
||||
forced periodically so dropped packets / late joiners resync. The decoder
|
||||
(`codec.js`) is shared by the browser and the test suite, so the shipped path is
|
||||
the tested one.
|
||||
|
||||
**Measured wire savings** (mode 5, 200×80 grid):
|
||||
|
||||
| content | vs. legacy |
|
||||
| :------ | :--------- |
|
||||
| static screen / slideshow | **0.3%** (≈375×) |
|
||||
| pixel mode | 11.6% (≈8.6×) |
|
||||
| high-motion / full-frame change | 63% (never worse than legacy) |
|
||||
|
||||
An optional `--quality {lossless,high,balanced,low}` enables lossy *temporal
|
||||
delta*: a colour cell is only re-sent once it drifts past a tolerance from what
|
||||
the viewer already sees (the character plane stays exact), cutting the hard
|
||||
cases a further ~15–30% at imperceptible quality. Default is `lossless`
|
||||
(bit-exact).
|
||||
|
||||
> Verified two independent ways, both **bit-exact**: Python-encoded vectors
|
||||
> decoded by `codec.js` in Node (`experiments/gen_vectors.py` →
|
||||
> `experiments/check_vectors.js`), and a live `adaptive`-vs-`legacy` WebSocket
|
||||
> diff (`experiments/test_e2e.js`). Generate the test clips with
|
||||
> `experiments/make_test_clips.sh`. (A fuller mutation-test + Autobahn
|
||||
> conformance harness and CI workflow exist too — happy to add them if useful.)
|
||||
|
||||
## 📦 Installation
|
||||
|
||||
### 1. Clone the repository
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue