摘要

  • RFC 5371 规定,RTP Marker 在一帧的最后一个包上置一;当可伸缩画面分布在多条 RTP 会话时,每条会话都各自标记本会话对该帧的终点。因此单个 Marker 只关闭一条会话的发送边界。
  • 24 位分片偏移为每段数据提供相对于 codestream 起点的绝对坐标,即使某条图层会话看到的首包从非零位置开始。坐标能暴露空洞,却不能填补空洞或证明主头、其他层和解码结果完整。
  • T、MHF、基线下应被忽略的 mh_id 与优先级共同说明:字段必须连同有效性、扩展契约和接收端结果保存,不能把名字或数值当成跨层事实。

第一个终点只属于第一条会话

RTP 的 Marker 位很容易被监控系统解释成“帧结束”。在单会话里,这个近似往往够用:最后一个包把 Marker 置为一,接收端据此知道发送方对这帧的本会话贡献已经结束。

RFC 5371 允许使用多条 RTP 会话承载可伸缩视频。同一 JPEG 2000 画面的不同层可以在不同会话中传送。规范明确要求,每条会话都在自己对该帧的最后一个包上置一。

于是,同一帧会有多个合法终点。基础层先结束,增强层仍在路上;或者增强层先收到终点,基础层内部却丢了一个关键包。Marker 没有撒谎,只是观察系统扩大了它的主语。

要判断整帧是否完成,系统必须先知道本帧预期有哪些会话和图层,再逐条检查终点与内部覆盖。没有图层清单,连“还缺一条会话”都无法表达。

更重要的是,所有 Marker 都到达也不等于所有包到达。终点可以越过内部空洞抵达。结束边界与连续覆盖是两份证据。

完成必须先回答“完成什么”

对于某些业务,基础层足以维持服务;增强层丢失只构成降级。对于另一些业务,约定质量要求所有层到齐。协议不能替产品决定哪一种画面可接受。

因此至少存在四种不同的“完成”:发送方结束某条会话的本帧输出;接收方收到该会话的终点;预期图层的字节区间闭合;解码与显示满足服务目标。

Marker 只直接参与前两种。第三种需要分片区间与丢包证据,第四种需要解码器和显示端收据。

如果监控平台在第一个 Marker 到达时停止延迟计时,它会得到更漂亮的数字,却可能提前于增强层、重组和解码。如果平台等到所有已知会话,却没保存期望集合,新增图层后历史口径也会悄悄改变。

可审计的指标应把终点写成“session X 对 frame Y 的最后发送包已观察”,而不是笼统的“frame Y 完成”。

非零首偏移不是自动丢包

RFC 5371 的 24 位 fragment offset 从每幅 JPEG 2000 codestream 的第一个字节起算。它回答当前 payload 应放在完整画面的哪个字节位置。

在多会话分层传输中,一条会话收到的第一个包可以拥有非零偏移。这并不自动说明前面的包在这条会话中丢失,因为前段数据可能属于另一条会话。坐标系以共同画面为原点,而不是以单条会话为原点。

这也是为什么偏移必须和会话、图层、frame 身份一起保存。只看到非零起点而不知道分层契约,会把正常拆分误报成丢包;只看到另一条会话的零偏移而不知道缺失图层,又会把不完整交付误报为完整。

正确的数据结构是跨会话区间图:每段记录偏移、长度、字节哈希、RTP 序列、会话与图层。系统在共同坐标系上标出覆盖、空洞、重叠和冲突。

偏移能把缺口定位得很精确。它不能说明缺口为何产生,也不能证明缺口对解码无害。

小小的主头决定大量数据能否解释

RFC 5371 直言,主头丢失时图像无法解码。后续 tile 数据即使完整到达、偏移正确,也可能因为共同参数缺失而失去语法依据。

MHF 用两位描述当前 payload 是否含主头材料:零表示没有;一表示分片主头的非末段;二表示末段;三表示整个主头在当前 payload 内。

这些状态有利于检测依赖,却不是恢复结果。收到 MHF=2 只能证明末段来了,不能证明先前各段都来。收到 MHF=3 可以证明这个 payload 携带完整主头,不能证明 tile 数据和所有图层完整。

