https://webrtcforthecurious.com/docs/06-media-communication/#adaptive-bitrate-and-bandwidth-estimation
RTP (Real-time Transport Protocol) 是传输媒体的协议。它的设计目的是允许实时传输视频。它没有规定任何关于延迟或可靠性的规则,但为您提供了实现它们的工具。RTP为您提供流,因此您可以通过一个连接运行多个媒体。它还为您提供了给媒体管道所需的时间和顺序信息。
RTCP(RTP Control Protocol) 是传递关于调用的元数据的协议。格式非常灵活,允许您添加任何想要的元数据。这用于传递关于调用的统计信息。它也被用来处理数据包丢失和实现拥塞控制。它为响应不断变化的网络条件提供了必要的双向通信。
视频压缩将视频编码成一种新的格式,这种格式需要更少的比特来表示相同的视频。
无损压缩需要传输更多的数据,会造成更大的延迟和丢包。因此一般采用有损压缩,视频质量不咋好
视频压缩有两种类型。第一种是帧内压缩。帧内压缩减少了用于描述单个视频帧的比特。同样的技术也被用于压缩静态图片,比如JPEG压缩方法。
第二种是帧间压缩。由于视频是由许多图片组成的,我们想办法不重复发送相同的信息。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X| CC |M| PT | Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Synchronization Source (SSRC) identifier |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| Contributing Source (CSRC) identifiers |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Payload |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Version (V)
Version is always 2
Padding §
Padding是控制负载(payload)是否有填充的bool值.
负载(payload)的最后一个字节 包含需要填充多少字节的数量。
Extension (X)
如果设置了,RTP报头将会有扩展。
CSRC count (CC)
CSRC是SSRC之后和有效载荷之前的标识符。
Marker (M)
标记位没有预先设置的含义,用户可以随意使用。在某些情况下,它是在用户说话时设置的。它也通常用于标记关键帧。
Payload Type (PT)
Payload Type 是该数据包所携带的编解码器的唯一标识符。
对于WebRTC,Payload Type是动态的。一次通话中的VP8可能与另一次不同。调用中的提供者在Session Description中确定有效Payload Type到编解码器的映射。
Sequence Number
Sequence Number用于对流中的数据包进行排序。每次发送一次数据包时,序列号加1。
RTP在有损网络上很有用。这为接收方提供了一种检测数据包何时丢失的方法。
Timestamp
此包的采样时间。这不是一个全球时钟,而是在媒体流中经过了多少时间。如果它们都是同一视频帧的一部分,几个RTP包可以具有相同的时间戳。
Synchronization Source (SSRC)
An SSRC is the unique identifier for this stream. 这允许您在单个RTP流上运行多个媒体流。
Contributing Source (CSRC)
传达SSRC对这个包的贡献的列表。
这通常用于谈话指标。假设在服务器端,您将多个音频馈送组合到单个RTP流中。然后,您可以使用该字段表示“输入流A和C正在此时交谈”。
Payload
实际有效载荷数据。如果设置了填充标志,则可能以添加的填充字节的计数结束。
The actual payload data. Might end with the count of how many padding bytes were added, if the padding flag is set.
Every RTCP packet has the following structure:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P| RC | PT | length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Payload |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Version (V) :Version is always 2.
Padding § :Padding is a bool that controls if the payload has padding.The last byte of the payload contains a count of how many padding bytes were added.
Reception Report Count (RC) :这个包中的报告数。单个RTCP报文可以包含多个事件。
Packet Type (PT)
RTCP数据包类型的唯一标识符。WebRTC代理不需要支持所有这些类型,代理之间的支持可以是不同的。这些是你可能经常看到的:
- 192 -Full INTRA-frame Request(FIR)
- 193 -Negative ACKnowledgements(NACK)
- 200 -Sender Report
- 201 -Receiver Report
- 205 -通用RTP反馈
- 206 -payload特定反馈
FIR和PLI消息都有类似的用途。这些消息请求发送方提供完整的关键帧。能够同时处理PLI和FIR包的软件在这两种情况下会以相同的方式工作。它将向编码器发送一个信号,以产生一个新的完整关键帧。
FIR请求关键帧的原因不是数据包丢失。例如,当一个新成员进入视频会议时。他们需要一个完整的关键帧来开始解码视频流,解码器将丢弃帧,直到关键帧到达。接收方在连接后立即请求完整的关键帧是一个好主意,这将最大限度地减少连接和图像显示在用户屏幕上之间的延迟。
PLI包是一种payload特定反馈消息。PLI适用于将部分帧提供给解码器,但解码器无法解码它们的情况。(因为你丢包太多或者解码器崩溃了)。当数据包或帧丢失时,用PLI。
NACK请求发送方重新传输单个RTP包。这通常是由于RTP包丢失引起的,但也可能因为延迟而发生。
NACK比重新发送整个帧更节省带宽。由于RTP将数据包分成非常小的块,所以实际上您只是请求了一小块缺失的数据包。接收端使用SSRC和序列号制作RTCP消息。如果发送方没有这个RTP包可以重新发送,它就会忽略该消息。
这些报告用于在两端之间发送统计信息。他传递了实际收到的数据包数量和jitter。该报告可用于诊断和拥塞控制。
也被称为FEC,另一种处理丢包的方法。FEC是指在没有被请求的情况下多次发送相同的数据。这是在RTP级别或者甚至更低的编解码器完成的。如果丢包是稳定的,FEC是一种延迟比NACK低得多的解决方案。请求再重新传输丢失数据包的往返时间对于nack来说是非常重要的。
主要思想是根据预测的、当前的和未来可用的网络带宽来调整编码比特率。这可以确保传输尽可能高质量的视频和音频信号,并且连接不会因为网络拥塞而中断。对网络行为建模并试图预测它的启发式方法被称为带宽估计。
RTP/RTCP运行在所有类型的不同网络上,因此,一些信息在从发送方到接收方的途中被丢弃是很常见的。由于构建在UDP之上,它没有内置的数据包重传机制,更不用说处理拥塞控制了。
为了给用户提供最好的体验,WebRTC必须估计网络的质量,并适应这些质量随时间的变化。要监视的关键特征包括:可用带宽(在每个方向上,因为它可能不是对称的)、往返时间和抖动(往返时间的波动)。它需要考虑数据包丢失,并随着网络条件的发展传达这些属性的变化。
这些协议有两个主要目标:
这些RTCP消息在RFC 3550中定义。Receiver Reports关注网络的通信质量(包括丢包、往返时间和抖动),它与其他算法配对,然后负责根据这些报告估计可用带宽。
发送方和接收方报告(SR和RR)一起描述了网络质量。它们根据每个SSRC的时间表发送,它们是估计可用带宽时使用的输入。这些估计是由发送方在接收到包含以下字段的RR数据后做出的:
sendertime1
包含在SR中。当接收端收到SR报文时,发送回RR。其中,RR包括刚从发送方接收到的sendertime1
。在收到SR和发送RR之间会有一个延迟。因此,RR还包括“自上次发送者报告以来的延迟”时间- DLSR(delay since last sender report)。DLSR用于稍后在流程中调整往返时间估计。一旦发送方收到RR,它将从当前时间sendertime2
中减去sendertime1
和DLSR
。这个时间增量称为往返传播延迟或往返时间。rtt = sendertime2 - sendertime1 - DLSR
谷歌拥塞控制(GCC)算法解决了带宽估计的挑战。它与各种其他协议配对,以满足相关的通信需求。因此,它非常适合在接收端(当使用TMMBR/TMMBN或REMB运行时)或在发送端(当使用TWCC运行时)运行。
为了估计可用带宽,GCC将数据包丢失和帧到达时间波动作为两个主要指标。它通过两个链接的控制器运行这些度量:基于损失的控制器和基于延迟的控制器。
t(i) - t(i-1)
:两组包(一般为连续视频帧)到达时间的差值。这些分组经常以固定的时间间隔分开(例如,对于一个24帧/秒的视频来说,每1/24秒一次)。因此,测量到达间时间就像记录第一个包组(即帧)的开始和下一个包组的第一帧之间的时间差一样简单。对于TMMBR/TMMBN和REMB,接收方首先估计可用的入站带宽(使用GCC等协议),然后将这些带宽估计传达给远程发送方。他们不需要交换关于丢包的详细信息或关于网络拥塞的其他质量,因为在接收端操作允许他们直接测量到达间时间和丢包。相反,TMMBR, TMMBN和REMB只交换带宽估计值:
假设我们开始时将比特率设置为1000 kbps。
编码器输出只有700kbps,因为没有足够的高频特征来编码。(又名“盯着墙看”。)
让我们再想象一下,接收机在零丢包的情况下获得700kbps的视频。然后应用REMB规则1将传入比特率提高8%。
接收端发送一个带有756 kbps建议值(700 kbps * 1.08)的REMB包给发送端。
发送方将编码器比特率设置为756 kbps。
编码器输出一个更低的比特率。
这个过程继续重复,将比特率降低到绝对最小值。
您可以看到这将导致编码器参数的大量调整,并且即使在良好的连接下也无法观看视频,使用户感到惊讶。
传输宽拥塞控制是RTCP网络状态通信的最新发展。它在draft-holmer-rmcat-transport-wide-cc-extensions-01中定义,但也从未被标准化。
TWCC使用了一个非常简单的原理:
使用REMB,接收端用可用的下载比特率指示发送端。它使用精确测量推断的数据包丢失和数据,只有它有关于数据包间到达时间。
TWCC几乎是SR/RR和REMB两代协议之间的混合方法。它将带宽估计带回发送端(类似于SR/RR),但其带宽估计技术更类似于REMB生成。
使用TWCC,接收方让发送方知道每个包的到达时间。对于发送方来说,这些信息足以测量包间到达延迟的变化,以及识别哪些包被丢弃或到达太晚而无法贡献到音频/视频提要。由于这些数据频繁交换,发送方能够快速调整变化的网络条件,并使用GCC这样的算法改变其输出带宽。
发送方跟踪发送的数据包、它们的序列号、大小和时间戳。当发送方从接收方接收RTCP消息时,比较发送方的包间延迟和接收方的延迟。如果接收延迟增加,则表明网络拥塞,发送方必须采取纠正措施。
通过向发送方提供原始数据,TWCC提供了实时网络状况的绝佳视图: