WebRTC之視頻NackModule

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),當超過最大重試次數時,不再請求此序號

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容