基于 RK3588S的自研编码器+ ZMS+WebRTC 服务器100ms以内的低延迟视频流媒体系统

摘要

在边缘计算与实时视频交互场景中,嵌入式设备实现 1080P@60 高帧率、超低延迟、多用户并发 的视频传输是典型挑战。本文介绍一套全自研视频流媒体系统:前端基于 Orange Pi 5(RK3588S) 搭载 USB 摄像头采集 MJPEG 流,利用 RK3588 MPP 硬件完成 MJPEG → H.264 的高效转换编码;中间层使用自研轻量级流媒体路由器 ZMS 进行协议转换与多路分发,CPU 消耗仅约 1%;后端对接 Go 语言自研的多路 WebRTC 服务器,支持同时服务多个浏览器客户端。实测数据:

  • RTSP 直接拉流 + RK3588 硬解码上屏:端到端延迟稳定在 70ms
  • WebRTC 浏览器播放:端到端延迟约 100ms(基于页面内时间戳差值实测)。
  • 有图有真相局域网webrtc延时截图101ms
    windows 自研播放器

全文阐述了 MJPEG 硬件转码、ZMS 极简路由、Go 多路 WebRTC 网关的工程实现与性能调优,为边缘实时视频交互提供高性价比、可落地的参考方案。

1. 背景与动机

实时视频在无人机巡检、远程操控、智慧安防等领域需求日益增长。传统 RTMP/HLS 方案延迟高(3~10 秒),难以满足交互型业务;而纯 WebRTC 方案在 ARM 边缘设备上往往过于臃肿。

1080P@60 高帧率 对边缘节点的编码、转发、传输提出了更高要求。本方案基于以下约束设计:

  • 采集源为通用 USB 摄像头,输出 MJPEG 格式(带宽友好,但无法直接用于低延迟 RTP 传输);
  • 边缘节点为 Orange Pi 5(RK3588S),具备强大的 H.264 硬件编码器,最高支持 1080P@60 实时编码;
  • 目标为 多浏览器客户端 并发播放 1080P@60,要求端到端延迟 ≤120ms。

我们设计并实现了 MJPEG 硬件转换 + 轻量级路由 + Go 多路 WebRTC 网关 的全链路方案。作为对比,纯 RTSP 拉流 + 本地硬解码上屏(如使用 RK3588 的硬件解码器)可达到 70ms 稳定延迟,而 WebRTC 方案实测约 100ms,完全满足交互需求。

2. 总体架构

┌─────────────┐    ┌────────────────────┐    ┌─────────────┐    ┌────────────────┐    ┌────────┐
│ USB Camera  │───▶│ RK3588S MPP        │───▶│   ZMS       │───▶│ WebRTC Server  │───▶│Browser│
│ (MJPEG)     │    │ MJPEG→H.264        │    │  Router     │    │   (Go, Multi)  │    │(Multi-│
│ 1080P@60    │    │ (hardware)         │    │ (CPU ~1%)   │    │                │    │client)│
└─────────────┘    └────────────────────┘    └─────────────┘    └────────────────┘    └────────┘
                                                    │
                                                    ▼
                                             RTSP direct path:
                                          ZMS → 自研播放器 → display
                                              (70ms latency)
  • MJPEG 采集与硬转码:V4L2 抓取 1080P@60 MJPEG 帧,通过 RKMPP 硬件解码为 YUV,再送入 H.264 编码器,输出 Annex‑B 格式。
  • ZMS 流媒体路由器:轻量级 RTSP 服务器,转发消耗仅约 1% CPU(1080P@60 实测),支持多路分发。
  • Go WebRTC 服务器:使用 Go 语言实现(基于 pion/webrtc 框架),支持多客户端并行会话,完成 RTSP→WebRTC 协议转换。
  • RTSP 直接路径:客户端直接 RTSP 拉流,FFMPEG深度优化解码上屏,延迟可低至 70ms。

3. 硬件平台:Orange Pi 5 + USB 摄像头(MJPEG 1080P@60)

Orange Pi 5 采用瑞芯微 RK3588S 芯片,其硬件编码器(H.264)支持 1080P@60 实时编码,硬件解码器支持 1080P@60 实时解码。USB 摄像头需支持 MJPEG 格式的 1080P@60 输出(例如 Logitech Brio 或工业 UVC 相机)。通过 V4L2 验证:

v4l2-ctl -d /dev/video0 --list-formats-ext | grep -A10 MJPG

