教学同屏系统开发

前言

有个客户在开发教学白板系统时遇到了一个问题,就是采用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

posted @ 2019-02-03 20:14 rongpmcu 阅读(...) 评论(...) 编辑 收藏