Camera Quirks Tolerance#4
Merged
Merged
Conversation
steelbrain
commented
Apr 27, 2026
Owner
- Adds diagnostic callback for consumers
- Changes previously-fatal errors to diagnostic logs now and keeps the stream going
Introduces RTSPDiagnostic (severity + message) and an optional onDiagnostic closure on RTSPClientSession.init. The first emitter: when a camera issues a new Session ID at audio SETUP that differs from the one returned at video SETUP, emit a .warning before rolling forward. Severity .error is reserved for cases where real data is dropped while the stream lives — distinct from a thrown RTSPError, which means the stream is dead.
H.264 and H.265 depacketizers previously returned a hard failure on a too-short payload (zero bytes for H.264, fewer than 2 bytes for H.265). That failure propagated up the AsyncThrowingStream and tore the session down. Some IP camera firmwares emit such packets — likely as keep-alives or simply buggy framing — and a single one ended an otherwise-healthy stream. Both codecs now treat too-short payloads as no-ops and return success. The session-level video pump emits an onDiagnostic .warning when an empty payload is observed so consumers can flag the misbehaving hardware. Severity is .warning rather than .error: an empty packet carries no real video data, so nothing was actually lost. .error stays reserved for cases where data we expected to deliver gets dropped. Matches GStreamer rtph264depay (silent debug-log skip) and Live555 (BufferedPacket discard); FFmpeg/retina/ gortsplib/pion/ExoPlayer all return errors here, but their callers vary on whether to abort. retina #115 already relaxed the FU-A inner check for the same class of bug; this extends the same leniency to the outer zero-byte case.
InorderParser previously threw on an out-of-order RTP sequence when the transport was TCP-interleaved; the UDP path silently dropped. The TCP-strict policy was inherited from upstream retina with no rationale beyond "TCP guarantees order." That justification confuses TCP byte-stream ordering (which is preserved) with RTP-sequence ordering (which is not). A buggy camera whose internal packetizer writes packets out-of-order before muxing onto the TCP pipe will deliver out-of-order RTP regardless of TCP. RFC 3550 §A.1 treats reordering as a normal case receivers MUST tolerate, and RFC 2326/7826 say nothing about RTP-sequence guarantees on interleaved transport. Both transports now drop out-of-order packets. On TCP this also emits an onDiagnostic .warning so consumers can surface the camera misbehavior; UDP stays silent because reordering on UDP is normal network behavior. Aligns with FFmpeg, GStreamer, Live555, gortsplib, and ExoPlayer — none of which abort on this case. retina itself has open issue #40 / PR #111 acknowledging the same class of bug. Test added: out-of-order TCP packet is dropped (no throw) and the diagnostic callback fires once with .warning severity.
Covers the 0.2.0 fix that swapped DepacketizeError("Empty
NAL" / "Short NAL") for .success(()): empty H.264 RTP
payloads, plus zero- and one-byte H.265 payloads, must
no longer tear down the session. Both depacketizers also
recover cleanly on a subsequent valid packet.
steelbrain
added a commit
that referenced
this pull request
May 30, 2026
A VPS/SPS/PPS NAL over 65535 bytes trapped building the HEVC record; reject it up front, mirroring the H264 guard. SimpleAudioDepacketizer frameLength now returns nil on an oversized payload instead of a precondition trap. Compute the H.265 conformance-window crop in 64-bit so malformed offsets can't wrap a 32-bit add to a wrong/zero size, and require the crop to leave a positive picture. Tighten bit_depth_*_minus8 to the spec range [0,6] (7/8 also collided with the reserved HEVC-record bit). Addresses audit findings #4/#19/#31/#32. Adds regression tests for the NAL-size and oversized-payload guards.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.