2010-11-19 17 views
2

我們已經在Silverlight上實現了一個音頻 - 視頻協作應用程序,並試圖調整它。我們遇到的一個問題是,丟包時流延遲會增加:我們必須等待丟包被檢測,請求,然後再丟失丟包。當然,這與我們的音頻流的一致性發揮地獄。 (如果可以的話,我們會切換到UDP,但是Silverlight不支持瀏覽器中的內容,我們也禁用了Nagle算法,所以一般來說,只要我們提交一個要傳輸的byte []數組,我知道TCP數據包的大小!=提交的數據量,但是在Nagle算法關閉的情況下,它是接近的,而且我們有一個自適應抖動緩衝區,所以我們可以用處理丟失數據包,但TCP/IP上丟失的數據包大大增加了我們需要緩衝的音頻數量,從而大大增加了延遲。)什麼是最大限度地減少丟失數據包對通過TCP發送的實時媒體流的影響的最佳方式?

因此,我們試圖優化我們發送數據包的方式,以查看是否有任何方法減少丟包的影響。我們目前有幾個競爭的解決方案,我們正在考慮實施:

(1)我們可以嘗試使我們的數據包更大。目前,我們通過同一個TCP流發送大量(〜1024字節視頻)數據包和小型(〜70字節音頻)數據包。但是我們可以將音頻和視頻數據複用在一起,也就是說,只要有空間,我們就可以將一些視頻數據附加到我們的音頻數據包中。這將使單個數據包稍大,但會減少數據包的總數。 (2)我們可以將音頻和視頻分成兩個獨立的TCP流。這意味着如果視頻流由於丟失數據包而停滯,則音頻流不會停頓,反之亦然。當然,這會稍微增加開銷,並且不會減少發送的數據包總數。 (3)我們可以將音頻反向複用爲多個單獨的TCP流,然後在遠端重新組裝它們。這將有效地允許我們「僞造」單個UDP數據包傳輸方式。如果我們有8個音頻流,並且其中一個音頻流由於丟失了數據包而停止工作,其他數據流仍然能夠按時發送數據,我們所要做的就是處理音頻數據包的1/8直到停滯的河流恢復正常爲止。這當然並不理想,但它可能會導致更好的體驗,而不是讓整個流停頓,並且不能播放任何數據包,直到丟失的數據包被重新傳輸。

對這些可能性有任何想法嗎?還有其他建議嗎?或者我們只需要編碼所有三個,然後測試它們?

+0

MTU將影響選項1 - 它僅與客戶端和服務器之間的最小MTU速度相同 – 2010-11-19 22:13:06

+0

同意 - 我們不能使數據包太大。目前我們的有效負載限制在1024字節,但我相信我們可能會達到1500字節,而不會遇到MTU問題。 – 2010-11-19 22:25:34

回答

0

這個應用程序是通過互聯網使用嗎?因互聯網質量而丟失數據包的原因是什麼?如果是這樣,除了將應用程序開發爲儘可能容錯外,您還可以確保互聯網電路質量可以接受。今天良好的互聯網電路應該不會有超過0.1%的數據包丟失。您可以使用我們的Packet Loss工具測試Internet電路和ISP。它可以免費使用,所以幫助你自己。

+0

是的,它將通過互聯網使用。但它將被(希望)成千上萬的消費者使用,其互聯網連接的質量將完全超出我們的控制範圍。當然,數據包可能會丟失的原因有很多,從本地的無線WiFi連接到超載路由器,從這裏到達這20個跳躍點的任何地方,到宇宙射線在某個緩衝區翻轉一點。 – 2010-11-21 00:26:28

1

如果您重新啓用了Nagle算法,您將(i)讓TCP根據路徑MTU發送最大尺寸的緩衝區而不是您自己的決定; (ii)完成你的建議(1)捎帶音頻和視頻數據包;和(iii)減少分組總數。飽和TCP連接的穩定狀態性能(無論是否使用Nagle算法)都是相同的,所以除了在初始窗口填充期間,您不會丟失任何內容。

您還應該運行您可能承受的最大套接字發送緩衝區:至少128k,或者如果可能的話,雙倍或四倍;並且您還應該使用盡可能大的套接字接收緩衝區,儘管在連接套接字之前必須先設置套接字接收緩衝區> 64k,以便可以在TCP握手期間告知另一端有關窗口縮放的信息。

