diff options
| author | Luke Hoersten <[email protected]> | 2026-07-15 18:04:31 -0500 |
|---|---|---|
| committer | Luke Hoersten <[email protected]> | 2026-07-15 18:04:31 -0500 |
| commit | 6ee12595d339eeafc7fdc7dbb9ba4c4c757f3565 (patch) | |
| tree | f83470042963c24b2eef87b54d7d484ff0ca11be /main/stream_server.h | |
| parent | 55303088ea499017c75203eef71588d18609f124 (diff) | |
stream: instrument TCP-window decomposition (wire kbps, hdr_gap, pend_age)
Before touching CONFIG_LWIP_TCP_WND_DEFAULT, make the window question
decidable from the logs. New per-window metrics in the stream log,
/state, and stats struct:
- wire min/avg/max kbps: instantaneous throughput while each body
drained (jpeg_len/recv_us). Ceiling ~= TCP_WND/RTT, so it scales
with the window iff the window is the limiter.
- hdr_gap min/avg/max us: time blocked waiting for the next header
after finishing a body. Large = sender-paced; ~0 = receive path
is the bottleneck.
- pend_age min/avg/max us: publish->claim latency of painted frames.
Growing across windows = queue backlog building, the failure mode
that killed the previous WND=65535 attempt.
Together with recv/dec/paint the frame interval is now fully
decomposable: interval ~= hdr_gap + recv + pend_age + dec + paint.
Also stamp TCP_WND/TCP_MSS/RECVMBOX into the client-connect log line
so every capture is self-labeled with the config it ran under.
Diffstat (limited to 'main/stream_server.h')
| -rw-r--r-- | main/stream_server.h | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/main/stream_server.h b/main/stream_server.h index e2eba06..2562738 100644 --- a/main/stream_server.h +++ b/main/stream_server.h @@ -73,6 +73,22 @@ typedef struct { uint32_t last_paint_event_us_low; // last v1 frame's event_us_low, // 0 if none seen yet on this // boot or last frame was v0 + // TCP-window decomposition. Together with recv/dec/paint these account + // for the whole frame interval: + // interval ≈ hdr_gap (sender idle) + recv (wire) + pend_age (handoff + // queue wait) + dec + paint. + // wire = instantaneous throughput while the body drained (jpeg_len / + // recv_us). Ceiling ≈ TCP_WND / RTT — the definitive window-throttle + // metric: scales with CONFIG_LWIP_TCP_WND iff the window is the limiter. + uint32_t wire_min_kbps, wire_avg_kbps, wire_max_kbps; + // Blocked-with-nothing-to-read time between previous body completion + // and next header completion. Large → sender-paced (we are NOT the + // bottleneck); ~0 → back-to-back arrivals, receive path is the limiter. + uint32_t hdr_gap_min_us, hdr_gap_avg_us, hdr_gap_max_us; + // publish → decode-claim latency of painted frames. Healthy: bounded + // well under a frame interval. Growing window-over-window = latency + // backlog building (the failure mode that killed the last WND raise). + uint32_t pend_age_min_us, pend_age_avg_us, pend_age_max_us; } stream_server_stats_t; void stream_server_snapshot_stats(stream_server_stats_t *out); |
