v0.3: In-memory keyframe cache for faster first-frame #17

Closed
opened 2026-05-03 14:54:43 -04:00 by zgaetano · 0 comments
Owner

Implemented and deployed in commits a2e0a8c020a1807490edd.

What landed:

  • core/webrtc/keyframecache.go — new bounded ring buffer (keyFrameCache). Detects H.264 IDR NAL starts in both single-NAL (type 5) and FU-A (type 28, start bit set, inner type 5) packetisation modes. Capped at 512 packets / 2 MiB per source.

  • core/webrtc/source.go — added cache *keyFrameCache field and EnableKeyFrameCache() method. readLoop() calls cache.push(pkt) after each unmarshal (before the subscriber fanout). Subscribe() snapshots the burst outside s.mu (avoids any cross-lock ordering with push) and pre-fills the new channel with the IDR burst before registering it live — using a labeled break prefill to stop gracefully if the channel is full.

  • app/webrtc/lifecycle.goallocAdjacentPair() calls videoSrc.EnableKeyFrameCache() immediately after binding the video UDP source. Audio sources are intentionally left uncached.

Result: new WHEP subscribers receive the last H.264 keyframe burst immediately on join rather than waiting up to one full IDR interval (~2 s at GOP=60/30 fps). Verified binary contains all 8 cache symbols. Container restarted and running.

Implemented and deployed in commits a2e0a8c → 020a180 → 7490edd. **What landed:** - `core/webrtc/keyframecache.go` — new bounded ring buffer (`keyFrameCache`). Detects H.264 IDR NAL starts in both single-NAL (type 5) and FU-A (type 28, start bit set, inner type 5) packetisation modes. Capped at 512 packets / 2 MiB per source. - `core/webrtc/source.go` — added `cache *keyFrameCache` field and `EnableKeyFrameCache()` method. `readLoop()` calls `cache.push(pkt)` after each unmarshal (before the subscriber fanout). `Subscribe()` snapshots the burst outside `s.mu` (avoids any cross-lock ordering with push) and pre-fills the new channel with the IDR burst before registering it live — using a labeled `break prefill` to stop gracefully if the channel is full. - `app/webrtc/lifecycle.go` — `allocAdjacentPair()` calls `videoSrc.EnableKeyFrameCache()` immediately after binding the video UDP source. Audio sources are intentionally left uncached. **Result:** new WHEP subscribers receive the last H.264 keyframe burst immediately on join rather than waiting up to one full IDR interval (~2 s at GOP=60/30 fps). Verified binary contains all 8 cache symbols. Container restarted and running.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: zgaetano/datarhei-dragonfork-core#17
No description provided.