WebRTC之视频NackModule

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/momo0853/article/details/87288580

NackModule

一个包的最大请求次数是kMaxNackRetries(10)次,最大请求时间是10*rtt,在这个时间内还没有获取到丢失的包则不再请求
对外提供的接口如下,源码

const int kDefaultRttMs = 100;
const int kMaxNackRetries = 10;
const int kProcessFrequency = 50;
const int kProcessIntervalMs = 1000 / kProcessFrequency;
int OnReceivedPacket(const VCMPacket& packet);
void ClearUpTo(uint16_t seq_num);
void UpdateRtt(int64_t rtt_ms);
void Clear();
int64_t TimeUntilNextProcess() override;
void Process() override;
  • OnReceivedPacket
    数据走向:RtpReceiverImpl::IncomingRtpPacket -> RTPReceiverVideo::ParseRtpPacket -> RtpVideoStreamReceiver::OnReceivedPayloadData -> NackModule::OnReceivedPacket
    • IncomingRtpPacket
      数据从网卡过来,经过上一层的分发(每个ssrc会对应一个RtpReceiver实例),这里会根据payloadType得到对应的视频编解码类型
    • ParseRtpPacket
      根据视频编解码类型调用对应的RtpDepacketizer解析此包,得到帧类型(FrameType)和帧信息(RTPTypeHeader -> RTPVideoHeader)等信息
    • OnReceivedPayloadData
      添加ntp时间直接交付给nack模块
  1. 所以到了nack模块是可以知道此包是否是关键帧的包,是否是一帧的第一个包,包序号等信息。
  2. 例如收到1 2 3 6 7 4 5等包,那么在收到序号为6的包的时候就认为4和5这两个包丢失了,具体可以阅读AddPacketsToNack这个函数,然后把4和5两个包加入到nack列表中(nack_list_),当收到5这个包的时候从nack列表中移除
  3. 调用GetNackBatch(kSeqNumOnly)找到缺失的包序号,kSeqNumOnly选项触发第一次nack请求,所以nack请求是非常及时的
  • ClearUpTo
    此函数最终是由帧缓触发的FrameBuffer::InsertFrame,帧缓冲只保留kMaxFramesBuffered帧,并且当帧是乱序的时候也不要此帧。清除到此序号的nack列表和关键帧列表

  • UpdateRtt
    更新rtt时间,rtt是根据sr包的信息计算得到的,第一个包的nack触发以后,后面的9次触发都是依据rtt时间而定的。也就是说nack请求的间隔是nack1 rtt nack2 rtt nack3 ...

  • Clear
    清空nack列表和关键帧列表

  • TimeUntilNextProcess
    获取下一次执行Processc的时间,每隔kProcessIntervalMs(20ms)检查一次

  • Process
    依据rtt找到当前需要发送的nack序号,并递增nack的重试次数(retries),当超过最大重试次数时,不再请求此序号

猜你喜欢

转载自blog.csdn.net/momo0853/article/details/87288580