From 57ab615973bc18ab601f3551576525662a24ed36 Mon Sep 17 00:00:00 2001 From: badbread Date: Sat, 8 Aug 2026 18:16:59 -0700 Subject: [PATCH] docs(cameras): sharpen the Uniview LPR entry to the precise fmtp root cause The entry described the H265 main as having NO a=fmtp. The live-restream investigation (2026-08-08) showed the camera's producer SDP DOES carry an a=fmtp with sprop-sps + sprop-pps but no sprop-vps; go2rtc, unable to build a complete HEVC parameter set, is what serves clients a fmtp-less SDP, which is the actual Media3 blocker. Correct the main note and the quirk detail to that, and note the repair is auto-detected per-camera from the served SDP and reached first by the client (so it starts fast). Removed the pre-existing em-dashes while here. Signed-off-by: badbread --- data/camera-compatibility.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/camera-compatibility.json b/data/camera-compatibility.json index 7f76d594..fee1731d 100644 --- a/data/camera-compatibility.json +++ b/data/camera-compatibility.json @@ -23,7 +23,7 @@ "streams": { "main": { "codec": "H265", - "notes": "The RTSP SDP advertises the H265 video track with NO 'a=fmtp' (no sprop-vps/sps/pps) — the parameter sets ship only in-band. Android's Media3 RTSP client requires fmtp and rejects the DESCRIBE with 'IllegalArgumentException: missing attribute fmtp' (confirmed on-device 2026-08-08). Also full-range (yuvj420p) with a 'PPS id out of range' bitstream quirk. All benign to ffmpeg, so server ingest, recording, desktop, and web are unaffected." + "notes": "The camera's RTSP SDP advertises the H265 main with an 'a=fmtp' that carries sprop-sps and sprop-pps but NO sprop-vps (HEVC needs VPS, SPS, and PPS). go2rtc cannot assemble a complete parameter set from that, so the SDP it SERVES to clients has no 'a=fmtp' at all. Android's Media3 RTSP client requires fmtp and rejects the DESCRIBE with 'IllegalArgumentException: missing attribute fmtp' (confirmed on-device 2026-08-08; producer-vs-served SDP confirmed against the live restream 2026-08-08). The main is also full-range (yuvj420p) with a 'PPS id out of range' bitstream quirk. All benign to ffmpeg, so server ingest, recording, desktop, and web are unaffected." }, "sub": { "codec": "H264", @@ -44,7 +44,7 @@ { "summary": "Android fullscreen HD live falls back to SD", "affects": ["android"], - "detail": "The confirmed blocker is the missing 'a=fmtp' in the H265 main's SDP: Media3's RTSP client throws 'missing attribute fmtp' at DESCRIBE, before any video decodes, and the tile drops to the H264 sub with an 'SD' badge. It is specific to this camera's stream, not to H265 in general: clean 4K H265 mains from other cameras play full HD on the same phone. Note the H264 '_subv' fmtp repair (an ffmpeg copy that recovers the parameter sets) does NOT translate to this H265 main: a copy-remux restores fmtp but go2rtc then bundles the VPS/SPS/PPS/SEI into an RTP Aggregation Packet at each keyframe, which Media3's RtpH265Reader cannot depacketize (androidx/media#1008) — so the copy only trades the fmtp rejection for a 'processAggregationPacket' crash (verified by packet capture 2026-08-08). Only a full-res H265->H264 transcode ('_mainv', opt-in via MAIN_REPAIR_TRANSCODE_ENABLED) yields an HD main this device can play. Server ingest, recording, desktop, and web are all unaffected." + "detail": "The blocker is that the SDP go2rtc SERVES for this main has no 'a=fmtp'. The camera's own fmtp is missing sprop-vps, so go2rtc cannot re-advertise a complete HEVC parameter set and drops it. Media3's RTSP client then throws 'missing attribute fmtp' at DESCRIBE, before any video decodes, and the tile drops to the H264 sub with an 'SD' badge. It is specific to this camera's stream, not to H265 in general: clean 4K H265 mains from other cameras, which include sprop-vps, play full HD on the same phone. The H264 '_subv' copy repair does NOT translate to this H265 main: a copy-remux restores fmtp but go2rtc then bundles VPS/SPS/PPS/SEI into an RTP Aggregation Packet at each keyframe that Media3's RtpH265Reader cannot depacketize (androidx/media#1008), so the copy only trades the fmtp rejection for a 'processAggregationPacket' crash (verified by packet capture 2026-08-08). Only a full-res H265->H264 transcode ('_mainv', opt-in via MAIN_REPAIR_TRANSCODE_ENABLED) yields an HD main this device can play. Crumb detects the condition per-camera from the served SDP and registers the repair only for a camera that needs it; with the repair on, the app reaches for the repaired main first, so it starts fast. Server ingest, recording, desktop, and web are all unaffected." } ], "recommended_settings": [