预期输出包含 1920x1080 且帧率可达 60.0 fps。采集时设置 V4L2_PIX_FMT_MJPEG 以及 V4L2_CAP_TIMEPERFRAME 为 1/60 秒。

4. MJPEG 采集与 MPP 硬件转码(MJPEG → H.264,1080P@60)

4.1 V4L2 采集 MJPEG

struct v4l2_format fmt = {0};
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = 1920;
fmt.fmt.pix.height = 1080;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
fmt.fmt.pix.field = V4L2_FIELD_NONE;
ioctl(fd, VIDIOC_S_FMT, &fmt);

// 设置帧率 60fps
struct v4l2_streamparm parm = {0};
parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
parm.parm.capture.timeperframe.numerator = 1;
parm.parm.capture.timeperframe.denominator = 60;
ioctl(fd, VIDIOC_S_PARM, &parm);

采集缓冲区大小需适应 1080P MJPEG 典型尺寸(每帧约 200~500KB)。

4.2 MPP 解码 JPEG + 编码 H.264 的流水线优化

由于 1080P@60 数据率约为 60 帧/秒,单线程串行处理(解码+编码)可能成为瓶颈。采用 双线程流水线 + 双缓冲

  • 线程 A(解码):从 V4L2 获取 MJPEG buffer → MPP 解码为 YUV420 → 放入帧队列。
  • 线程 B(编码):从队列取 YUV 帧 → MPP 编码 H.264(输出 Annex‑B)→ 发送给 ZMS。

使用无锁环形队列(boost::lockfree::spsc_queue)传递帧指针,避免互斥开销。实测解码耗时约 3~5ms(1080P MJPEG),编码耗时约 7~9ms(1080P@60,码率 4Mbps),总 pipeline 延迟 <15ms,可稳定达到 60fps 输出。

4.3 编码器配置(低延迟)

