NackModule
一個(gè)包的最大請求次數(shù)是kMaxNackRetries(10)次候学,最大請求時(shí)間是10*rtt,在這個(gè)時(shí)間內(nèi)還沒有獲取到丟失的包則不再請求
對(duì)外提供的接口如下,源碼
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
數(shù)據(jù)走向:RtpReceiverImpl::IncomingRtpPacket
->RTPReceiverVideo::ParseRtpPacket
->RtpVideoStreamReceiver::OnReceivedPayloadData
->NackModule::OnReceivedPacket
- IncomingRtpPacket
數(shù)據(jù)從網(wǎng)卡過來盐捷,經(jīng)過上一層的分發(fā)(每個(gè)ssrc會(huì)對(duì)應(yīng)一個(gè)RtpReceiver實(shí)例)孽江,這里會(huì)根據(jù)payloadType得到對(duì)應(yīng)的視頻編解碼類型 - ParseRtpPacket
根據(jù)視頻編解碼類型調(diào)用對(duì)應(yīng)的RtpDepacketizer解析此包,得到幀類型(FrameType
)和幀信息(RTPTypeHeader
->RTPVideoHeader
)等信息 - OnReceivedPayloadData
添加ntp時(shí)間直接交付給nack模塊
- IncomingRtpPacket
- 所以到了nack模塊是可以知道此包是否是關(guān)鍵幀的包宣鄙,是否是一幀的第一個(gè)包袍镀,包序號(hào)等信息。
- 例如收到
1 2 3 6 7 4 5
等包冻晤,那么在收到序號(hào)為6的包的時(shí)候就認(rèn)為4和5這兩個(gè)包丟失了苇羡,具體可以閱讀AddPacketsToNack
這個(gè)函數(shù),然后把4和5兩個(gè)包加入到nack列表中(nack_list_)鼻弧,當(dāng)收到5這個(gè)包的時(shí)候從nack列表中移除 - 調(diào)用
GetNackBatch(kSeqNumOnly)
找到缺失的包序號(hào)设江,kSeqNumOnly選項(xiàng)觸發(fā)第一次nack請求,所以nack請求是非常及時(shí)的
ClearUpTo
此函數(shù)最終是由幀緩觸發(fā)的FrameBuffer::InsertFrame
攘轩,幀緩沖只保留kMaxFramesBuffered
幀叉存,并且當(dāng)幀是亂序的時(shí)候也不要此幀。清除到此序號(hào)的nack列表和關(guān)鍵幀列表UpdateRtt
更新rtt時(shí)間度帮,rtt是根據(jù)sr包的信息計(jì)算得到的歼捏,第一個(gè)包的nack觸發(fā)以后,后面的9次觸發(fā)都是依據(jù)rtt時(shí)間而定的笨篷。也就是說nack請求的間隔是nack1 rtt nack2 rtt nack3 ...
Clear
清空nack列表和關(guān)鍵幀列表TimeUntilNextProcess
獲取下一次執(zhí)行Processc
的時(shí)間甫菠,每隔kProcessIntervalMs(20ms)檢查一次Process
依據(jù)rtt找到當(dāng)前需要發(fā)送的nack序號(hào),并遞增nack的重試次數(shù)(retries)冕屯,當(dāng)超過最大重試次數(shù)時(shí)寂诱,不再請求此序號(hào)