webrtc笔记-媒体部分(丢包问题)

蓝皮鼠 蓝皮鼠 | 127 | 2022-07-05

一、现象

通话中语音断断续续,视频卡顿或丢失画面,造成这些现象的一个重要原因是数据包在传输过程中出现丢失,在后端处理中,可以通过一些算法对缺失的数据进行预估,减轻一些影响,例如视频可以用I帧、P帧预估一些丢失的P帧,语音可以添加舒适噪音数据,但效果较好的办法还是降低丢包率。

二、原因

丢包的原因是媒体数据传输为了保证实时性,使用了UDP作为传输层的RTP协议,UDP只提供尽量送达的服务,数据传输过程经过网络中众多的交换机、路由器等设备有很多情况会导致数据包丢失。

三、处理办法

1、NACK

丢包首选想到的解决办法就是让发送端重发,那就需要接收端告诉发送端丢了那些包。NACK也就是no ack,接收端发送NACK给发送端,告诉丢了那些包,发送端重发。voice使用NackTracker类存丢包的sequence_number信息,而vodie使用NackModule类。
voice的NACK算法:
当收到一个包时,与上次收到的包比较序列号IsNewerSequenceNumber,如果序列号大,那上次收到包到本次收到的包之间缺失的包,可以看做包延时或丢失,定义一个常量nack_threshold_packets_,规定本次收到包之前的临近的nack_threshold_packets_个包是延时,其余的包认为丢失,并更新NackList,对丢失的包SendNACK给发送端。
vodie的NACK算法:
与voice的原理差不多,视频的数据量大,I帧最重要的特点,算法需要尽量重传关键数据,定义常量kMaxPacketAge,规定本次收到包的临近的kMaxPacketAge个包有机会重传,定义kMaxNackPackets,规定当nack_list_超过kMaxNackPackets时,清楚nack_list_中的某些非关键帧,再将恢复帧也去除,在GetNackBatch函数内根据规定判断是包丢失还是包延时。
缺点及改进:
当网络拥塞严重时,延时包会增多,延时时长也会增加,算法可能会将很多延时包当做丢包,进而发NACK,这样会进一步增加网络拥塞,可以根据网络延时情况、网络丢包情况控制发NACK包的量(做个分段函数之类的),网络情况在计算jitterbuffer大小时有相关计算,可以引用。

2、FEC

丢包另一个解决办法是增加冗余,在发包的时候多发根据一定算法组合的冗余包,出现丢包时根据冗余包和收到的包反推丢失的包,这种办法算法复杂,还会增加带宽,丢包几率大时,丢冗余包几率也大,算法有效性降低。目前webrtc语音未增加FEC,视频RTPSenderVideo::SendVideo函数使用了FEC,UlpfecGenerator类发包时组RED包,UlpfecReceiver类解RED包。

文章标签: 流媒体协议
推荐指数:

真诚点赞 诚不我欺~

webrtc笔记-媒体部分(丢包问题)

点赞 收藏 评论