关键参数:

  • rc_modeMPP_ENC_RC_MODE_CBR(恒定码率,避免码率波动引入缓冲)
  • gop:30(关键帧间隔 0.5秒,降低延迟)
  • profileMPP_PROFILE_AVC_HIGH
  • level:40(支持 1080P@60)
  • 关闭 B 帧(b_frame_num = 0
  • 设置 intra_refresh 为 1(低延迟编码模式)

输出流为 H.264 Annex‑B,通过本地 RTSP 推送给 ZMS。

5. ZMS 流媒体路由器(CPU ~1%,1080P@60)

关键性能数据:在 Orange Pi 5 上,ZMS 处理一路 1080P@60 H.264 流(约 4 Mbps)的 CPU 消耗实测约为 1~1.2%(单核利用率)。内存占用约 16 MB。

ZMS 内部无编解码操作,仅进行:

  • RTP 解包(从 RTSP 推流输入)或直接接收 Annex‑B;
  • 为每个 RTSP 拉流客户端独立生成 RTP 包(序列号/时间戳偏移);
  • 参数集缓存。

实测转发延迟(push_nalu 到 RTP 发送完成)小于 1ms,不成为瓶颈。

6. Go 自研 WebRTC 服务器(支持多路并发)

6.1 技术选型:Go + pion/webrtc

采用 Go 语言重构,原因:

  • 开发效率高,内存安全;
  • pion/webrtc 是成熟的纯 Go WebRTC 实现,支持 DTLS/SRTP/ICE;
  • 并发模型(goroutine)天然适合多会话管理。

架构

type WebRTCServer struct {
    sessions   map[string]*Session
    rtspClient *gortsplib.Client   // 单例,拉取 ZMS 的 RTSP 流
    videoTrack *webrtc.TrackLocalStaticRTP
    mu         sync.RWMutex
}

type Session struct {
    peerConnection *webrtc.PeerConnection
    videoSender    *webrtc.RTPSender
    inbound        chan *rtp.Packet   // 从全局解码器接收的 RTP 包
}

工作流程

  1. 服务器启动,建立 单个 RTSP 连接 到 ZMS(rtsp://zms:8554/live),调用 DESCRIBE 获取 SDP,SETUP TCP 传输,PLAY 开始接收 RTP 包。
  2. 接收 RTP 包后,通过 RtpDepacketizer 还原 H.264 NAL 单元,再通过 RtpPacketizer 为每个会话重新打包(每个会话独立序列号、SSRC)。
  3. 每个 PeerConnection 创建时,动态注册 Video RTPSender,将重打包的 RTP 包发送给对应的浏览器。
  4. WebSocket 信令处理:接收 Offer → 创建 Answer → 设置 LocalDescription → 返回 Answer。

6.2 多路并发关键设计

  • 单输入多分发:全局只有一个 RTSP 接收 goroutine,解码后的原始帧(NAL 单元)通过 sync.Cond 广播给所有会话的打包 goroutine。
  • 每会话独立 RTP 序列号:使用 pion/rtp 库,每个会话维护一个 sequencer
  • 发送隔离:每个会话的发送 goroutine 拥有独立的 channel 缓冲(容量 500 包),防止慢会话阻塞全局。
  • 会话数限制:可在配置文件中设置最大并发数(例如 8),超过返回 503

实测在 Orange Pi 5 上,支持 5 路 1080P@60 并发,每增加一路会话,CPU 增加约 4~6%(主要为 SRTP 加密和 RTP 打包)。总内存占用约 50MB + 每会话 5MB。

6.3 延迟优化

  • 关闭 WebRTC 的抖动缓冲(通过设置 peerConnection.ConfigurationSDPSemanticsSetRemoteDescription 后修改 jitterBuffer 参数,使用 pion 的扩展选项)。
  • 禁用音频,仅使用视频。
  • 直接使用 ZMS 传递的 RTP 时间戳(基于编码器时钟),不做平滑处理。
  • 强制使用 TCP 传输(RTSP 拉流),避免 UDP 丢包重传。

7. 性能实测(1080P@60)

7.1 RTSP 直接拉流解码上屏(基准)

若客户端直接通过 RTSP 拉流,利用 RK3588 硬件解码器(RKVDEC)解码并上屏(FFmpeg 硬解),端到端延迟包括:

  • 编码端:MJPEG 采集+转码 15ms
  • ZMS 转发 <1ms
  • 网络传输(本地) 2ms
  • 客户端硬解+渲染 50ms

实测平均延迟:70ms(多次秒表测量,标准差 5ms)。这是本方案能达到的最佳延迟,适用于对实时性极度敏感的场景(如无人机第一视角)。

7.2 WebRTC 端到端延迟(浏览器播放)

在相同环境下,WebRTC 路径增加:

  • Go 服务器 RTP 重打包 + DTLS 握手(首次连接) + SRTP 加密(每包)
  • 浏览器内部缓冲与渲染

实测平均延迟:约 100ms(基于页面内视频帧时间戳与系统时间差值计算,如截图所示)。帧率稳定在 59~60 fps,无丢帧。Frames rendered 计数器线性增长(截图显示从 118965 增长到 121506)。

7.3 资源占用(单路 1080P@60)

组件 CPU 占用 内存占用
MJPEG 解码+H.264 编码 18% 25 MB
ZMS 1.2% 16 MB
Go WebRTC 服务器 15% 35 MB
总计 34.2% 76 MB

多路(5 路浏览器并发)时:

  • ZMS CPU 不变(1.2%)
  • Go 服务器 CPU 升至 42%
  • 总内存约 120 MB

在 RK3588S 8GB 版本上,可稳定运行。

8. 关键技术点总结

项目 实现细节
原始格式 MJPEG (USB Camera)
转码 MPP 硬件解码 JPEG + 硬件编码 H.264 (1080P@60)
流媒体路由 ZMS (自研 C++),CPU 1.2%
WebRTC 服务器 Go + pion/webrtc,支持多路并发 (1080P@60)
RTSP 直接延迟基准 70ms (硬解码上屏)
WebRTC 浏览器延迟 100ms (基于实测截图)
开发语言 采集编码:C/C++ (V4L2 + MPP); 路由:C++; WebRTC 网关:Go

9. 结论

本文基于 Orange Pi 5(RK3588S)、自研 ZMS 流媒体路由器和 Go 语言多路 WebRTC 服务器,构建了支持 1080P@60 的超低延迟实时视频系统。通过 MJPEG 硬件转码链路、极低消耗的 ZMS(CPU 1.2%)、以及高效的多会话 WebRTC 网关,实现了浏览器端 约 100ms 的端到端延迟(截图验证),而纯 RTSP 硬解码路径可达 70ms。系统整体资源占用低,为边缘实时视频交互提供了高性价比、可落地的参考方案,欢迎探讨特定硬件和使用场景的100ms以内超低延时低价解决方案。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