📹 第十章 GB/T 28181协议原理
📄 一句话概括

非 SIP 域的设备要接进国标平台,中间必须有个网关做翻译。 翻译分三层:信令、媒体封装、地址端口。 每多转一层就多一份延迟和一份出错的机会——所以工程上的原则是「能少转就少转」。

📝 本节和前面几节的关系

上一节把 SDP 讲完了,那是「国标内部怎么说话」。这一节讲「跟外人怎么说话」。 ONVIF、RTSP、私有 SDK 都属于「非 SIP 域」,它们不会说 SIP,得有人替它们说。

一、网关到底转什么

先分清三件事,很多人把它们的成本混在一起: 第一件是信令翻译,把 RTSP 的 DESCRIBE/SETUP/PLAY 翻成 SIP 的 INVITE/ACK。 第二件是媒体重封装,把裸流 H.264 包成 PS 再塞进 RTP,或者反过来。 第三件是地址端口转换,设备在内网、平台在外网,得有人替它做 NAT 穿透和端口映射。 三件事的成本差着一个数量级: 信令翻译是「一秒钟几次」,媒体重封装是「一秒钟几百次」,地址转换是「一次会话一次」。 所以网关的 CPU 几乎全花在第二件上, 而排障时最常出问题的却是第一件——因为信令错了,后面什么都看不到。

二、转换的三种代价

第一种代价是字节:每重贴一层头,包就变长一点。 一千路 1080p 每帧一个包,每秒两万五千个包,每个包多二十几个字节,加起来就是每秒半兆。 第二种代价是延迟:网关要先收完一个包才能转,这就多了一次攒和发的时间。 单看很短,但级联三层就是三份。 第三种代价最隐蔽,是「可控性」:转过的流,原始时间戳往往被打乱, 出问题时你在下游抓包,看到的是网关重新打的时间戳,查不回源头。 所以规范的网关会保留原始 PTS,只在必要的地方改 RTP 时间戳的基准。 这一点在验收时很少有人问,出事时却最要命。

三、能少转就少转

同一个设备有三种接法,成本差很多: 设备自己支持国标,直连最省;只支持 ONVIF,得用接入网关;只支持私有 SDK,得用厂商的转码服务。 这三条路的排障难度是递增的: 直连时你只需要看两端的日志;过网关时你还要看网关的日志;过转码服务时你连码流参数都改不了。 一个实用建议:能用国标直连就别上网关。 网关真正的价值是「把老设备接进来」,不是「让新设备多绕一圈」。 还有一个常被忽略的点:网关是有状态的。它记着「哪个会话对应哪路流」,重启一次全丢。 所以做双机热备时,网关的会话表比配置文件更值得同步。

四、动手 Demo:协议网关把一路流搬过去,多花了几个字节

按四种常见的转换方式各算一遍:每包多几个字节、一千路每秒多搬多少兆。 最后再把「UDP 转 TCP」之后的丢包代价算出来,那个数会让人改变看法。

payload, fps, n = 1400, 25, 1000
for name, extra in (("RTP/UDP", 12), ("RTP/TCP", 16),
                     ("PS/TCP", 25), ("HTTP-FLV", 15)):
    per = payload + extra
    print(name, extra, "%.2f%%" % (100.0 * extra / payload),
          "%.1f MB/s" % (per * fps * n / 1e6))

loss, pps = 0.001, fps * n
print("每秒重传", pps * loss, "次,累计停顿",
      pps * loss * 0.2, "秒/秒")

实跑输出:

--------------------------------------------------------------------
协议网关把一路流搬过去,多花了几个字节
--------------------------------------------------------------------
**非 SIP 域的设备要接进国标平台,中间必须有个网关做翻译**。
**翻译不是免费的:每个包都要拆开、重贴一层头、再发出去。**
**这一节算的就是这层「重贴」的成本。**

  转换方式                    每包加      包长         开销占比      千路每秒
  ------------------------------------------------------------------------------------
  **原样转发(RTP/UDP)**     **+12**     **1412**     **0.86%**     **35.3 MB/s**
  **转 RTP/TCP**              **+16**     **1416**     **1.14%**     **35.4 MB/s**
  **转 PS/TCP(国标)**       **+25**     **1425**     **1.79%**     **35.6 MB/s**
  **转 HTTP-FLV**             **+15**     **1415**     **1.07%**     **35.4 MB/s**

**最后一列是最扎眼的**:**一千路 1080p、每帧一个包,每秒要搬过去 35 MB**,
**其中 0.5 MB 是网关自己贴上去的头。**
**换句话说,网关的网卡上有不到百分之二的流量是在运「信封」。**

**但真正让网关吃不消的不是这些字节,是包数**:
**千路每秒 25000 个包,网关要为每个包做一次状态查找**——**查的是「这个源地址对应哪一路会话」。**

**这张表还漏了一项**:**UDP 转 TCP 之后,丢包不再是「丢掉就算了」。**

  丢包率 0.1%、每秒 25000 个包 → 每秒约 25 次重传
  重传超时按 200 毫秒算 → 累计停顿 5.0 秒/秒,已超过 1 秒

**这一行算出来超过 1 秒,意思是「这条 TCP 连接根本跑不动」**:
**停顿时长会滚雪球,后面的包继续丢,重传继续排队。**
**这就是为什么国标的媒体传输首选 UDP**——**视频丢一帧可以掩盖,等一次重传就是肉眼可见的卡。**

**所以网关的正确做法是「尽量晚转」**:
**能整段共用一个 TCP 连接就别一包一连,能不改封装就不改封装。**
**每多一层转换,就多一次出错的机会和一段固定的延迟。**

开销占比那一列全在百分之二以内, 但千路每秒那一列是三万五千兆——量级一大,小比例也成了真金白银。 最后一行的算式要停一下: 丢包千分之一、每秒两万五千个包,就是每秒二十五次重传;每次等两百毫秒,累计停顿五秒。 「五秒每秒钟」这个结果本身就是荒谬的, 它说明这条 TCP 连接根本不可能跑起来——停顿会滚雪球,后面的包继续丢,重传继续排队。 这就是「国标的媒体传输首选 UDP」的真正理由:不是 UDP 更快,是 TCP 在这种场景下会崩。 视频丢一帧可以掩盖,等一次重传就是肉眼可见的卡。 注意这里的 200 毫秒是「设定的参数」不是实测值, 换个数结论会变,但「超出承载能力」这个方向不会变。

30 秒实验

  1. 算一下:1400 字节负载加 12 字节头,开销占比多少?(0.86%)
  2. 想一下:为什么网关的 CPU 大多花在媒体重封装上?
  3. 想一下:级联三层,延迟为什么是三份而不是一份?

常见误区

  1. 以为「网关只是转发,不改内容」。 它要重贴头、甚至重打时间戳,改得比想象多。
  2. 以为「UDP 转 TCP 更可靠所以更好」。 高码率下 TCP 会被重传拖死,可靠不等于可用。
  3. 以为「转过的流和原始流一样」。 时间戳常常被打乱,下游抓包查不回源头。
自测三问(点开对答案) 1. 网关要转的三件事是什么? —— **信令翻译、媒体重封装、地址端口转换**。 2. 为什么国标的媒体传输首选 UDP? —— **不是因为它快,是因为 TCP 在高码率、有丢包时会因为重传而崩**。 3. 为什么说网关的会话表比配置文件更值得同步? —— **网关是有状态的**,**重启丢会话表,正在跑的流全断**。

下一节看控制:云台指令两套协议根本对不上,转换时精度丢在哪。

相关笔记