fix(codec): bound keyframe bursts with VBV and microsecond time_base
The first real sender/receiver run failed permanently: the receiver reported 'non-existing PPS 0' for every frame. Without a VBV, a 2256x1504 IDR keyframe bursts hundreds of kilobytes of back-to-back FU-A packets, overflowing the ~208KB default UDP receive buffer; the resulting sequence gap made the depacketizer drop whole keyframes including their in-band SPS/PPS, so the decoder never initialized and never recovered, because every keyframe burst overflowed again. - Encoder: add rc_max_rate = bitrate and rc_buffer_size = bitrate*2/fps, capping any single frame to about two frame periods of bytes (~40KB at the 4Mbps default). - Encoder: switch the time_base to microseconds. It was derived from the configured frame rate, which quantized capture-rate timestamps and duplicated pts; RTP timestamps are now lossless. - Transport: request a 4MB SO_RCVBUF on the receive socket (best-effort; the kernel clamps to net.core.rmem_max). meson test 4/4, valgrind clean (loopback + codec).
This commit is contained in:
+10
-2
@@ -59,8 +59,16 @@ Two terminals on the same desktop session:
|
||||
```
|
||||
|
||||
Expected: the receiver window shows the captured desktop in near real time.
|
||||
Stop either side with Ctrl-C. Optional flags: `--port`, `--peer HOST[:PORT]`,
|
||||
`--bitrate KBPS`, `--target window`.
|
||||
If the receiver starts after the sender, a few `non-existing PPS` decode
|
||||
errors are normal until the next keyframe arrives (the GOP is ~0.4s);
|
||||
video should appear within a second. Stop either side with Ctrl-C.
|
||||
Optional flags: `--port`, `--peer HOST[:PORT]`, `--bitrate KBPS`,
|
||||
`--target window`.
|
||||
|
||||
Notes: the encoder runs a VBV that caps keyframe bursts to roughly two
|
||||
frame periods of bytes, and the receiver requests a 4MB UDP receive
|
||||
buffer (clamped by `net.core.rmem_max`). For very high `--bitrate`
|
||||
values, raise `net.core.rmem_max` on the receiver machine.
|
||||
|
||||
The headless equivalent runs as part of `meson test` (`udp loopback` test):
|
||||
synthetic frames → encode → packetize → localhost UDP → depacketize →
|
||||
|
||||
Reference in New Issue
Block a user