这说明“字节数量”不是影响大小。主头可能只占很小比例,却具有解释权。一个很小的头部空洞能使大量已收数据无法使用。

监控必须单独记录主头覆盖、解析结果、参数代际和解码器采用的状态,不能用总收包率替代。

mh_id 在基线契约里没有恢复权

payload 头里还存在三位 mh_id,名称像“主头标识”。但 RFC 5371 对只实现本规范的发送端说应把它设为零,对接收端说应忽略。

RFC 5372 才为主头补偿赋予额外规则:什么时候沿用同一标识、参数变化时怎样递增、回卷如何处理,以及接收端在何种条件下保存旧头。

因此,看到 mh_id=0 不能宣布“零号主头已恢复”。也不能因为代码解析出了这个字段,就默认 RFC 5372 扩展已协商。

字段位置属于格式,字段权力属于契约。格式可以为未来或伴随扩展预留位置;只有协商和实现事实才能激活它的意义。

审计记录应保存当前使用的是基线还是扩展、相关 SDP 参数、发送端赋值规则、接收端缓存代际以及补偿是否实际发生。

优先级字节不等于网络优待

RFC 5371 同样包含八位 priority。基线实现应把它设为 255,接收端应忽略。RFC 5372 才提供按进度、层、分辨率和分量计算优先级的模式。

一个名为 priority 的字段很容易被运营或销售解释为 QoS。可是在基线会话中,它没有调度权。即便 RFC 5372 已协商,字段也只是发送端表达的重要性;仍需证明网络队列读取了它、做了何种动作以及接收结果是否改善。

“已标优先”与“已获优先服务”至少隔着扩展协商、映射策略、调度行为和交付测量四步。

如果只保存字节值,后续系统会把保留的 255 误当作最高等级,进而生成完全倒置的服务报告。

字段名不能替代运行契约。服务等级不能由源端自报字段单独结算。

tile 数字也有失效条件

十六位 tile number 由 T 位控制。T=0 时有效;T=1 时必须忽略。

当 payload 只装主头时,没有 tile-part 可编号,发送端必须设 T=1。当一个 payload 混装多个 tile-part 时,一个数字无法代表全部,仍必须设 T=1。

位槽里可能仍出现零或别的值。那不构成“未知 tile”,而是“不适用”。把它写入 tile 统计会制造虚假的空间定位。

这类错误常发生在日志扁平化之后。原始消息里的条件关系被拆成独立列,聚合工具不知道某列受另一位控制。

保真采集应把门控和值作为一个类型:valid(tile=7) 或 invalid(reason=header-only/multi-tile)。不能先丢掉 T 再靠数值猜测。

packetization unit 保护边界,不保护到达

RFC 5371 把主头、tile-part 头和 JPEG 2000 packet 称为 packetization unit。发送端可以把多个单位放进一个 RTP 包,但必须维持 codestream 顺序。

如果某个单位连同网络头超过 MTU,可以分片。装着该单位分片的 payload 不能同时装下一个单位。这个约束让边界可恢复,避免解析器无法判断上一单位何时结束。

它是发送端构造规则,不是网络交付保证。RTP 序列号描述传输顺序,偏移描述 codestream 坐标,单位边界描述解析范围。三者分别回答不同问题。

包可以乱序后被正确重排,也可以顺序到达但中间缺失。字节可以连续却包含超出资源限制的参数。解析可以成功而显示质量不达标。

“顺序正确”只关闭一个检查点。不要让它签署整个媒体链。

交错扫描把“一帧”再拆成两份

tp 字段区分逐行、奇场和偶场。交错视频的 JPEG 2000 主头高度只表示完整显示画面的一半。接收端需要把先到的奇场与随后的偶场去交错组合。

因此,一条会话的 Marker 还可能只是某个场的终点语境。收到奇场不能证明偶场到达、时间匹配、去交错成功或最终画面显示。

SDP 中若没有 interlace,payload 必须逐行且 tp=0。若声明交错,包级 tp 仍要和协商一致。

监控应把场身份、共同 frame 关系、时间戳、配对结果和输出分别记录。用“最后包”直接累计显示帧数,会把半幅材料当成完整结果。

交错只是一个具体例子:协议对象的逻辑边界可能比传输边界更细,也可能更粗。计数前必须确认主语。

