Ring Buffer Architecture & Shared Memory Routing
The Ring Buffer (internal/buffer/ring.go) is the central memory routing hub of RUSEON Core. It acts as a high-concurrency shared-memory broadcast bus that distributes incoming video packets from camera ingest to all outbound consumers (WebRTC, HLS, fMP4 Archiver, gRPC AI) without copying payload buffers.
1. Split-Lock Synchronization Strategy
To eliminate lock contention between high-frequency frame producers and dynamic client subscription lifecycles, the Ring Buffer utilizes two independent sync.RWMutex locks:
- Storage Mutex (
mu sync.RWMutex): Protects the circular slice of*Framepointers and the read/write cursor pointers. - Subscriber Mutex (
subMu sync.RWMutex): Protects the list of active subscriber channel registrations.
Benefit: Adding or removing a WebRTC client never blocks or delays the ingestion thread from appending new video frames to the ring.
2. Lock-Free Codec Parameters (atomic.Pointer[CodecParams])
H.264 and H.265 streams periodically send in-band parameter sets (SPS, PPS, VPS) that are required to initialize client video decoders.
- When an SPS/PPS frame arrives, the Ring Buffer parses and caches them in an
atomic.Pointer[CodecParams]. - Outbound workers (such as on-demand HLS muxers or new WebRTC peers) read the codec parameters with zero locks and zero allocations.
3. Instant Playback via KeyFrame Backfill
When a new viewer connects, waiting for the camera's next physical I-Frame (which might be 2–4 seconds away) would cause a noticeable start delay.
Upon calling Subscribe():
- The Ring Buffer scans backward to locate the nearest preceding KeyFrame (I-Frame).
- It immediately backfills all frames from that KeyFrame to the current head into the subscriber's channel.
- The client player renders video in milliseconds without waiting for the next GOP cycle.
4. Slow Consumer Isolation & NeedsIFrame Recovery
If an individual subscriber cannot consume frames fast enough (e.g. a mobile client on a degraded cellular connection):
- Non-Blocking Enqueue: The buffer pushes frames using
select ... default. - Frame Drop: If the subscriber's channel is full, the frame is dropped immediately, ensuring the ingestion goroutine is never blocked.
- Metric Tracking: The atomic counter
ruseon_ringbuffer_drops_totalis incremented. NeedsIFrameFlag: The subscriber is flagged withNeedsIFrame = true.- Clean Recovery: The buffer will discard all subsequent P-frames for that subscriber until the next clean KeyFrame arrives. This prevents visual artifact distortion (green smearing / torn frames) on the client player.