教學同屏系統開發


前言

有個客戶在開發教學白板系統時遇到了一個問題,就是采用wifi的方式同屏至少60個學生端時,自己開發的同屏無法滿足教學同屏最基本的要求,比如視頻畫質質量、播放流暢性、馬賽克問題等,因此決定將這部分外包給我們開發,本文主要記錄了開發該同屏模塊的過程。

評估

根據現場實際情況及經驗分析,主要存在以下兩個問題:

  • AP+AC是否能夠滿足負載60台終端,因為一般的AP+AC是無法負載這么多客戶端的,特別是同屏一般采用多播的方式實現,很多AP+AC的設備對多播的配置是有性能限制的
  • 無線傳輸都要遇到的問題,帶寬、丟包率高(特別是打算采用多播方式開發時)、延時大、抖動厲害

問題1需要通過調試來確定問題是否確實存在,這個是找華為的工程師現場后台登陸,查看當前運行狀態來確定的,命令:display radio all,輸出如下:
AC后台運行狀態圖

從上圖可以看出,2.4G和5G的CU占用率已經很高了,要么換更高配置的AP+AC,要么針對性的優化該AP+AC(這個得找華為的工程師來專門優化了_
最終和客戶討論確定,問題1由客戶自己找華為來優化。

問題2是無線傳輸都可能遇到的問題,我們可以針對特定場景做特定的優化。
比如對於同屏系統,一般滿足幀率15幀的同屏就可以了,不需要網絡電影播放要求的25fps或者30fps,針對這一個現象,我們決定采用基於jpeg的同屏,它相對於通過h264方式的同屏有很多優勢:

  • 不存在馬賽克問題,h264傳輸如果出現丟包就很容易出現馬賽克問題,當然通過增加一些機制也能夠基本避免馬賽克,不過最終的播放的效果仍然不夠理想(畫面可能靜止)
  • 對教師端和學生終端的主機配置性能要求極低,幾乎不會占用什么cpu和內存,而如果通過h264方式,對兩端的cpu和內存都會有一定的要求,這多少會干擾主程序的資源使用

再比如客戶的wifi環境只是單個教師里面的,通過分析發現,主要的無線問題出現在丟包率高上,帶寬、延時、抖動通過問題1對應的解決方案可以很大程度上優化掉,幾乎對最終的同屏效果不會有什么影響。丟包的問題采用FEC前向糾錯可以得到很好的解決。

下面主要對jpeg傳送實現以及FEC前向糾錯實現進行詳細描述。

jpeg傳輸

jpeg的編碼解碼采用的是開源的jpeglib庫,我們采用的是jpeg-9c,下載下來后,用vs編譯即可。使用的時候要特別注意,運行時可能會報版本不匹配的錯誤,出現這個問題是因為系統可能已經存在jpeg.dll了,而我們編譯采用的jpeg頭文件和鏈接dll(鏈接到系統自帶的dll了)的版本不一致。

另外,我們還可以采用libjpeg-turbo庫來替換jpeglib,該庫是基於jpeglib,內部采用了cpu並行指令對jpeg編解碼進行了優化,現在的cpu一般都支持這些並行指令,因此替換后的cpu的使用率會有所降低,jpeg編解碼時間也會有所較低。

FEC前向糾錯

FEC的方案我們同時測試了幾套,比如基於一個朋友開發的fec,該fec庫是經過了市場檢驗的,在各方面都有不錯的表現,采用clumsy.exe測試抗丟包能力時,可以很輕松的抵抗30%的丟包。除了基於該朋友的fec庫,我們還摸索了開源的fec庫,用開源的方案可以為我們省下一筆費用支出_ 因此值得一試。最終我們測試了以下幾個fec庫:

通過測試發現,feclib優點是接口用起來比較方便,缺點是效果很差,只能抗2%的丟包,因此放棄了它。libcorrect沒編譯過_,放棄了。下面重點說說openfec,雖然它的整體性能比不上朋友的fec,但是卻滿足了客戶的基本需求。

openfec支持以下四種算法:

  • LDPC-Staircase codec
  • Reed-Solomon GF(256) codec
  • 2D parity codec
  • LDPC from file codec

其中LDPC-Staircase 和 Reed-Solomon是適合我們jpeg傳輸的,但是通過測試發現了幾個問題,比如Reed-Solomon有2的8次方最大分包限制,LDPC-Staircase雖然沒有這個限制,但是存在一定的數據恢復出錯情況,也就是在不丟包的時候,本身解碼后也會存在部分數據錯誤(暫時沒有去跟蹤是什么原因導致的,用自帶的demo測試也是一樣的結果),因此只能采用Reed-Solomon算法了,得想辦法繞過2的8次方限制這個問題,不然當某一幀編碼后的數據稍微長一點就可能超過這個限制,這會導致接收端解碼直接崩潰。

我們采用繞過的方法是自動拆分編碼后的jpeg幀,使每個拆分后的包滿足不超過2的8次方限制,這樣做降低一點點解碼恢復能力,但是因為絕大部分幀是不需要拆分的(大部分幀沒有超過2的8次方限制),也就是可以直接單幀傳送的,因此對解碼恢復沒有造成影響。

最后,針對客戶的場景,我們還對openfec做了適當的微調,這里就不再詳說了。

總結

這個項目的開發雖然只耗時兩周,但是這兩周積累了不少經驗,覺得非常值得!因為很少在windows下開發,在開發前特意研究了vs對項目的布局規划,最終有了如下布局(我覺得比較滿意,布局清晰)
├── bin 編譯生成文件的位置
│   ├── debug
│   │   ├── 32
│   │   └── 64
│   └── release
│   ├── 32
│   └── 64
├── cli 客戶端庫源文件路徑
├── cliDemo 控制台版本客戶端測試程序
├── combianWidthCTest
│   ├── Client c#版本客戶端測試程序
│   └── Server c#版本服務端測試程序
├── dependsDLL 額外依賴的dll庫路徑
├── external 額外依賴的模塊路徑
│   ├── jpeg-9c
│   ├── libjpeg-turbo
│   └── openfec_v1.4.2
├── lib 編譯庫生成的文件路徑
│   ├── win32
│   └── win64
├── svr 服務端庫源文件路徑
├── svrDemo 控制台版本服務端測試程序
├── syncScreenSDK 該文件夾是執行pack.bat生成的打包文件夾
│   ├── win32
│   │   ├── bin
│   │   ├── cli
│   │   └── svr
│   └── win64
│   ├── bin
│   ├── cli
│   └── svr
├── temp 編譯鏈接的臨時路徑
│   ├── compile
│   │   ├── cli
│   │   ├── cliDemo
│   │   ├── svr
│   │   ├── svrDemo
│   │   └── upgrade
│   └── link
│   ├── cli
│   ├── cliDemo
│   ├── svr
│   ├── svrDemo
│   └── upgrade


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM