docs: 记录 RTSP 低延迟调研结论与 rtsp-client-android 集成决策

- AGENTS.md: RTSP 视频流章节重写——现状(ExoPlayer)、延迟根因分析、
  决策(弃用 ExoPlayer 视频渲染,集成 rtsp-client-android v5.6.5)、
  库的关键技术要点(零缓冲架构/仅TCP/H.265 FU/内置延迟统计/已知坑)
- TODO.md: 视频低延迟改造拆解为 7 个可执行任务
This commit is contained in:
2026-08-13 08:55:01 +08:00
parent e3ffb01485
commit d3b2ef1102
2 changed files with 38 additions and 2 deletions
+25 -1
View File
@@ -113,7 +113,31 @@ Yaw = (左履带 - 右履带) / 2
## RTSP 视频流
使用 `MediaPlayer` + `SurfaceView``ExoPlayer` 拉取 RTSP 流。视频层作为 UI 最底层背景,摇杆等控件覆盖其上(半透明)。
视频层作为 UI 最底层背景,摇杆等控件覆盖其上(半透明)。
### 当前实现(将废弃)
- 使用 **Media3 ExoPlayer + RTSP 扩展**`media3-exoplayer-rtsp:1.5.1`),实现见 `video/RtspVideoPlayer.kt`
- 已做:最小缓冲 LoadControl200/500/100/200ms、无回退缓存、时间优先)、RTSP 自动重连(指数退避 1s→30s)、`VideoCodec` 枚举(AUTO/FORCE_HW/FORCE_SW_H264/FORCE_SW_H265)→ `MediaCodecSelector`
- 默认 `MediaItem.fromUri(url)`,未自定义 `RtspMediaSource.Factory`Media3 默认 UDP 优先、收不到数据自动回退 TCP interleaved
### 延迟问题与决策(2026-08 调研结论)
- 现象:RTSP/TCP 延迟高、缓冲大;H.265 解码不高效
- **根因**:不是解码器也不是 TCP 协议本身,而是 ExoPlayer 播放器架构(缓冲水位 + presentationTime pacing 渲染同步)为"平滑播放"设计,非实时
- **决策**:弃用 ExoPlayer 的视频渲染路径,集成第三方库 **rtsp-client-android**alexeyvasilyevv5.6.5,纯 Kotlin 零缓冲直出架构)
- 库源码位于:`/tmp/rtsp-client-android`(工作区外临时目录,后续需拷入项目,见 TODO)
### rtsp-client-android 关键技术要点(集成时必读)
- 架构:RTSP **仅 TCP interleaved**(无 UDP)→ RTP 解析(H.264/H.265)→ `FrameQueue(60)` → MediaCodec 直解 → 立即渲染。**无播放时钟 pacing,帧到即解即渲染** = 零缓冲低延迟(宣传 20ms 解码延迟)
- H.265`RtpH265Parser` 支持 single NAL + FU 分片重组;**AP 聚合包未实现**(有 TODO
- 硬解优先,`MediaCodecUtils.getLowLatencyDecoder` 挑专用低延迟解码器,失败自动回退软解;`MediaCodecHelper.setDecoderLowLatencyOptions``KEY_LOW_LATENCY`
- 实验性 SPS 改写(仅 H.264):`maxDecFrameBuffering=1, numReorderFrames=0`,可砍半部分硬解器延迟
- **内置延迟统计**`RtspSurfaceView.statistics``videoDecoderLatencyMsec`(解码渲染)+ `networkLatencyMsec`(网络),无需自写埋点
- **已知坑**`RtspProcessor` 拼 CSD 顺序为 `sps+pps+vps`H.265 标准应为 VPS→SPS→PPS),多数硬解器容错,若 H.265 起播黑屏第一嫌疑在此
- 依赖:`androidx.media3:media3-exoplayer`(仅用工具类如 NalUnitUtil,可剔除)、`androidx.camera`YUV→BMP)、`org.jcodec`SPS 改写)
- 库活跃:2026-06 更新(v5.6.5),全库约 6300 行,无 JNI/无预编译 so,全量可改
---
+13 -1
View File
@@ -2,7 +2,19 @@
## 待办
- [ ] 视频进一步延迟优化:探索更激进的低延迟策略(跳过 Media3 ExoPlayer,直接使用 MediaCodec + SurfaceView
### 视频低延迟改造(进行中,分支 feature/rtsp-low-latency
- [ ] 集成 rtsp-client-android:将 `/tmp/rtsp-client-android/library-client-rtsp` 拷贝为本地模块(如 `rtspclientlibrary/`),替换 ExoPlayer 视频渲染
- [ ] Compose 封装:`RtspSurfaceView``AndroidView`,替换 `video/RtspVideoPlayer.kt``PlayerView`;保留现有 `VideoCodec` 枚举映射到 `DecoderType.HARDWARE/SOFTWARE`,设置界面 `video_codec` 选项复用
- [ ] 保留 RTSP 自动重连:rtsp-client-android 无内置重连,移植现有指数退避逻辑(1s→30s,URL/codec 变化重置)
- [ ] 接入延迟统计:`RtspSurfaceView.statistics``videoDecoderLatencyMsec`/`networkLatencyMsec` 显示到状态栏或日志,验证延迟改善
- [ ] 起播黑屏排查:若 H.265 起播黑屏,检查 `RtspProcessor` CSD 拼装顺序(sps+pps+vps,应为 VPS→SPS→PPS
- [ ] 可选:`FrameQueue(60)` 改小(10~20)进一步压缓冲;剔除 media3/camera 依赖(仅需 jcodec
- [ ] 删除 ExoPlayer RTSP 依赖与 `RtspVideoPlayer.kt` 旧实现(保留 `VideoCodec`/`VideoResizeMode` 枚举迁移)
### 其他
- [ ] 视频进一步延迟优化:探索更激进的低延迟策略(跳过 Media3 ExoPlayer,直接使用 MediaCodec + SurfaceView)——已由上方 rtsp-client-android 集成方案承接
## 已完成