Address several stream socket review findings on the transport, its
consumer client and the wire protocol:
- ParseAllowedUids rejects negative, out-of-range and non-round-tripping
uids instead of wrapping or truncating them (e.g. 2^32 no longer
becomes uid 0).
- StreamSocketClient backs off after a connection the producer closes
before any message, so a rejected consumer (uid allow-list, client
limit) no longer busy-loops; a rejection is not reported as a
disconnect.
- SendMedia drops packets for a stream that has no announced HELLO, and
ClearAudioParams forgets a previously announced audio stream (bumping
the generation and re-issuing the surviving video HELLO), so a stale
audio HELLO is never replayed and media never precedes its HELLO.
- Header pts_us is encoded as signed (two's-complement) microseconds so
negative and AV_NOPTS_VALUE timestamps survive the wire; the dump tool
decodes it as signed and tracks sequence gaps per generation so a
generation reset is not mistaken for packet loss.
Tests cover the uid rejections, the audio HELLO clearing and media
guard, the connection-rejection backoff, and signed pts round-trips.
refs #5143
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T4UcdJLt1bxwdpcigGxZRD
Wire the monitor lifecycle events into zmc. Monitor::SetState() replaces
the scattered shared_data->state assignments in Analyse() and connect(),
publishing a state_changed event (with previous and new state id and name)
whenever the analysis state actually changes. Monitor::SendStreamHealthEvent()
emits the capture-fault edges and tracks the active fault for the snapshot;
the snapshot is refreshed on every state or health change and after a
successful prime, so a consumer connecting mid-fault learns current status.
zmc's capture loop emits the six health transitions once per edge:
connection failed/restored around connect(), prime_capture failed/restored
around PrimeCapture(), capture_failed on pre/capture/post failure, and a
single capture_resumed once the pipeline recovers. Because the stream
socket survives camera reconnects, these are observable exactly when media
has stopped. A small mutex guards the health fields shared between the
capture thread (health events) and analysis thread (state events).
Documents the EVENT frame in docs/stream_socket.rst and decodes it in
tools/zm_stream_socket_dump.py. Full build and ctest pass (121 tests).
refs #2875
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Small dependency-free python client for the monitor stream socket:
prints every message (HELLO TLVs decoded, MEDIA/KEYFRAME with flags,
sequence and pts, STATS counters) and flags sequence gaps. Used for
the live end-to-end verification; useful for consumer development
and field debugging.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>