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:
@@ -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`
|
||||
- 已做:最小缓冲 LoadControl(200/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**(alexeyvasilyev,v5.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,全量可改
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -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 集成方案承接
|
||||
|
||||
## 已完成
|
||||
|
||||
|
||||
Reference in New Issue
Block a user