初探基于TCP的服务器/客户端结构的聊天系统(四)视频聊天的实现
2013-08-15 22:01
816 查看
视频聊天,肯定首先要捕获视频。这个实现倒是很顺利,我是用别人写好的Widget类实现的。好东西,附上链接http://download.csdn.net/download/zlhforever2/4503796,没分的我可以传给你。很容易用,作者是继承的QWidget类。这个就不贴源代码了。
接下来就遇到一个很让人头疼的问题。我估算了一下数据量,如果采用RGB888格式的也就是RGB24格式,那么在320*240大小的画面的情况下,一帧原始数据的大小就是320*240*3 = 230400字节。那么加入1秒钟传输10帧原始数据,那么就要2304000字节,也就是2M多,那么就需要2304000 * 8 = 18432000bit/s的传输速率,也就是大概需要20M带宽才能满足这路视频信号!!就国内这网速,想都不用想。那就只能采用一定的压缩算法了。
那么用什么压缩算法呢?视频的工业标准应该是MPEG-4(我不是学视频编码的,说的不对的还望大家见谅)。压缩算法,更准确的说是压缩库也有很多,X264、XVID、DIVX等等。我用的是XVID。这东西我看了一天多,才发现有多蛋疼。竟然没有一个像样的官方文档!不过也确实,光那些多如牛毛的参数都列举不完,如果不是有点理论基础的,还真难玩的转。网上貌似只有一个中文的文档,http://wenku.baidu.com/view/d20e5b0e7cd184254b35351c.html说的倒是挺清楚,但是连个像样的范例都没举。让我去看源代码中sample,又没那么大耐性。耐着性子看完了那个文档,比着他说的套路写下来,发现死活不管用,调了半天,也不知道到底哪个参数没设置好。这还真郁闷。算了,看别人写的吧。还真是好人多,发现网上有个哥们写的http://blog.csdn.net/markman101/article/details/5713034,不得不说,还是好人多啊!我果断给他回复,好人一生平安!真是好东西,谁用谁知道,连接口都写好了。
还真不得不说,这个视频实现,大部分代码还都是抄别人的
。不过,拿来注意也没什么不好。毕竟时间有限,容不得我去把每一个模块都自己一一实现了。剩下的就是用别人的代码实现自己的功能了。
我统计了一下,用他的压缩设置,我的视频压缩率在77~78之间,这样算下来,我只要300K左右的带宽就可以支持一路视频信号,还算比较理想。
接下来还有一个问题,传输协议的问题。TCP实时性不好,UDP可靠性不好,并且容易出现乱序。比较标准的选择应该是RTP协议。关于这些协议的特性,可以百度百度,详细了解一下。RTP协议可以自己实现,当然,懒人自然是懒办法,用别人的库呗。我用的是JRTP库。
在发送端,先从设备中提取原始的帧数据,然后用编码器编码,每个帧压缩完有几K,但是RTP包支持的最大大小是1000多个字节(可能是为了保持实时性),所以就需要拆分每个帧。我是这样做的,每个包的负载的第一个字节标示是否是一个帧的结束,如果是,则标为0,否则标为1。发送部分代码如下:
在接收端就循环接收,当收到包的负载的第一个字节是0的时候,就将已接收到的所有数据发送给解码器,然后解码器解码并显示出来。
关于不定长数据,还要考虑循环缓冲区接收的问题。
这就是整个视频聊天的大概流程。说的有点笼统。但是自己写的代码又太烂了,不能模块化到直接拿出来就能供大家使用。我只能说说我的经验以及我用到的比较好的资源。希望我提到的这些资源和思路能帮到大家。
接下来就遇到一个很让人头疼的问题。我估算了一下数据量,如果采用RGB888格式的也就是RGB24格式,那么在320*240大小的画面的情况下,一帧原始数据的大小就是320*240*3 = 230400字节。那么加入1秒钟传输10帧原始数据,那么就要2304000字节,也就是2M多,那么就需要2304000 * 8 = 18432000bit/s的传输速率,也就是大概需要20M带宽才能满足这路视频信号!!就国内这网速,想都不用想。那就只能采用一定的压缩算法了。
那么用什么压缩算法呢?视频的工业标准应该是MPEG-4(我不是学视频编码的,说的不对的还望大家见谅)。压缩算法,更准确的说是压缩库也有很多,X264、XVID、DIVX等等。我用的是XVID。这东西我看了一天多,才发现有多蛋疼。竟然没有一个像样的官方文档!不过也确实,光那些多如牛毛的参数都列举不完,如果不是有点理论基础的,还真难玩的转。网上貌似只有一个中文的文档,http://wenku.baidu.com/view/d20e5b0e7cd184254b35351c.html说的倒是挺清楚,但是连个像样的范例都没举。让我去看源代码中sample,又没那么大耐性。耐着性子看完了那个文档,比着他说的套路写下来,发现死活不管用,调了半天,也不知道到底哪个参数没设置好。这还真郁闷。算了,看别人写的吧。还真是好人多,发现网上有个哥们写的http://blog.csdn.net/markman101/article/details/5713034,不得不说,还是好人多啊!我果断给他回复,好人一生平安!真是好东西,谁用谁知道,连接口都写好了。
还真不得不说,这个视频实现,大部分代码还都是抄别人的
。不过,拿来注意也没什么不好。毕竟时间有限,容不得我去把每一个模块都自己一一实现了。剩下的就是用别人的代码实现自己的功能了。
我统计了一下,用他的压缩设置,我的视频压缩率在77~78之间,这样算下来,我只要300K左右的带宽就可以支持一路视频信号,还算比较理想。
接下来还有一个问题,传输协议的问题。TCP实时性不好,UDP可靠性不好,并且容易出现乱序。比较标准的选择应该是RTP协议。关于这些协议的特性,可以百度百度,详细了解一下。RTP协议可以自己实现,当然,懒人自然是懒办法,用别人的库呗。我用的是JRTP库。
在发送端,先从设备中提取原始的帧数据,然后用编码器编码,每个帧压缩完有几K,但是RTP包支持的最大大小是1000多个字节(可能是为了保持实时性),所以就需要拆分每个帧。我是这样做的,每个包的负载的第一个字节标示是否是一个帧的结束,如果是,则标为0,否则标为1。发送部分代码如下:
int bitToSend = videoSender->bitLen; int bitHaveSend = 0; unsigned char buff[1024]; while(bitToSend > 1000) { buff[0] = 1; memcpy(buff+1, videoSender->bitstream + bitHaveSend, 1000); videoSession.SendPacket(buff, 1001, 0,false,0); bitToSend -= 1000; bitHaveSend += 1000; } buff[0] = 0; memcpy(buff+1, videoSender->bitstream + bitHaveSend, bitToSend); int status = videoSession.SendPacket(buff, 1001, 0,false,0);
在接收端就循环接收,当收到包的负载的第一个字节是0的时候,就将已接收到的所有数据发送给解码器,然后解码器解码并显示出来。
关于不定长数据,还要考虑循环缓冲区接收的问题。
if(writePos + pack->GetPayloadLength() - 1 > IN_BITSTREAM_SIZE ) { memcpy(recvBuff + writePos, tempBuff + 1, IN_BITSTREAM_SIZE - writePos); memcpy(recvBuff, tempBuff + 1 + IN_BITSTREAM_SIZE - writePos, pack->GetPayloadLength() - 1 - IN_BITSTREAM_SIZE + writePos); writePos = (writePos + pack->GetPayloadLength() -1) % IN_BITSTREAM_SIZE; } else { memcpy(recvBuff + writePos, tempBuff + 1, pack->GetPayloadLength() - 1); writePos += pack->GetPayloadLength() - 1; }
这就是整个视频聊天的大概流程。说的有点笼统。但是自己写的代码又太烂了,不能模块化到直接拿出来就能供大家使用。我只能说说我的经验以及我用到的比较好的资源。希望我提到的这些资源和思路能帮到大家。
相关文章推荐
- 初探基于TCP的服务器/客户端结构的聊天系统(三)之表情聊天的实现
- 初探基于TCP的服务器/客户端结构的聊天系统(二)之应用层通信协议设计
- 初探基于TCP的服务器/客户端结构的聊天系统
- WINDOWS (服务器) 和 DOS(客户端) 网络互连 基于TCP/IP的编程实现
- WINDOWS (服务器) 和 DOS(客户端) 网络互连 基于TCP/IP的编程实现
- WINDOWS (服务器) 和 DOS(客户端) 网络互连 基于TCP/IP的编程实现
- winsock实现基于TCP的客户端/服务器通讯
- Android Socket编程基于TCP实现客户端与服务器简易通信
- 基于Linux的TCP多路复用IO结构网络在线聊天系统
- WINDOWS (服务器) 和 DOS(客户端) 网络互连 基于TCP/IP的编程实现
- Java基于TCP实现服务器和多客户端之间的通信
- 基于onvif规范的视频监控系统客户端(四):QT5.8+FFMPEG实现rtsp流的播放
- 基于C/S结构的高校学生网络行为规范系统的设计与实现(包含服务器与客户端)
- 基于MFC的视频监控系统客户端实现 ---项目经验
- C#使用Socket实现服务器与多个客户端通信(简单的聊天系统)
- WINDOWS (服务器) 和 DOS(客户端) 网络互连 基于TCP/IP的编程实现
- WINDOWS (服务器) 和 DOS(客户端) 网络互连 基于TCP/IP的编程实现
- WINDOWS (服务器) 和 DOS(客户端) 网络互连 基于TCP/IP的编程实现
- Python中的TCP编程,实现客户端与服务器的聊天(socket)
- golang简单实现一个基于TLS/SSL的 TCP服务器和客户端