SDP 说的是能力包络

video/jpeg2000 要求声明 RTP clock rate 与采样/色彩空间。90 kHz 必须支持,其他频率可以支持;偏好非 90 kHz 时应同时提供另一个 90 kHz payload type 作为兼容选择。

width 与 height 是可选最大值,出现时必须成对。语法范围可到 2^32−1。这不表示接收端已经为最大尺寸分配内存,也不证明某个实际 frame 能被接纳。

offer/answer 选择声明的包络。随后仍要证明实际包符合参数、时钟正确、资源足够、解码器接受且输出可用。

“SDP accepted”属于控制面证据。“decoder admitted frame”属于运行面证据。把前者当后者,会在资源拒绝时错误地归因给网络。

未声明参数必须按契约处理,不能由监控平台用方便的默认值补成已知事实。

加密和认证没有替 codec 作证

RFC 5371 将保密、完整性和来源认证分开讨论。适当机制可以确认 RTP 包来自会话成员,并保护 payload 不被未检测修改。

被认证的成员仍可能发送错误偏移、无效门控、畸形 codestream 或超过资源策略的尺寸。完整性会忠实保存错误,不会把错误变正确。

丢失包也不会因为其邻包有认证而恢复。认证后的终点 Marker 仍只结束一条会话。

文档在 2008 年引用 SRTP、IPsec 和 RTP over TCP 的 TLS,属于历史上下文,不是对当前部署的配置证明。

安全收据应准确说明保护了谁、哪些字节和哪个会话。codec 收据则说明结构是否成立、资源是否接纳、输出是否生成。两者不能合并成模糊的“安全视频成功”。

QoS 标签也需要损失实测

RFC 5371 要求,即便使用增强 QoS,接收端也应监测丢包以验证所请求的服务是否实际交付。若没有,就应按 best effort 处理。

best effort 下还要根据损失调节码率、订阅层数,或在损失不可接受时退出会话。

这与多会话完成直接相关。某层消失可能是网络损失,也可能是拥塞控制主动退订。偏移图只显示缺少材料,适配日志解释决策来源。

如果运营系统不保存适配事件,会把负责任的降级误判为事故,或把事故包装成策略选择。

真正的 QoS 证据包括请求、观察到的损失、采取的动作以及接收结果。优先级字节和服务标签都不能单独完成这份证明。

RFC 9828 不拥有本篇的完成边界

后来的 RFC 9828 面向 sub-codestream latency,区分 Main Packet 与 Body Packet,并加入重同步、扩展序列、时间、质量和分辨率信号。它研究怎样在整幅 codestream 编码完成前开始发送。

BTW 已有文章讨论 RFC 9828:早发首包不能证明接收恢复、完整质量或端到端显示时延。本篇不重复这个主题。

这里的问题是,同一幅画面分布在多条 RFC 5371 会话时,谁有权宣布整体完成,以及字段何时有解释权。它发生在“首包是否更早”之外。

RFC 5372 也不是自动继承,而是另一个扩展契约。它让 mh_id 与优先级获得额外语义,但仍需协商、实现和结果证据。

把三份 RFC 的字段拼成一条理想能力链,会得到一个不存在的部署。研究必须停在实际协议身份和可见事实处。

最小记录必须保存关系

Lu Heng 的 Minimum Initial Specification 在这里是一种公开说明的分析镜头。共同最低规范无需规定所有解码策略,却必须保存未来本地决策无法重建的关系。

最低记录包括:协商 payload;frame、会话与图层身份;序列、时间戳和 Marker;tp、MHF、mh_id、T、priority 与 tile;偏移、长度和字节区间;扩展模式;主头状态;解码与显示结果。

关系比数值更重要。Marker 属于某会话;offset 属于某 frame;tile 受 T 控制;priority 与 mh_id 受扩展控制;解码结果属于某个完整输入集合。

Reality Layers 给出停止推论的位置。Marker 是协议符号。终点包是传输观察。跨会话区间闭合是重组事实。解码帧是软件结果。显示质量是产品事实。

三条会话都可以诚实地说“我结束了”。只有证据系统有责任回答:我们期待的整体,究竟有没有完成。