4. 在分层编解码器中应用于解码顺序恢复 (Application to Decoding Order Recovery in Layered Codecs)
RTP 流中的数据包通常采用预测编码, 接收方必须先将数据包排列成特定顺序, 才能解码媒体数据. 根据负载格式的不同, 解码顺序可能在 RTP 负载头部中作为字段显式指定, 或者接收方可能按 RTP 时间戳顺序解码数据包. 如果使用分层编码, 媒体数据会分布在多个 RTP 流中, 那么在能够解码基础层之外的其他层之前, 往往必须精确同步构成不同层的 RTP 流. 这类分层编码的示例包括 NI-T 模式 [AVT-RTP-SVC] 下的 H.264 SVC, 以及 MPEG 环绕多声道音频 [RFC5691]. 如第 2 节所述, RTP 中可以实现这种同步, 但要快速完成并不容易. 下文说明如何使用第 3.3 节定义的扩展来同步分层流, 并提供基于公共时间戳的解码顺序.
4.1. 用于解码顺序恢复的带内同步 (In-Band Synchronisation for Decoding Order Recovery)
当使用分层, 多描述或多视图编解码器, 并且媒体的不同组成部分在单独的 RTP 流上传输时, RTP 发送方 SHOULD 周期性且同步地带内传送同步元数据, 以允许接收方快速且准确地同步分层媒体流的各个独立组成部分. 这包含三部分:
-
发送方必须协商使用第 3.3 节所述的 RTP 头部扩展, 并且必须周期性且同步地把这些头部扩展插入组成分层, 多描述或多视图流各个独立组成部分的所有 RTP 流中.
-
同步插入要求发送方把这些 RTP 头部扩展插入到所有流中与完全相同采样时刻对应的数据包内. 由于每个流的头部扩展都在完全相同的采样时刻插入, 它们将具有相同的 NTP 格式时间戳, 因而允许接收方精确对齐各组成流的 RTP 时间戳. 如果某些组成 RTP 流中包含的采样时刻在其他流中不存在, 则可能需要向其中一些组成 RTP 流插入额外的数据包. 例如, 分层视频编解码器中的各层具有不同帧率时就可能出现这种情况.
-
发送方插入头部扩展的频率会直接对应同步延迟. 插入越频繁, 每个流的开销越高, 但同步延迟越低. RECOMMENDED 发送方至少在媒体的每个随机访问点向所有组成 RTP 流同步插入一次头部扩展, 但也 MAY 更频繁地插入.
发送方 MUST 继续发送包含 SR 数据包的周期性 RTCP 报告, 并且 MUST 确保 RTCP SR 数据包中的 RTP 时间戳到 NTP 格式时间戳的映射, 与 RTP 头部扩展中使用的映射一致. 接收方应将 RTCP SR 数据包中包含的信息以及 RTP 和 NTP 格式时间戳的带内映射都作为同步过程的输入. 但 RECOMMENDED 接收方对收到的映射进行合理性检查并丢弃离群值, 以增强对无效数据的鲁棒性. 有人可能认为 RTCP SR 映射更可能无效, 因为它们在不规则时间发送且受偏斜影响, 但损坏的 RTP 转换器也可能破坏 RTP 头部扩展中的时间戳. 接收方需要能够处理这两类故障.
4.2. 基于时间戳的解码顺序恢复 (Timestamp-Based Decoding Order Recovery)
一旦接收方使用第 4.1 节所述的 RTP 头部扩展同步了分层, 多描述或多视图流的各个组成部分, 就可以按如下方式基于同步后的时间戳推导解码顺序. 如果 RTP 负载头部中存在相关信息且需要使用, 也可以使用该信息推导解码顺序.
分层, 多描述或多视图流的各组成流之间可能存在显式依赖关系. 例如, 分层流通常按层次结构排列, 来自 "较高" 层的流必须等到 "较低" 层流中的对应数据已经收到并解码后, 才能解码. 如果存在这样的解码层次结构, 则 MUST 通过带外方式进行信令传递. 例如, 使用 SDP 信令时可以使用 [RFC5583].
每个组成 RTP 流 MUST 包含与其所依赖的 RTP 流中所有采样时刻对应的数据包. 如果 RTP 流中自然不存在这些数据包, 发送方 MUST 根据需要生成额外数据包以满足此规则. 这些数据包的格式取决于所使用的负载格式. 对于 H.264 SVC, 应使用空网络抽象层 (Network Abstraction Layer, NAL) 单元数据包 [AVT-RTP-SVC]. 流也可以包含与其所依赖流中不存在的额外采样时刻对应的数据包.
接收方应按如下方式解码所有组成 RTP 流中的数据包:
-
对每个流中的每个 RTP 数据包, 使用 RTP 头部扩展和 RTCP SR 数据包中包含的映射, 推导与其 RTP 时间戳对应的 NTP 格式时间戳.
-
将所有组成流中具有相同计算所得 NTP 格式时间戳的 RTP 数据包分组到一起.
-
按 NTP 格式时间戳升序处理各组, 并根据已信令传递的 RTP 流解码层次结构解码每组中的 RTP 数据包. 也就是说, 先把所有其他流所依赖的流中的 RTP 数据包数据传递给解码器, 然后传递下一个依赖流中的数据, 依此类推. RTP 流层次结构的解码顺序可以通过 [RFC5583] 中定义的机制或其他方式指示.
注意, 解码顺序不一定与数据包传输顺序一致. 接收方需要按编解码器相关的时间量缓冲数据包, 以便所有必要数据包到达后再执行解码.
4.3. 示例 (Example)
图 7 所示示例涉及三个 RTP 流 A, B 和 C, 它们包含一个分层, 多视图或多描述媒体流. 在该示例中, 按 [RFC5583] 定义的依赖关系信令指示流 A 是最低 RTP 流. 流 B 是下一个更高的 RTP 流, 并依赖 A. 流 C 是三个 RTP 流中最高的流, 并依赖 A 和 B. 所使用的媒体编码结构会导致视频访问单元 (即编码视频帧) 出现在较高流中, 但并不出现在所有较低流中. 流 A 的帧率最低. 流 B 和流 C 具有相同帧率, 且高于流 A. 图中显示了完整视频访问单元及其对应的 RTP 时间戳 "(x)". 这些视频访问单元已经按其 RTP 序列号顺序重新排序. 该图指示了每个 RTP 流中按解码顺序接收到的视频访问单元部分, 以及关联的 NTP 媒体时间戳 ("TS[..]"). 如图所示, 这些时间戳可以使用 RTCP 发送方报告中提供的 NTP 格式时间戳推导, 该时间戳以 "{x}" 标出. 它们也可以直接从 RTP 头部扩展中包含的 NTP 时间戳推导, 该时间戳以 "<x>" 标出. 注意, 这些时间戳并非递增顺序, 因为在此示例中, 解码顺序不同于输出或呈现顺序.
解码顺序恢复过程首先前进到与第一次可用的 NTP 时间戳同步插入相关联的视频访问单元部分, 该 NTP 时间戳位于 RTP 头部扩展中, NTP 媒体时间戳为 TS=[8]. 接收方从最高 RTP 流 C 开始, 在 RTP 流 A, B 和 C 的每个去抖动缓冲区中, 移除或忽略所有早于 TS=[8] 的视频访问单元部分, 这里的顺序按解码顺序计算. 然后, 从流 C 开始, 选择解码顺序中第一个可用媒体时间戳 (TS=[8]), 并按照 [RFC5583] 中定义的机制所指示的 RTP 流依赖顺序, 放置从 RTP 流 A 开始以及流 B 和 C 中的视频访问单元部分. 在 TS[8] 的示例中, 先将流 B, 再将流 C 放入与 NTP 媒体时间戳 TS=[8] 相关联的视频访问单元 AU(TS[8]) 中. 随后处理最高 RTP 流 C 中按出现顺序的下一个媒体时间戳 TS=[6] (RTP timestamp=(4)), 并重复上述过程. 注意, 某些视频访问单元可能不存在视频访问单元部分, 例如在最低 RTP 流 A 中, 见 TS=[5]. 假设用于生成 NTP 格式时间戳的源不存在时钟偏斜, 也可以在收到包含 RTP 时间戳与 NTP 格式时间戳映射的 RTP 发送方报告后启动解码顺序恢复过程, 该映射以时间戳 "(x){y}" 表示.
C:-(0)----(2)----(7)<8>--(5)----(4)----(6)-----(11)----(9){10}-
| | | | | | | |
B:-(3)----(5)---(10)<8>--(8)----(7)----(9){7}--(14)----(12)----
| | | |
A:---------------(3)<8>--(1)-------------------(7){12}-(5)-----
---------------------------------------decoding/transmission order->
TS:[1] [3] [8]=<8> [6] [5] [7] [12] [10]
Key:
A, B, C - RTP flows
Integer values in "()" - video access unit with its RTP timestamp as
indicated in its RTP packet.
"|" - indicates the corresponding parts of the
same video access unit AU(TS[..]) in the
RTP flows.
Integer values in "[]" - NTP media timestamp TS, sampling time
as derived from the NTP timestamp
associated with the video access unit
AU(TS[..]), consisting of video access unit
parts in the flows above.
Integer values in "<>" - NTP media timestamp TS as directly
taken from the NTP RTP header extensions.
Integer values in "{}" - NTP media timestamp TS as provided in the
RTCP sender reports.
Figure 7: Example of a Layered RTP Stream