3G下的无压缩视频传输(基于嵌入式linux) (转载)
本课题研究嵌入式系统在数据采集,3G无线通信方面的应用,开发集视频采集、地理信息采集、无线传输、客户机/服务器模式于一体的车载终端,实现终端采集视频与GPS信息的传输,支持服务器端显示视频与GPS信息的功能。 这里我着重介绍本项目中的视频传输。由于知识水平的缺乏和实验条件的限制,本人并没有采取视频压缩算法。但针对数据量大而且3G网络相对有线网络带宽限制的情况采取了措施。
硬件环境:友善之臂mini2440实验板(ARM9)。 操作系统:linux(终端)、windows7(服务器)。 网络环境:WCDMA(联通3G上网卡)。
Mini2440实验板上有CMOS摄像头接口。同时厂家提供的linux源代码中有摄像头驱动,编译进内核即可使用摄像头。摄像头采用的是OV9650,30万像素,在linux下作为字符串设备驱动,可通过读取设备文件,获得图像信息。
读取摄像头数据的代码如下:
int camdata_count;
int cam_fd=open("/dev/camera",O_RDONLY);
printf("Camera init!\n");
while(){
camdata_count=read(cam_fd,cam_data,**);
if(camdata_count==**){
/*视频数据处理与传输的代码*/
}
else{ printf("CAMERA Error!\n");
}
}
close(cam_fd);
从摄像头中读取的数据格式是RGB565的,如图所示。即红色分量占6位,绿色分量占6位,蓝色分量占5位,总共是16位。
为了作为bmp文件显示,需要将RGB565转换为RGB888(即24位真彩色)。再在文件开头加上bmp文件头,就成为一个完整的bmp文件了。用UDP协议传输这些图像数据。在服务器端,用.NET的库可以将接收到的BMP数据在图形界面的指定组件上显示。 .NET显示图像的代码如下:
// st是一个已经建立的MemoryStream对象,bmp_data是bmp数据(byte数组),bmpSize是BMP图像大小(单位是B)。
st.Write(bmp_data, , bmpSize);
try
{
picBox.Image = Image.FromStream(st);//picBox是已经建立的PictureBox对象,呈现在图形界面上
}
catch (Exception e)
{
richTextBox2.Text += "error\n";//如果BMP数据错误,则输出如下错误
}
//st对象清空
st.SetLength();
st.Position = ;
st.Flush();
流程图如下:
以上方案在有线网络传输的情况下能顺利运行,但是在3G网络下图像几乎不能显示。这是因为3G网络的带宽限制和UDP协议不可靠的缺点,数据在传输过程中会产生丢包现象,影响图片质量。对此需要改善程序代码,增加一些措施来避免丢包: (1) 将数据转化的工作交给服务器。 BMP文件基本不经过任何压缩,每个像素点占用3个字节(R、G、B分量分别占用一个字节),而从CMOS摄像头读取的数据是RGB565的,即一个像素点只占用2个字节。如果说从CMOS读取的图像信息不经真彩化处理,直接传输给服务器,这样,需要传输的数据量减少了大约1/3。 (2) 减少图像的尺寸。 从CMOS摄像头读取的图像尺寸是640*512的。如果打包成BMP数据的话,总共大小是640*512*3+54(B),大约960KB。如果说不经真彩化处理,一帧数据总共大小是640*512*2(B),大约640KB。正常情况下,一秒可以采集6-7帧图像。联通WCDMA理论的上行速率是5.76Mbps,约为720KB/s,实际情况一定低于此值。在此情况下,一秒基本上只能传输一帧图像。所以减小图片尺寸很必要。可以考虑将图片的长宽都减小为原来的1/6,再在服务器端进行真彩化处理和打包,放大为320*256的尺寸显示。这样,一帧RGB565的图像的大小约为107*86*2(B),约为18KB。这样就足够传输相应的数据了。 (3) 分包传输。 UDP协议仅负责传输,不保证对方可靠接收,没有拥塞控制。因此,在WCDMA这种相对来说较差的网络环境下,会造成大量数据包的丢失。实验证明,当一次传输数据量达到18KB(一帧的数据大小)时,丢包率在95%以上,这会严重影响图片质量。当一次传输数据量在1-2KB时,丢包率可以降低到一定值,并保证一定的传输效率。 (4) 每次数据传输之间给与一定延时。 如果将一帧图片分为每个1-2KB数据包来传输,大约要传输15-18次。在每次传输之间,如果不引入一定量的延时,同样会造成很大量的数据包丢失。而延时的时间也是需要把握好的,一般延时500-1000ns比较合适。在传输每帧图片之间,也需要给与一定的延时,此时延时时间过大的话,会造成每秒传输帧数过少,图片流畅率下降,一般传输每帧图片之间给予50ms的延时。
修改后的程序代码:
count=read(fd,cam_data,WIDTH*HEIGHT*);//缩小图片大小,data_buf为原图像数据,cam_data为缩小后的图像数据,两者都为字符数组类型 if(count==WIDTH*HEIGHT*){
shrink(data_buf,cam_data,WIDTH,HEIGHT);
for(i=;i<;i++){
//用UDP分包传输图像数据
sendto(sockfd,data_buf+(i*),,,(struct sockaddr *)&addr,len);
usleep();//给与一定的延时
}
printf("One picture sended!\n");//一帧传输完毕
usleep();
}
else{
printf("Error\n");
}
以上措施可以减少UDP传输视频数据的丢包率,但是,不管怎样,UDP传输数据的丢包现象普遍存在,或多或少会有一些。在3G网速较差的地区,丢包率甚至还是会达到50%。视频数据从摄像头读取后存放在一个无符号字符串数组里,本来是按顺序分割数据进行传输,由于读取的图像数据对应的像素点分布是从左到右、从上到下排布的,如果丢包,会造成接收到的图像的部分图像条无法及时更新,影响肉眼观察图像的质量。下面两张图对比了网络状况较好和较差情况下的显示效果。
上图是网络状况良好情况下的显示效果,可以看出,显示比较流畅,图像质量较好。下图是网络状况较差情况下的显示效果,可以看出,动态图像的某些图像条未及时更新,这是由于决定该图像条的显示的数据包在传输过程中丢包。
为了降低丢包带来的这种损失,可以考虑将每帧图像分成多个位平面并按一定顺序传输,每个位平面代表所有像素的同一位组成的二值图像。如下图所示,是每个位平面传输的顺序(从0开始计数)。
实验证明,每一帧分包传输后,靠前面的数据包丢包率比较小,而每个颜色分量的最高位对图片色彩质量的影响最大,位数越低,对图像色彩质量的影响越小。所以即便后面的位平面数据没有接收到,对图片色彩质量的影响也不会很大。将RGB每种颜色分量的位数按照从最高到最低的顺序进行传输,每种颜色分量对应的位平面穿插进行传输,于是就采用了上图所示的顺序。由于RGB565格式的数据每个像素共16位,一帧图片总共需要分16个位平面数据包传输。为了服务器能够正确进行图片数据的组装,在传输之前,将每个位平面数据包的最前面加上该包传输顺序的值,如下图所示。
终端部分代码如下:
shrink(data_buf,cam_data,WIDTH,HEIGHT);//缩小图片大小,data_buf为原图像数据,cam_data为缩小后的图像数据,两者都为字符数组类型
for(i=;i<;i++)
{
bzero(cut_buf,);
cut_buf[]=(uchar)i;//将要传输的数据首个字节设为顺序号
for(j=;j<;j++)
{
//每个像素按位分位平面数据包
cut_buf[j/+]|=(uchar)(((uchar)(data_buf[j]>>bit_index(i))&0x01)<<(j%));
}
sendto(sockfd,cut_buf,,,(struct sockaddr *)&cam_addr,sockaddr_len);//发送数据
usleep();//传输每个数据包之间的延时
}
printf("One picture sended!\n");//传输每帧图像之间的延时
usleep();
在服务器端,用如下函数进行数据的重组,同时进行真彩化处理(C#.NET语言):
private void picDataCopy(byte[] bBuf,byte[] bData) //bBuf为接收到的数据,bData是重组后的数据存放的数组
{
int index=bBuf[];
for (int i = ; i < ;i++ )//循环9202次,逐位进行数据的重组
{
if(index<){
bData[*i + - (index%)] |=
(byte)(((bBuf[i/ + ] >> (i%)) & 0x01) << ( - index/));
}
else if(index==){
bData[*i+]|=
(byte)(((bBuf[i/ + ] >> (i%)) & 0x01) << );
}
}
}
如上图所示,是在改变传输方案后,即采用按位平面传输的方法传输后的显示效果图,在网络良好的情况下,可以正常显示。在网络状况较差的情况下,图像颜色质量会下降,而且会不稳定地变化。但是部分图像条不显示的情况就不再出现。
总结:此方案重在联系,实际工程中肯定不会采取此方案,还是有必要学习视频压缩算法及其在linux上的移植。
转载时的图片都木有,花了好多功夫才还原这里面的图片,框架图.......
3G下的无压缩视频传输(基于嵌入式linux) (转载)的更多相关文章
- 【miscellaneous】【ARM-Linux开发】ARM平台基于嵌入式Linux Gstreamer 使用
1). 简介 随着ARM平台性能的日益强大和嵌入式设备的发展,对于多媒体处理如音视频播放,摄像头,流媒体处理等需求也日益增多,本文就通过几个基于嵌入式Linux下多媒体应用的示例来简单展示下使用Gst ...
- 基于嵌入式Linux的千兆以太网卡驱动程序设计及测试
一. 引言 千兆以太网是一种具有高带宽和高响应的新网络技术,相关协议遵循IEEE 802.3规范标准.采用和10M以太网相似的帧格式.网络协议和布线系统,基于光纤和短距离同轴电缆的物理层介质,更适用于 ...
- 7、基于嵌入式Linux的视频采集系统---UVC驱动模型介绍
UVC 即 usb video class.USB协议中,除了通用的软硬件电气接口规范等,还包含了各种各样的Class协议,用来为不同的功能定义各自的标准接口和具体的总线上的数据交互格式和内容.这些C ...
- 手把手带你基于嵌入式Linux移植samba服务
摘要:Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件,由服务器及客户端程序构成. 本文分享自华为云社区<嵌入式Linux下移植samba服务--<基于北斗和4G ca ...
- 基于嵌入式linux路由转发功能的实现
环境 arm7开发板, uclinux系统,kernel version: linux-2.4.x arm芯片的单网卡双网口设备,eth0 WAN口 ipaddr 192.168.9.61 eth0: ...
- 基于bootsplash的嵌入式linux启动画面定制
来源: ChinaUnix博客 作者: ChinaUnix博客 发布时间:2007-01-01 16:29:00 摘 要:在基于linux的嵌入式仿真平台研发中,利用开源工具bootsplash能够定 ...
- linux下视频传输测试
本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明. 在上一篇<ubuntu下基于qt+OpenCV控制摄像头>的基础上测试了视频传输. 环境:主 ...
- 一种H.264高清视频的无参考视频质量评价算法(基于QP和跳过宏块数)
本文记录一种无参考视频质量评价算法.这是我们自己实验室前两年一个师姐做的,算法还是比较准确的,在此记录一下. 注意本算法前提是高清视频.而且是H.264编码方式. 该方法主要使用两个码流里面的参数进行 ...
- DxPackNet 5.视频高质量的压缩和传输
DxPackNet 对视频的压缩和解压也提供了很好的支持,且系统不需要装第三方解码器哦~ 主要用到了 IxVideoEncoder 视频编码器 和 IxVideoDecoder 两个接口 这里只做简 ...
随机推荐
- sql server字符串中怎么添加换行?
换行/回车,可以使用CHAR函数处理,比如: 1 insert into tbtest (text) values ('abc' + char(13)+char(10) + 'def') 主要还是要看 ...
- 居然上了模板使用排行榜第一 happy一下
这段时间在学习css和div,顺便把博客给整了一下,然后不小心就上了FFandIE模板使用排行榜第一,happy一下下.不知道这个算不算排名,还是随机刷新.感觉应该是按流量统计的,这段时间有几篇文章一 ...
- MySQL字符集设置及字符转换(latin1转utf8)
MySQL字符集设置及字符转换(latin1转utf8) http://blog.chinaunix.net/uid-25266990-id-3344584.html MySQL字符集设置及字符转换 ...
- 003-Nginx 设置Header 获取真实IP
1.X-Forwarded-For的定义: X-Forwarded-For:简称XFF头,它代表客户端,也就是HTTP的请求端真实的IP,只有在通过了HTTP 代理或者负载均衡服务器时才会添加该项.它 ...
- Tomcat清空缓存方法
把Tomcat的work目录下有个Catalina全部删除
- kmeans聚类源代码
代码是在weka上二次开发的,但没有使用原来的kmeans代码,只是用了它的数据类Intances,先说下与它相关的几点东西. 一.KMeans算法简介 输入:聚类个数k,以及包含 n个数据对象的数据 ...
- XenServer:使用XenCenter开设VPS(多图完整版)
打铁要趁热,咱们接着来玩XenServer.昨天赵容用机房提供的KVM给服务器装了XenServer,今天我们来玩更有意思的:开小鸡.装好XenServer之后,访问我们的服务器IP,就可以看到Xen ...
- 机器学习理论基础学习14.1---线性动态系统-卡曼滤波 Kalman filter
一.背景 动态模型 = 图 + 时间 动态模型有三种:HMM.线性动态系统(kalman filter).particle filter 线性动态系统与HMM的区别是假设相邻隐变量之间满足线性高斯分布 ...
- 集成树模型使用自动搜索模块GridSearchCV,stacking
一. GridSearchCV参数介绍 导入模块: from sklearn.model_selection import GridSearchCV GridSearchCV 称为网格搜索交叉验证调参 ...
- docker搭建本地仓库并制作自己的镜像
原文地址https://blog.csdn.net/junmoxi/article/details/80004796 1. 搭建本地仓库1.1 下载仓库镜像1.2 启动仓库容器2. 在CentOS容器 ...