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