採用udp廣播進行資料的傳輸,實現windows下進行低延遲的螢幕共享。
開發語言:c#
第三方元件:redis
1.實現思路
總體流程圖
dgis.desktopshare實現windows下螢幕分享低延遲功能,按照服務執行位置由三部分構成:發起端、接收端、快取端。
通過udp廣播實現發起端和接收端的通訊,是為了盡量的減少通訊負載和降低延遲。眾所周知udp是所有通訊協議中延遲最低的(但也有受網路因素丟包的問題,這裡作為區域網同屏,暫不考慮丟包問題),而採用廣播的方式可以有效的降低發起端的效能負擔。
增加乙個redis服務,是為了減少udp廣播資料,按照1920*1080解析度的截圖資料來算,單張已經超過了udp單包的最大資料量1472位元組,倘若直接使用udp傳輸截圖,需要額外的進行封包拆包,這樣不僅浪費了程式執行時間,也增加了傳送端和接收端的**複雜度。本著最低延遲的目的,將真實的資料存入redis快取,只通過udp廣播redis中對應的uid資訊即可,這也是本程式最核心的地方。接收端接收到uid的資料後,再自行去獲取redis中真實的資料進行解析。
2.**結構
dgis.desktopshare.service的**結構分為frm(窗體)、iservice(介面)、service(實現)三個部分。引用的第三方dll有redis相關操作庫、螢幕獲取相關庫和dgis開頭的輔助操作庫。
frm:
imgdisplyfrm是接收端的預設顯示介面,包含乙個picturebox控制項,顯示接收到的螢幕影象。
iservice:
idesktopshareservice螢幕共享操作介面,主要方法有4個。
注釋的已經很明確了,這裡不多說。
service:
desktopshareservice:idesktopshareservice的實現類,裡面是詳細的實現方法。核心的**有下面幾個地方:
1開始螢幕分享,_udpservice 初始化,螢幕抓取設定以及開啟螢幕抓取。public
void start(int framerate, bool mousedisplay, int
port)2);
89 _desktopcapturer =capture***ctory.createdesktopcapturer(framerate, mousedisplay);
10 _desktopcapturer.imagecaptured +=imagecaptured;
11_desktopcapturer.start();
1213
//佇列迴圈處理積壓的
14//
task.factory.startnew(() =>
15//
2324//}
25//
});26 }
1///2
///螢幕截圖結果
3///
4///
5private
void
imagecaptured(bitmap bitmap)
6
1抓取到螢幕的結果是bitmap,這裡需要將bitmap轉換為byte,因為在測試中redis直接存入bitmap取出時候有些異常。待redis存入資料後,再通過udp傳送資料。來看下測試資料,獲取到傳送的耗時情況。///2
///傳送命令
3///
4///
5private
void
sendcommand(bitmap bitmap)
6
主要的耗時在轉換這個地方,耗時約10毫秒,redis存入時間是很快的6毫秒左右,udp傳送時間基本為0.
1public
void recive(int
port)211
};12
13 _udpservice = new
udpbroadcastservice(port,
14 bytes =>
15);
18_imgdisplyfrm.showdialog();
19 }
1///2
///顯示影象
3///
4///
5private
void showimg(byte
recivebytes)
6
1接收端同樣也是開啟乙個_udpservice ,初始化,進行訊息監聽,接收到訊息後進入showimg(顯示影象)方法,中間主要**是parseimg(獲取解析)這部分,這部分實現將真實資料從redis中獲取。看下耗時情況。///2
///解析
3///
4///
5///
6private bitmap parseimg(byte
bytes)721
else
22return
null
;23 }
這裡能看到,訊息的傳送和接收之間耗時約為0(這裡考慮本機沒有經過網絡卡,實際應該有100毫秒左右延遲),redis快取獲取時間非常的快4毫秒左右,轉碼耗時30毫秒。
以上綜合計算,從螢幕採集到終端接收解析總共耗時50毫秒左右,加上udp廣播理論上的100毫秒延遲,150毫秒是能夠達到的。
下圖是真實環境中兩台電腦的螢幕分享延遲。
從截圖上看,延遲在170毫秒,由此看出這種方案是比較可行的。
放一張測試效果圖。
3.原始碼
原始碼放到了csdn上,不知道如何上傳附件。萬惡的csdn居然至少需要設定2分了。
**開源位址:
2018.1.30更新:增加了音效卡聲音採集同步傳輸
Windows下C 實現多執行緒
有時候我們想在乙個類中實現多執行緒,主線程在某些時刻獲得資料,可以 通知 子執行緒去處理,然後把結果返回。下面的例項是主線程每隔2s產生10個隨機數,將這10隨機數傳給多執行緒類,讓它接收到資料後馬上列印出來。首先看類的定義 cpp view plain copy print?pragma once...
分享個windows下的makefile
直接上 insert source test.cpp opencv version opencv ver 2.4.10 visual c version for opencv vc12.0 vc10.0 vc11.0 vsv vc12.0 cvv 2410 arch for opencv x86 x...
FFMPEG在Windows下的螢幕錄影錄音
ffmpeg在linux下用x11grab進行螢幕錄影,在windows下用directshow濾鏡 首先需要安裝乙個軟體,原始碼位址是 安裝完了之後,在命令列執行 ffmpeg list devices true f dshow i dummy 系統輸出大致如下 dshow 002db420 di...