+0

重新啓用Nagle算法的問題是它有可能增加大量的延遲,這正是我們試圖最小化的原因。在包含音頻和視頻數據的數據流上,它可能不會增加太多的延遲,但對於只包含80字節音頻消息的數據流,需要比我們想要排隊足夠的消息來填充整個數據包所用的時間更長。 – 2010-11-22 18:51:22

0

您是如何確定丟包導致失速的?

我不認爲分離流會有很大的幫助,只是在保持音頻/視頻同步時遇到更多問題。

無論哪種方式,無論你使用什麼樣的設置,你都會被TCP/IP限制,要求重傳數據包。我想我會研究的最重要的事情是你的TCP堆棧是否是服務器,客戶端是否啓用了一些更高級的選項。我特別指的是選擇性確認和快速重傳(任何現代操作系統應該默認都有這些)。快速重新傳輸會使客戶端在檢測到丟失數據包時非常快地請求丟失數據包,而選擇性確認將使服務器僅重新傳輸流中缺失的部分。

最終,聽起來好像你沒有使用足夠大的抖動緩衝區,如果你無法容忍丟失的單個數據包。在用於將數據發送到tcp堆棧的時間中,應用程序的可能性也不盡相同。我會收集一些數據包並嘗試瞭解網絡中發生了什麼,並瞭解您可以從中做些什麼。

+0

我承認,間歇性丟包只是一個假設,儘管這對我來說似乎相當有說服力。我們注意到有時音頻流會停頓,即我們的應用程序將不會收到1-2秒的任何通知;然後當它被告知一些未決數據時,它將包含許多數據包的數據。除了間歇性的數據包丟失之外,我無法想象會有任何其他情況可以解釋這一點。 – 2010-11-22 18:55:15

+0

另外,就抖動緩衝區而言,是的,抖動緩衝區更大是微不足道的。但是我們試圖保持抖動緩衝區儘可能小,因爲這就是引入延遲的原因。當抖動緩衝區足夠大以處理1-2秒的「失速」時,它還會在對話中引入1-2秒的等待時間,這相當分散注意力。我們現在要做的是在我們遇到拖延時立即跳過抖動緩衝區,然後緩慢減小其大小(通過丟棄偶爾的幀),直到延遲時間不再那麼明顯。 – 2010-11-22 18:59:46

0

我第二@Kevin Nisbet在緩衝區(不幸)。如果您使用的是TCP而不是UDP,則緩衝區的大小應該等於服務器收到關於丟失字節的通知並讓它們到達客戶端。由於TCP以有序流的形式嚮應用程序發送數據,因此當數據包丟失時,堆棧無法嚮應用程序提供任何附加字節,直到確認報告丟失的字節被髮送到服務器,進行處理並且字節到達在客戶端。同時,保持您的應用程序運行的唯一方法就是緩衝區。你知道往返需要多長時間,包括處理嗎?

如果沒有選擇性確認,在丟失字節後收到的任何內容都是無用的,需要重新發送。客戶端將確認收到的最後一個字節,並且服務器需要重新傳輸此時的所有內容。

有了Selective Ack,至少服務器只需要發送缺失的塊,但堆棧需要等待塊到達。它不能將它到目前爲止收到的數據提供給應用程序,然後填寫缺失的部分。這就是UDP所做的:) 也許你應該寫信給MS ...

來自網絡方面,我畏懼(有點)關於發送相同內容的多個副本。您的應用程序中的帶寬是否充足?也許某種冗餘(FEC或類似)比複製內容要好。 此外,如果可能發生數據包丟失,我不認爲在網絡上推送更多流量是明智的。您的計算機是否運行半雙工? :-D

+0

感謝您的意見。靜態大型緩衝區的問題在於它增加了對話的延遲,這是令人煩惱和分心的。目前我們正在使用一個動態緩衝區,根據流量的穩定性,這個緩衝區將會(快速)增加或緩慢減少。另外,在選項3中,我們不會發送相同數據的多個副本。我們將它們進行反向複用,即,將一組音頻樣本發送到一個TCP流中,然後將下一個TCP流發送到下一個TCP流,等等,或許將一些冗餘/ FEC數據添加到數據中(如您所建議的)。 – 2010-12-31 16:56:32

相關問題