2010-09-19 85 views
5

我必須儘可能快速和實時地通過UDP發送一系列視頻幀,並在基本工作時,我遇到了各種各樣的困難。我的一些目標:如何通過UDP發送實時數據?

  1. 數據通常會通過撥號發送(因此UDP而不是TCP),但也需要支持快速以太網。

  2. 可以偶爾丟棄幀(因此UDP而不是TCP)。

  3. 需要低延遲。遠程接收的幀應該是最近發送的幀(緩衝區中不超過幾幀)。

  4. 我需要能夠檢測有效帶寬,以便我可以或多或少地壓縮幀以保持幀速率。

我已成功地實現大多數件:

  1. 我分手幀數據成約500個字節的一個或多個數據報,並且每個都有一個序列號和其他信息。接收器重新組裝整個幀並檢測是否有數據報丟失。

  2. 如果接收方檢測到丟失幀的比例超過了一定比例(例如,在過去10幀中爲50%),我會向發送方發送TCP消息以減慢50%。發送者比每個後續幀慢慢增加5%的速度。

  3. 使用System.Net.Sockets.UdpClient發送和接收數據。

  4. 我有一個單獨的TCP通道用於控制消息回發給發件人。

我現在的主要困難是檢測有效帶寬並處理延遲,特別是在撥號(最大約4000字節/秒)時處理延遲。例如,如果我嘗試使用TcpClient.Send()發送100,000字節/秒,則它們似乎都到達(沒有丟棄的數據報),但是到最後一個數據報到達時有很大的延遲。我認爲TcpClient.Send()函數是阻塞的,直到緩衝區能夠發送使我當前的算法變得混亂。

任何人都可以點我的任何信息來源如何:

  1. 通過UDP檢測實際帶寬。

  2. 一個更好的動態調整帶寬以適應可用管道的算法。

  3. 以期望的帶寬順利發送數據。

  4. 一種檢測延遲降至最低的方法。

上週我一直在旋轉我的車輪,每當我解決一個問題時,它似乎是另一個問題。

回答

2

您也可以爲每個數據包添加一個時間戳。然後你可以檢測延遲是否增加。在這種情況下,您發回消息以減少帶寬。

在創建連接時,您只需檢測很少數據包的延遲。這個值在運行時不應該改變。

+0

我確定檢測延遲將需要某種數據報時序。例如,我可能需要附加一個時間戳,發送給接收者,然後發送回(可能使用TCP控制通道)。在某種歷史隊列中查找原始發送時間,差異/ 2是aprox。潛伏。我無法找到已發佈的算法來完成此操作,因此我可以高效地實施。 – 2010-09-19 19:13:45

+0

你甚至不需要知道絕對延遲。由於它是你想要解決的帶寬問題,你可以看看幀間時間 - 如果幀間隔爲40毫秒,但你看到它們相距90毫秒,那麼發送者需要放慢速度。 – caf 2010-09-20 04:23:48

+0

問題在於,隨着時間的推移,小的延遲可能會在幀發送之間產生大的延遲。我最終發送了一個ACK每收到一個完整的幀。在發件人處,我會跟蹤最近發送的10個幀,發送時間和確認時間。如果平均時間太長,那麼我知道要放慢速度。 – 2010-09-27 03:01:29