abnk

1. 项目介绍

  该项目有两三千行代码,各个部分都使用基本成熟的模块做整合、改造,为后面更深入的学习打下了基础。

  在一些场景中,希望在电脑上使用手机的高清摄像头,比如在现在的一些云服务器、瘦客户机中,远程电脑如果没有摄像头的话能不能添加一个,这就是一个好办法,通过TCP传输视频,把手机拍摄的视频实时在电脑上显示出来。

  采集IOS上的视频,使用硬件编码,编码数据通过TCP私有协议发送,然后通过CALayer预览显示,或解码后通过 CAEAGLLayer 使用 OpenGL 完成 YUV 转 RGB 并渲染显示预览界面。TCP发送出去的数据在电脑端通过Qt的客户端接收、解包、x264解码、libyuv 转 RGB、OpenGL渲染显示,以此完成端到端的视频显示。

  下面分模块做简单介绍。

2. Server端代码实现

TCPServer类:

该Server端移植自 v4l 的服务端 c 语言代码,经改造为 oc 的代码,使用信号量同步,通过代理方法获取摄像头编码后的数据。

从主界面加载完毕,开始监听套接字,如果有客户端发出请求连接则按照相应的协议封装进行解包、回复。

需要注意的是,Server端需要采用非阻塞界面的编程,独立出线程来处理请求,有客户端连接则打开摄像头,采集数据进行编码,断开连接后则关闭摄像头。

其中,协议的交互分为命令线程和数据线程,命令线程用来接收处理控制命令,数据线程用来发送H264数据。

摄像头数据采集:

通过AVCaptureSession采集数据,将采集到的数据通过代理方法传递到编码器进行编码,编码后的数据经过代理方法被传递发送或者通过OpenGL渲染显示。

这里以前采用的方法并不合理,是通过01信号量控制数据编码和发送的,类似于生产者和消费者,但是网络往往会发生阻塞,而数据产生的速率是固定的,就会发生丢帧的现象,所以需要改进:将编码后的数据存储为队列再用线程单独发送。因为该程序写的早,当时未充分考虑这一点。

视频编码:

  客户端解码要求的格式是avcC的格式,而视频采集的是annex-b的格式。需要转换为avcC的格式,并且sps、pps需要一并发送,不能分开。

  这一点同前面的RTMP的要求是一致的。

  该程序硬件编码产生IDR帧的间隔还是比较短的,基本就是一帧IDR、一帧非IDR。

视频解码:

  编解码都是通过VideoToolbox,最后都要对产生的数据进行解析,使之符合传输/解码要求。

视频渲染显示:

  CALayer 底层就已经是有硬件加速了。使用OpenGL,可以做更多的事情。

3. Client端代码实现

Qt 下使用  OpenGL 同样类似于上面的视频渲染流程,解码得到YUV,YUV 转 RGB,将 RGB 渲染显示。

其中的视频传输协议同样是使用一样的头文件,来按照Server的数据发送格式解析数据包获得h2674数据。每一帧数据被封装成一个数据包。

4. 总结

  该项目是早期练习视频传输、编解码、学习私有网络协议、学习IOS上的C/C++编程而整合的一个稍大点的项目。

  TCP 传输实时视频还是太容易受网络环境影响而阻塞了,后期的重点将转向RTSP的学习,故本文不做过多介绍。

   

 

 

  

分类:

技术点:

相关文章: