RTP传输视频数据的两个细节

最近接到一个工作,为视频会议的视频编码增加一种VP8格式。整个流程包括VP8的编码,封包,发送,接收,解包,解码。在学习这一部分的代码时,注意到两个细节:一,对于压缩后大于1000字节的视频数据进行了拆包,既把较大的视频数据封装成多个RTP包进行发送。二,视频数据并不是拆包后立即发出,而是进入一个队列,根据一定条件进行等待后再发出。
那么,为什么要进行这两个处理呢?

背景

视频数据的特征

观察项目中的音频数据,是并没有这两个处理的。那么音频和视频有什么不同呢?
音频数据是每20ms得到一帧数据,每一帧比较小。以48000K,单声道为例,48000 * 20 / 1000,也就960个采样,每个采样16位,也就1920字节,经过压缩,肯定是小于1000字节的。
而视频数据不同,视频的数据量远远大于音频(几十甚至上百倍),特别是关键帧,一帧数据压缩后依然非常大。也就是一瞬间,会产生大量的数据待发。

RTP通常是基于UDP的

另一方面,RTP(实时传输协议)虽然可以基于不同的网络,但为了提高实时性,还是基于UDP为多。我们项目中,就是基于UDP发送的。UDP是一个无连接,不保障的网络协议。

原因解析

为什么需要拆包

UDP能接受的最大包,大约是64K左右。如果向UDP发送一个大包,会在下层自动拆分成多个包(网络底层对于包大小是有限制的,大约1500字节。)。接收端把所有拆分包都收齐以后,重新组装成UDP大包,交给应用层。然而UDP是不可靠连接,包有可能丢。如果一个大包,需要在底层拆为10个包,那么10个包里的任意一个丢失,UDP包都无法组装,从而导致整个包被丢弃。所以,可以看出,越大的包越容易丢包。而如果在应用层拆为10个包发送,丢了其中一个,不管是重传,还是通过其他方式恢复,掩盖被丢掉的那一个,都比对整个大包进行处理更容易。

为什么需要等待

UDP没有流量控制,应用程序向UDP发起发送,UDP就会立刻把数据发出去。然而,如果此时接收端的缓存满了,虽然接收端收到了数据,但是因为没地方放,就会丢掉这个数据,形成丢包。而由于视频一帧,尤其是I帧的数据量很大,如果不进行等待,一股脑全丢给网络,则很容易出现接收端到收到了前几个包,而后几个包怎么也收不到的情况。所以在发送视频数据时,应当有等待机制,发送一定量的包后,稍微等待一下,再接着发剩下的包。

UDP vs TCP

在这里顺便补充一下UDP与TCP的差别

TCP UDP
数据 面向流 面向消息
连接 面向连接 无连接
顺序 保序 不保序
到达 保证到达 不保证到达
流量控制
拥塞控制
延迟

你可能感兴趣的:(rtp,udp,视频直播)