題 如何強制進程通過UDP而不是TCP進行傳輸?


我在Linux機器上運行ffserver進程,以實現視頻流 ffmpeg的。但是,視頻流有延遲。上 ffserver配置文件 我定義 Port 8090

命令 netstat -tulnap 給我這個:

root@beagleboard:/etc# netstat -tulnap
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address               Foreign Address             Stat                                                                             e       PID/Program name
tcp        0      0 0.0.0.0:68                  0.0.0.0:*                   LIST                                                                             EN      654/pump
tcp        0      0 0.0.0.0:111                 0.0.0.0:*                   LIST                                                                             EN      662/portmap
tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LIST                                                                             EN      698/dropbear
tcp        0      0 0.0.0.0:8090                0.0.0.0:*                   LIST                                                                             EN      744/ffserver
tcp        0     52 192.168.1.104:22            192.168.1.111:10838         ESTA                                                                             BLISHED 724/dropbear
udp        0      0 0.0.0.0:514                 0.0.0.0:*                                                                                                            703/syslog-ng
udp        0      0 0.0.0.0:111                 0.0.0.0:*                                                                                                            662/portmap
udp        0      0 0.0.0.0:60628               0.0.0.0:*                                                                                                            709/avahi-daemon: r
udp        0      0 0.0.0.0:5353                0.0.0.0:*                                                                                                            709/avahi-daemon: r

如您所見,ffserver進程使用tcp協議進行傳輸,我懷疑這是視頻流延遲的原因。我如何強制進程使用或udp協議?我應該換口嗎?


4
2018-03-07 16:22


起源


tcp vs udp是一種非常不同的用法,不可互換 - ratchet freak
你告訴我沒有辦法通過UDP傳輸傳輸? - dempap
這是需要在應用程序級別進行的更改,您無法在外部執行此操作。 - heavyd
你想要的是什麼 告訴FFMpeg通過Simple RTP流式傳輸,另請參閱“點對點流媒體”部分。 RTP 可以使用UDP。 - Josh
問題的標題應該是“如何通過UDP製作ffmpeg流” - NothingsImpossible


答案:


您不能只強製程序使用UDP而不是TCP,而無需重寫程序本身的部分內容。這些協議太不同,不能互換。

  • TCP是面向流的(接收者以發送者輸出的確切順序將所有內容視為連續流); UDP是面向數據報的(每個數據報在一個單獨的數據包中發送,甚至可以重新排序)。

  • TCP具有流量控制,因此發送方(或發送方的操作系統)確切地知道它應該多快發送數據而不會溢出鏈接或顯著影響其他連接。 UDP不會執行任何操作 - 一個不太“強制”的程序可能會開始通過UDP每秒發送數十億字節的數據,而不管鏈接速度如何。

  • TCP具有重傳功能,因此如果數據包在中間丟棄(例如因為網絡過載或有其他問題),則會重新發送。如果協議依賴於可靠的傳輸並強制它通過UDP,則只要至少一個數據包丟失,連接就可能完全死亡。 (和包  走開;見上面的#1和#2點。)


22
2018-03-07 17:11



如果發件人不遵守流量控制,是否會斷開連接? - Jordan Doyle
@JordanDoyle否。這只會使連接速度變慢,因為接收器必須丟棄額外的數據包,然後需要重新傳輸。 - Bakuriu
@Bakuriu啊謝謝。如果發件人不遵守會發生什麼事嗎? - Jordan Doyle
@JordanDoyle正如我所說,除了更多的數據包將被丟棄並且連接將變得越來越慢之外,沒有什麼特別的事情會發生,因為發送者將填充所有的鏈接容量。您只是無用地增加網絡中的流量,並且可能導致網絡擁塞。 - Bakuriu


正如其他人所提到的,UDP和TCP是根本不同的協議。

但是,如果你 必須 通過UDP而不是TCP傳輸數據,可以使用諸如的中繼工具 socat。您可以將socat配置為偵聽TCP連接,並將TCP流的內容作為UDP流轉發到另一台主機。如果其他主機期望TCP流量,您可以使用其中的另一個中繼實例轉換回TCP。這將從主機到主機鏈接中刪除重試和確認行為。本地中繼工具和本地應用程序之間仍將存在重試和確認,但您不太可能在本地環回鏈接上看到重試。

但是,這不太可能解決您的延遲問題。如果您的應用程序構建為使用TCP而不是UDP,則可能無法容忍丟棄的數據包,在這種情況下,此黑客可能會導致不穩定的行為。


6
2018-03-07 19:00





除非您使用非常慢的連接,否則您的延遲問題很可能是由於您的視頻編解碼器造成的。

要有效地壓縮視頻,您必須使用預測編碼(請參閱 這篇關於維基百科的文章)。

預測編碼基本上計算來自較早或較晚圖像的圖像。這具有以下含義:

  1. 如果您使用許多P幀(從早期幀計算),您將在顯示視頻之前得到延遲 啟動,因為客戶端必須等待下一個完整的視頻幀(I幀)。但是,一旦建立了流,您就可以觀看相對無滯後的視頻。

  2. 如果你使用B幀(從早期和以後的圖像計算),你將有一些非常大的延遲:除了上面的初始延遲,客戶端必須等待下一個I幀從上一個開始播放我-幀。這將引入滯後(客戶端播放視頻明顯晚於服務器記錄/發送它,通常很多秒)。如果你正在動態編碼視頻,你也會有來自服務器的延遲 - 它需要等待下一個I幀從前一個I幀開始發送所有內容。

對於大多數編解碼器,您可以根據需要調整B幀和P幀的使用,但是,存在權衡延遲與壓縮效率的關係

如果你有足夠的帶寬,你也可以使用沒有B / P幀的編解碼器,比如 MJPEG

延遲的另一個原因是在播放器端緩衝,因此如果存在抖動的網絡傳輸,則不會有任何失真。許多視頻播放器允許您調整緩衝區大小。


3
2018-03-07 20:57