webrtc jitterbuffer--buffer草稿
webrtc的jitterbuffer按照功能分類的話,可以分為jitter和buffer。buffer主要對丟包、亂序、延時到達等異常情況做處理,還會和NACK、FEC、FIR等QOS相互配合.jitter就是trendline算法的jitter.
為什么要有jitterbuffer:
假設40ms一幀,1s 25幀. 發送時間序列0,40,80,120,160,200ms。網絡延時100ms;接收序列:100,140,200,240,280,300,400ms.
如果沒有jitterbuffer則在180ms發生卡頓,因為幀沒有到。
所以先緩存一段最大延時,然后播放,后面就再也不會有卡頓了。
那么最大等多久呢?不會造成任何幀卡頓。決定延時的兩個因素:網速和路由器buffer。
用最大幀測試這兩個值得到的就是max的jitterbuffer. 即每幀都不會超過這個時間到達。那么之后就在不會卡頓了。
第一部分 新版jitter buffer
整體結構:
- PacketBuffer:負責幀的完整性,保證組成幀的每個包序列號連續,并且有一個包標識幀的開始,有一個包標識幀的結束;
- RtpFrameReferenceFinder:幀參考關系尋找.負責給每個幀設置好參考幀,同時兼顧GOP內各幀的連續性;
- FrameBuffer:幀緩存.負責幀的連續性和可解碼性,這里幀的連續性是指某幀的所有參考幀都已經收到,幀的可解碼性是指某幀的所有參考幀都已經被解碼;
VCMJitterEstimator:計算抖動(googJitterbufferMS),用于計算目標延遲(googTargetDelayMs),用于音視頻同步;
VCMTiming:計算當前延遲(googCurrentDelayMs),用于計算渲染時間。
JitterBuffer流程圖
PacketBuffer:就是一幀的包亂序,在這個把一幀的包收集全了,幀完整在給下一環節
RtpFrameReferenceFinder:是保證幀的順序,把來的完整的幀排序,不產生幀順序錯誤。
同時設置參考幀,當前幀把前一幀設置成參考幀.
FrameBuffer 也設置參考幀不知道why? 它還會獲取jitter值,編碼器從這里獲取幀和jitter值
1)RtpVideoStreamReceiver類收到RTP包后,交給PacketBuffer類緩存、排序
2)PacketBuffer收集滿1個完整的幀后,交還給RtpVideoStreamReceiver類,RtpVideoStreamReceiver類將一個完整的幀交給RtpFrameReferenceFinder。
3)RtpFrameReferenceFinder類緩存最近的GOP,每個完整幀落在一個GOP中會填充好該幀的參考幀,交還給RtpVideoStreamReceiver。
notes:P幀的前一幀就是參考幀
4)RtpVideoStreamReceiver將填充好參考幀的完整幀交給FrameBuffer
5)?FrameBuffer判斷某幀的所有參考幀都收到認為該幀連續,在某幀的所有參考幀都解碼后認為該幀可以解碼,從而可以交給解碼器。?
notes:保存一個GOP的所有frame。如果參考幀已經解碼,說明這幀可以放入解碼器了
JitterBuffer的這些模塊分三個層次:分別做了RTP包的排序,GOP內幀的排序,GOP之間的排序??
- 包的排序:PacketBuffer;
- 幀的排序:RtpFrameReferenceFinder;
- GOP的排序:FrameBuffer。
notes:GOP排序?應該是一個GOP內部的事情
4.8 總結
PacketBuffer::InsertPacket向包緩存插入RTP數據,并觸發幀完整性檢查;
PacketBuffer::PaddingReceived處理空包,并觸發幀完整性檢查;
PacketBuffer::UpdateMissingPackets,更新丟包信息,用于檢查P幀前面的空洞;
PacketBuffer::PotentialNewFrame,判斷包的連續性,只有連續的包才檢查幀完整性;
PacketBuffer::FindFrames,幀完整性檢查,如果得到完整幀,則通過OnAssembledFrame回調上報
參考:WebRTC視頻JitterBuffer詳解_一朵喇叭花壓海棠的博客-CSDN博客_jitterbuffer
WebRTC視頻接收JitterBuffer_StoneLiu999的博客-CSDN博客
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
第二部分:舊版webrtc:VCMJitterBuffer 實現原理
Buffer?decodable_frames_和incomplete_frames_
這里介紹的是播放器的jitterbuffer
decodable_frames_存儲可以解碼的幀(比如關鍵幀或者前序完整的P幀);
incomplete_frames_存儲暫時不能解碼的幀:(1)本身rtp包不完整的幀.(2)依賴的參考幀不完整的幀
為了更便于理解jitter的存儲機制,用以下的邏輯存儲格式來描述
每個方格為一幀數據vcmframe。
- 綠色表示可解碼幀(圖中1、2),存儲在decodable_frames_
- 紅漸變色表示rtp包不完整的幀(圖中3、4),存儲在incomplete_frames_
- 紅色表示rtp包完整,但是依賴的參考幀不完整(圖中5、6),存儲在incomplete_frames_
- 白色表示還未接收到的包(圖中7),存儲在missing_sequence_numbers_
從圖中可以看出,未接收到包的重要程度是不同的,11的重要程度大于14,11的不完整影響了12和13的解碼。因此在網絡擁塞時,可以根據未接收到包的重要程度來優先發送nack請求,盡可能使靠近關鍵幀的包接收完整。必要情況下可以丟棄重要程度低的nack請求
Buffer 流程圖
?buffer對接收到的rtp包的處理流程如下:
- 第一次接收到一個視頻包,從freeframes隊列中彈出一個空frame塊,用來放置這個包。
notes:新包分配一個新frame buffer - 之后每次接收到一個RTP包,根據時間戳在incompleteframes和decodableframes中尋找,看是否已經接收到過相同時間戳的包。
如果找到,則彈出該frame塊,否則,從freeframes彈出一個空frame。
notes:同一幀的包使用相同的frame buffer - 根據包的序列號,找到應該插入frame的位置,并更新state。
其中state有empty、incomplete、decodable和complete,empty為沒有數據的狀態,incomplete為至少有一個包的狀態,decodable為可解碼狀態,complete為這一幀所有數據都已經到齊。 - 根據不同的state將frame幀 push回到隊列中去。
其中state為incomplete時,push到incompleteframes隊列,
decodable和complete狀態的frame,push回到decodableframes隊列中
notes:收到包之后檢查,如果一個幀的所有包都收到了,就放入decodableframes隊列。否則,仍在incompleteframes隊列 - freeframes隊列有初始size,freeframes隊列為空時,會增加隊列size,但有最大值。
也會定期從incompleteframes,decodable隊列中,清除一些過時的frame,push到freeframes隊列
notes:釋放過時的frame給回到freeframes 隊列. - 解碼線程取出frame,解碼完成之后,push回freeframes隊列。
notes:解碼完成的frame放回到freeframes隊列
jitterbuffer與QOS策略聯系緊密,比如,incompleteframes和decodable隊列清除一些frame之后,需要FIR(關鍵幀請求),根據包序號檢測到丟包之后要NACK(丟包重傳)等。
webrtc源碼分析(6)- jitter delay計算詳解 - woder - 博客園
源碼解析:webrtc QOS方法八(JitterBuffer)_CrystalShaw的博客-CSDN博客
總結
以上是生活随笔為你收集整理的webrtc jitterbuffer--buffer草稿的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: webrtc jitter buffer
- 下一篇: 计算机连接游戏手柄,电脑如何使用手柄_电