WebRTC中丟包重傳機制的實現

2021-08-19 19:11:11 字數 2489 閱讀 7212

當網路質量突然變的很差並開始丟包時,聲音聽起來音質會變差,畫面幀速會下降,甚至會完全卡住。我們可能需要某種機制來應對這種情況。在webrtc中,主要有兩種機制來應該網路變差的情況:

前向糾錯

:在每個資料報中,您將新增一些關於前乙個資訊的資訊,以防丟失,您需要重新構建它們(flexfec是webrtc [1]中的新格式)。

重傳:當接收方檢測到有丟包時,它會傳送nack型別的rtcp包給傳送方,傳送方會重發這些資料。

rtp接收方

丟包重傳的請求是由rtp接收方發起的。當rtp接收方檢測rtp包頭中的seq屬性發現有丟包時,丟包重傳機制就會啟用。但是,是否檢測到下乙個rtp包不是自己預期想要的哪個就會要求重傳呢?比如當前rtp序號是99,下乙個來的包序號是101,哪就是否意味著序號為100的包就丟了呢?由於rtp協議是基於udp的,而udp又是無序傳輸的。再下乙個包又可能就是序號為100的包。webrtc會以500毫秒週期性的檢測有沒有丟包,然後不斷請求重傳特定資料報,除非序列號為「超過10000 old」,列表中丟失的資料報數量大於1000,您已經詢問了相同的資料報10次,或者您有乙個新的可解碼的完整資料幀(任何依賴於其他幀的資料報都不丟失)。 

# code from nack_module.cc

on_packet(rtp):

#檢測丟包

if rtp.seq_num < newest_seq_num: # out of order or retransmnission

return

add_missing(newest_seq_num + 1, rtp.seq_num)

if rtp.is_first_packet_of_keyframe:

keyframes.insert(rtp.seq_num)

newest_seq_num = packet.seq_num

if nack = generate_nack(seq):

send_nack(nack)

#刪除過時的包

add_missing(from_seq_num, to_seq_num):

packets_lost.remove_older_than(10000) # max_packet_age (sequence numbers)

if packets_lost.size() > 1000: # max_size

packets_lost.remove_until_keyframe()

if packets_lost.size() > 1000: # still too big

packets_lost.clear()

sender.request_keyframe()

return

for seq_num in range(from_seq_num, to_seq_num):

packets_lost.insert(seq_num)

# 有乙個最新的可解碼完整幀,清空重傳佇列

cleanup_to(to_seq_num):

packets_lost.remove(seq_num < to_seq_num);

generate_nack(mode):

seq_nums =

for packet in packets_lost:

if packet.retries > 10: # max_retries

packets_lost.remove(packet)

if (mode == seq and packet.seq_num < newest_seq_num) or

(mode == time and packet.sent_at + rtt > now()):

seq_nums.insert(packet.seq_num)

packet.sent_at = now()

return seq_nums

every_20_msec():

if nack = generate_nack(time):

send_nack(nack)

#rtp_rtcp_impl.cc 傳送nack重傳rtcp包

send_nack(seq_nums):

if now - time_last_full_nack_sent < 1.5 * rtt:

seq_nums.filter(seq_num > seq_num_last_nack_sent)

else:

time_last_full_nack_sent = now

if seq_nums.length > 253:

seq_nums = seq_nums[:-253]

send(new rtcpnack(seq_nums))

rtp傳送方實現

rtp傳送方接收到nack重傳請求後會重傳所有的資料報嗎?webrtc是這樣實現的:

保留在最近1000毫秒(「歷史」)中傳送的資料報的副本。

當接收到nack時,如果歷史記錄中仍然有這個資料報,嘗試傳送資料報。

但...(rtp_sender.cc)

網路中丟包的原因及型別

網路中的丟包可以分為如下幾個型別 在阿里巴巴的網路中,超過60 的丟包是由流水線造成的 比如路由黑洞,acl規則,ttl為0,資料報長度超過mtu,等等 擁塞導致的丟包佔了10 左右,鏈路折損等原因導致的線卡之間和交換機之間的丟包佔了20 左右,剩下的還有少量的丟包是由於asic晶元損毀產生的.2 ...

python中package機制的兩種實現方式

10.5pt font family 宋體 mso ascii font family verdana mso fareast font family 宋體 mso fareast theme font minor fareast mso hansi font family verdana 當執行 ...

python中package機制的兩種實現方式

洞庭散人python中package機制的兩種實現方式 當執行import module時,直譯器會根據下面的搜尋路徑,搜尋module1.py檔案。1 當前工作目錄 2 pythonpath中的目錄 3 python安裝目錄 usr local lib python 事實上,模組搜尋是在儲存在sy...