ReviewOS

also looking at this

home-lang/home

feat(video): add bounded packet history, delayed FIFO and owned snapshots

#916
Merged chris wants to merge feat/keyframe-packet-ring into main
3 files +229 -0
packages/video/docs/packet-ring.mdadded+36-0
Changes to packages/video/docs/packet-ring.md
@@ -0,0 +1,36 @@
1# Keyframe-aligned packet history
2
3`core/packet_ring.zig` (exported as `video.packet_ring`) adapts the existing video
4ring-buffer structure to encoded pre-roll: storage consists of one fixed byte
5arena and a fixed entry array. Push copies borrowed packets without allocating
6or blocking. The caller serializes all access and chooses timestamp units.
7
8Byte capacity, frame capacity and duration are hard upper bounds. Eviction
9removes dependent packets until the oldest retained packet is a keyframe.
10If the limits cannot hold a GOP, history can be empty until the next key.
11Oversized packets and non-increasing timestamps are rejected without modifying
12retained history. Parameter sets/codec configuration belong outside the ring.
13`entry` returns metadata; `copy` explicitly copies a retained payload to caller
14storage, including when it wraps in the byte arena. Views expire on mutation.
15
16Three standalone regression tests cover arena wrap, byte/frame/time eviction,
17keyframe gating, rejected-input atomicity, zero capacities and allocator failure
18cleanup. Tested on Zig 0.15.2 and the installed 0.17 development toolchain. This
19focused validation does not establish correctness of the wider video graph.
20
21zig-camera uses this module with Home JPEG/Matroska and x264/x265/fragmented MP4.
22It retains compressed access units, without retaining camera DMA leases or raw
23RGB frames. Explicit snapshots need scratch space for one largest retained
24packet; remuxing starts with fresh codec headers and resets file timestamps.
25
26For time-shifted streaming, `pushQueued` uses the same owned arena as a bounded
27FIFO: it never evicts or filters dependent frames, and rejects full/oversized or
28non-monotonic input without mutation. Use `ready(now, delay)` then `copy(0, scratch)`
29and `pop()` to forward matured packets; `ready(null, delay)` flushes EOF. Queue
30capacity must cover the delay. The caller controls keyframe starts and output
31errors; a full FIFO must not silently discard encoded dependencies.
32
33`cloneFrom(allocator, start)` owns a minimally sized copy of a selected suffix.
34Serialize it with source mutation; the resulting data can move to a worker and
35outlive the source. It copies wrapped bytes directly into a contiguous arena and
36cleans up partial allocation failures. The module creates no threads or file I/O.