2013-02-18 63 views
2

我的C#代碼中有30FPS的視頻幀,我想在本地主機上廣播它,以便所有其他應用程序都可以使用它。我雖然是因爲它是一個視頻,並且沒有任何問題,如果任何數據包丟失,並且不需要連接/從客戶端接受,UDP是一個不錯的選擇。通過套接字傳輸視頻的幀

但這裏有很多問題。

  • 如果我使用UDP單播的速度是不夠的,大約25FPS(CPU使用率是25% 是在我的4核CPU的一個線程是指100%,這是不理想,但 至少它發送足夠的一套數據)。但單播不能向所有客戶端發送數據 。
  • 如果我用廣播速度很低。大約10FPS具有相同的CPU使用率。

我該怎麼辦?數據在同一臺計算機中,因此不需要從局域網等進行遠程訪問。我只是希望在同一臺機器的不同應用程序之間每秒鐘傳輸大約30MBytes的數據。 (640x480是固定大小的圖像×30fps×3byte每像素約爲27000KByte每秒)

  1. UDP Multicast是否有更好的性能?
  2. 即使我接受每個客戶端 並單獨發送給他們,TCP是否可以給我更好的性能?
  3. 有沒有比Socket更好的方法?記憶共享什麼的?!
  4. 爲什麼UDP廣播很慢?!只有約10MBy每 秒?!
  5. 是否有一種快速壓縮具有高性能幀的方法(至 每秒編碼30fps並在其他部分解碼)?客戶端應用程序在 C++中,所以這必須是跨平臺的方式。

我只想知道其他開發人員的經驗和想法,所以請寫下您的想法。 感謝您的幫助。

編輯:有關數據

更多信息:數據是位圖格式RGB24,他們是從設備分流到我的30FPS的應用程序。我想將這些數據廣播給其他應用程序,並且他們需要再次以RGB24格式顯示此圖像。沒有標題或任何東西,只有固定大小的位圖數據。所有操作必須在飛行中執行。無論使用有損壓縮算法還是任何事物。

+0

是有一些原因的許多現有的視頻流的協議之一是不合適的,以及爲什麼使用許多視頻流媒體解決方案的一個都不行?這是一個已經通過多種不同方式解決的問題。當然,其中一種方法應該能夠滿足您的需求,而不需要您重新發明輪子。 – Pete 2013-02-18 17:38:08

+0

@Pete,你知道任何基於UDP的跨平臺(.Net,C++)視頻流媒體庫嗎?!不幸的是我找不到一個。因爲在沒有庫的情況下實現這些協議之一併不容易,因此發明整個解決方案並不容易 – 2013-02-18 17:47:03

+0

查看FFMPEG – Pete 2013-02-18 17:50:34

回答

2

我在一個工業環境中試驗多播,這是一個很好的選擇通過一個不穩定的可靠網絡

本地主機共享存儲器可能是一個很好的選擇,因爲你可以建立幀的圓形隊列,並從一個到下一個只用一個單一的互斥來保護一個指針分配翻轉(writter側)。只需一名作者,幾名讀者,就不會出現問題。

在Windows上使用C++ C#共享內存稱爲文件映射,但您可以使用系統分頁文件(RAM和/或磁盤)。

看到這些詳細信息的鏈接

共享內存空間沒有保護,也沒有私人但它的名字。

通常,作者進程創建它,讀者通過它的名字打開它。防病毒軟件以與其他所有方式相同的方式查看這種I/O,但不阻止通信。

這裏是開始與文件映射的例子:

char shmName[MAX_PATH+1]; 
sprintf(shmName, "shmVideo_%s", name); 
shmName[MAX_PATH] = '\0'; 
_hMap = 
    CreateFileMapping(
     INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, size, shmName); 
if(_hMap == 0) { 
    throw OSException(__FILE__, __LINE__); 
} 
_owner = (GetLastError() != ERROR_ALREADY_EXISTS); 
_mutex = Mutex::getMutex(name); 
Synchronize sync(*_mutex); 
_data = (char *)MapViewOfFile(_hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); 
if(_data == 0) { 
    throw OSException(__FILE__, __LINE__); 
} 
+0

這似乎是一個很好的答案。謝謝,但我有一些關於內存映射文件的問題。首先,我如何從非託管端(C++客戶端)訪問其他託管進程內存文件?其次,用戶權限,防病毒和其他安全軟件/限制怎麼樣? – 2013-02-20 21:06:58

+0

好的謝謝。讓我看看,我會接受你的答案。目前我不能給予賞金,因爲它需要更多的7個小時:) – 2013-02-20 22:12:50

+0

目前使用內存映射文件,它有非常好的性能。幸運的是,從託管和非託管端訪問它沒有問題。只有一些人需要注意的是多進程寫入,它們需要很少的精確度。謝謝。 – 2013-02-21 16:29:45

0

使用live555 http://www.live555.com/與您最喜愛的壓縮器 - ffmpeg組合使用。

+0

那麼我怎樣才能使用它來發送位圖數據?!這是一個現場凸輪,所以我不能將它們保存到磁盤,然後使用FFMPEG將它們轉換爲視頻,然後使用Live555發送它們!我需要某種實時解決方案,它能夠將30位圖從內存編碼到視頻(再次在內存中,位圖流是流式傳輸,因此它們在應用程序啓動時不可用),然後使用其他解決方案(或相同的庫或I可以寫這個發送部分)發送給其他應用程序。他們還必須能夠將數據解碼到內存中的RGB數據幀。 – 2013-02-19 19:29:52