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

国标的 RTP 负载是 PS 封装,不是裸 H.264。 一帧多出三十几个字节,但换来「音视频同包、能直接当文件存」。

📝 本节和前面几节的关系

上一节算的是「码率占多少」,这一节算的是「封装多花多少」。 Demo 把 I 帧、P 帧、小 P 帧的头占比都算一遍,看为什么帧越小越吃亏。

一、为什么非要套一层

裸 H.264 只能装视频。 而一路监控流里通常还有音频、有时还有报警和智能分析结果, 这些东西必须待在同一个流里,否则音画对不上。 PS(节目流)就是干这个的:它把多条流打成一个个包,每个包带时间戳, 播放器按时间戳把音视频重新对齐。 换成 ONVIF 那边:它用裸流,音视频各走一条 RTP,靠 RTP 的时间戳对齐。 两种做法都行,区别在「谁负责对齐」——PS 是封装层对齐,裸流是传输层对齐。 国标选 PS 还有一个非常实际的理由:PS 流直接落盘就是一个可播的文件。 所以历史回放的实现变得极简单——把 RTP 里的 PS 一段段倒出来拼起来就行,不用重新封装。

二、头开销:帧越小越吃亏

一个 PS 包的头大约三十几字节:PES 头 14、PS pack 头 14、系统头 6。 对 I 帧来说这可以忽略(四万字节里多三十四个),但对小 P 帧就不是了: 八百字节的帧,头占了百分之四还多。 这和第八章语音包的结论一模一样:固定头和负载的比例,决定了「压缩还有没有意义」。 所以实现上通常不「一帧一个包」, 而是把多个小 P 帧拼进一个 PS 包——为的就是摊薄这三十几个字节。 代价是延迟多了一个打包周期。 这个取舍在监控里很好做:监控对延迟的容忍是「几百毫秒」而不是「几十毫秒」, 所以攒包完全划算。 而视频会议就不行,那才需要 20 毫秒一个包。

三、动手 Demo:为什么要套一层 PS,代价是多少

一个四万字节的 I 帧,加上 PES 头、PS pack 头、系统头,再对比 I 帧、P 帧、小 P 帧的头占比。

frame, pes, pack, sys_h = 40000, 14, 14, 6
total = frame + pes + pack + sys_h
print(total, total - frame)

for name, size in (("I 帧", 40000), ("P 帧", 4000), ("小 P 帧", 800)):
    over = pes + pack + sys_h
    print(name, size, over, "%.2f%%" % (100.0 * over / size))

实跑输出:

--------------------------------------------------------------------
为什么要套一层 PS,代价是多少
--------------------------------------------------------------------
**国标的 RTP 负载不是裸 H.264,而是 PS 封装的**。**这一层包装不是白加的,下面算它的开销。**

  项目                       字节
  --------------------------------------
  **裸 H.264 帧**            **40,000**
  **PES 头**                 **14**
  **PS pack 头**             **14**
  **系统头(每包一次)**     **6**
  **封装后**                 **40,034**

**一帧多出 34 字节,占 0.085%。**
**对 I 帧来说可以忽略**;**但 P 帧小得多,比例就不一样了**:

  帧类型          帧大小         头开销     占比
  ----------------------------------------------------
  **I 帧**        **40,000**     **34**     **0.09%**
  **P 帧**        **4,000**      **34**     **0.85%**
  **小 P 帧**     **800**        **34**     **4.25%**

**第三行是关键**:**帧越小,固定头占比越高**,**这和第八章语音包的道理一模一样。**
**所以国标虽然允许「一帧一个 RTP 包」,实际实现往往把多个小 P 帧拼进一个 PS 包**,
**为的就是摊薄这三十几个字节。**

**PS 换来了什么**:

  好处                 具体
  --------------------------------------------------------
  **音视频同包**       **一个 PS 里能同时放视频和音频**
  **可带私有数据**     **报警、字幕、智能分析结果都能塞**
  **能当文件存**       **录像直接落盘就是一个可播的 .ps**

**第三行是它最实用的地方**:**国标的历史回放,本质就是「把 RTP 里的 PS 一段段倒出来拼成文件」**。
**而 ONVIF 那边用的是裸流,回放得自己重新封装**——**这是两套协议在设计取向上的又一个分岔。**

一帧多出 34 字节,占万分之八,对 I 帧可以完全忽略。 但第三行的小 P 帧就不一样了:头占了四个多点百分比。 这不是 PS 的锅,是所有「固定头 + 小负载」结构的共同问题—— 第八章的语音包、第四章的 RTP 包,全都栽在同一个地方。 所以「国标比 ONVIF 多一层封装所以更费带宽」这个说法只对一半: 多出来的绝对值很小,真正的影响是「它逼你把包攒大」,而攒包带来的是延迟。 这才是那一层封装真正的代价。

30 秒实验

  1. 算一下:一帧 800 字节、头 34 字节,头占比多少?(4.25%)
  2. 想一下:为什么历史回放用 PS 特别省事?
  3. 想一下:监控为什么能容忍「攒包带来的延迟」?

常见误区

  1. 以为「PS 是为了压缩」。 它不压缩,只是把多条流打成一个包。
  2. 以为「多一层封装会让带宽明显变大」。 绝对值很小,真正的代价是攒包带来的延迟。
  3. 以为「一帧一个包最好」。 小帧会被头吃掉,所以要攒包摊薄。
自测三问(点开对答案) 1. PS 换来了什么? —— **音视频同包、可带私有数据、能直接当文件存**。 2. 为什么小 P 帧的头占比高? —— **头是固定的三十几字节**,负载越小占比越高。 3. 为什么监控可以攒包而会议不行? —— **监控容忍几百毫秒,会议只容忍几十毫秒**。

下一节看 SDP:「用什么编码、往哪儿发」全写在那一小段文本里。

相关笔记