天天看點

udp 視訊包網絡傳輸花屏

    視訊資料傳輸在傳輸層可以選擇TCP或者UDP,TCP面向連接配接,傳輸中斷,發送端是知道的。TCP傳輸的好處是不丢包,壞處是網絡不太好的情況下會越堵越嚴重。UDP非面向連接配接,發送端隻管發送資料,接收端有沒有接收到不管。UDP的好處應該是實時性,壞處顯而易見:網絡抖動大時資料會丢失嚴重,出現我們常說的花屏的情況。有一些情況是網絡也“正常”,ping包延時很低。但是接收端也會出現花屏。這是什為何呢?下面我将講述這種情況如何解決。

      如果視訊發送端視訊資料播放正常,接收端播放視訊花屏,第一件事情就是WireShark抓包。WireShark會告訴你很多問題點。有一種情況是發送端每次發送的資料包過大。一般交換機MTU單元設定一次通過的資料包大小是1500位元組。如果WireShark顯示很多fragment(分片)說明資料包被拆分。兩種解決方案,要麼增大MTU值,要麼重新組包,保證資料包的大小在MTU範圍内。正常情況下,要求網絡工程師設定通用值1500位元組。因為很多庫比如Ffmpeg就遵守這個值。在實際的項目中我就遇到過接收端播放視訊花屏,怎麼修改代碼都沒有,最後定位的資料包的網絡傳輸,讓網絡工程師修改MTU,問題才得以解決。

    包大了不行,小了同樣也會有問題。這個問題是本文的另一作者皚雪發現并解決的,問題是單個資料包太小接收端播放視訊同樣出現花屏,我所遇到的網絡環境裡沒有碰到這種情況資料包小了,多發幾次也沒出現花屏。這個問題的解決方法是如果包太小先緩存,等資料包夠數時一起發送。下面給出解決問題的基本代碼(代碼是皚雪寫的)。

#define BUFFER_LEN   1480

if (m_nBufferLen + nDataSize < BUFFER_LEN)

{

memcpy(m_pchBuffer + m_nBufferLen, (char*)pkt + RTP_HEAD_LEN, nDataSize);

m_nBufferLen += nDataSize;

}

else

SendData(pthis->sendtransport, m_pchBuffer, m_nBufferLen);

 memset(m_pchBuffer, 0, sizeof(m_pchBuffer));

m_nBufferLen = 0;

memcpy(m_pchBuffer, (char*)pkt + RTP_HEAD_LEN, nDataSize);

m_nBufferLen = nDataSize;