转载请注明来自:http://blog.csdn.net/ayangke 杨锞 QQ:843308498
快要找工作了,想将以前做的项目复习一下,同时给想做这个项目的童鞋一些指导。
硬件:MINI2440 软件:Linux-2.6.32
一、H.264介绍
H.264是一种视频压缩编码标准。该标准能够在较低带宽(2M以内)情况下提供高质量的图像传输。据数据分析,在同等画质下,H.264比上一代编码标准MPEG2平均节约64%的传输码流,而比MPEG4要平均节约39%的传输码流。
二、H.264视频监控系统架构
架构图如下
注意,摄像头最好采用网眼2000这款老摄像头,这款摄像头已经停产,很难找。我买了一个最新款的摄像头,最终由于采集的图像包数据过大,无法用UDP传输导致失败,因为UDP一次最多传送2K以内的包,否则会造成丢包,导致客户端收到数据显示为一片绿色。
三、视频数据采集接口V4L2
首先我们要解决的第一个问题当然是如何采集到摄像头的数据。要操作摄像头就要和摄像头驱动打交道,幸运的是现在的Linux内核已经集成了大多数的摄像头驱动。所以这点不需要我们关心,如果Linux内核没有集成就只有自己移植咯。
V4L2全称Video for Linux two,它是Linux提供的一套标准的API,应用程序通过一套API来调用音视频设备驱动操作音视频设备。这一套API屏蔽了音视频的硬件细节,提供了一个通用接口给应用程序。V4L2具体在Linux上以IOCTL系统调用提供给用户,通过IOTCL写入不同的命令实现音视频设备的不同操作。
具体操作流程如下:
首先打开视频设备,然后获取设备和图像的信息,如最大最小分辨率等,然后获得摄像头存储缓冲区的信息并且进行内存映射,再然后对摄像头进行一些必要的设置,如获取一帧图像的大小,图像的格式(RGB、YUV等等),然后启动采集。下面是一些常用的V4L2命令:
1 VIDIOC_REQBUFS:分配内存
2 VIDIOC_QUERYBUF:把VIDIOC_REQBUFS中分配的数据缓存转换成物理地址
3 VIDIOC_QUERYCAP:查询驱动功能
4 VIDIOC_ENUM_FMT:获取当前驱动支持的视频格式
5 VIDIOC_S_FMT:设置当前驱动的频捕获格式
6 VIDIOC_G_FMT:读取当前驱动的频捕获格式
7 VIDIOC_TRY_FMT:验证当前驱动的显示格式
8 VIDIOC_CROPCAP:查询驱动的修剪能力
9 VIDIOC_S_CROP:设置视频信号的边框
10 VIDIOC_G_CROP:读取视频信号的边框
11 VIDIOC_QBUF:把数据从缓存中读取出来
12 VIDIOC_DQBUF:把数据放回缓存队列
13 VIDIOC_STREAMON:开始视频显示函数
14 VIDIOC_STREAMOFF:结束视频显示函数
15 VIDIOC_QUERYSTD:检查当前视频设备支持的标准,例如PAL或NTSC。
具体操作参考这篇文章:http://blog.csdn.net/seven407/article/details/6401792#comments
四、H.264编码库的操作
通过V4L2接口我们采集到了一帧一帧的视频数据,然后我们的第二个问题是如何将内存中的帧数据进行H.264标准压缩了。H.264是一套标准,有很多组织对其进行的代码编写和实现,我用的是T264编码库,它是国内视频编码自由组织合力开发的。它遵循H.264视频编码标准,并吸收了JM,X264和Xvid三个源码的优点。在Linux下完成压缩编码。大家可以去下载T264的源码,然后进行编译,然后在T264/avr文件夹下会生成一些列*.obj文件,应用程序可以直接使用这些目标文件提供的功能函数对YUV格式视频进行编码。其流程如下图所示
首先init_param函数读取配置文件的一些编码配置信息,包括图像帧大小,1帧间距,参考帧数目等。T264的源码库中有配置参考文件enconfig.txt,一般需要改变的参数只有是图像帧大小的配置。然后t264_open调用init_param读取的配置信息读264编码器进行初始化。再然后调用T264_malloc为编码器分配空间用于存储编码后的帧数据。最后再调用T264_encode开始编码,该函数的参数包括上一部分V4L2操作中为视频数据映射的内存地址,且该函数会返回编码后一帧数据大小。这样视频数据就被压缩放到为T264分配的内存空间中了。当不需要编码的时候调用T264_close关闭编码器。
五、基于UDP方式的视频实时传输
当我们得到H.264编码标准压缩好的数据的时候我们需要发送到windows客户端,那下面一个问题便是如何与windows通信和传输视频数据。如何接触到网络编程应该都知道如何通过socket方式进行UDP数据传送。注意如果压缩后的数据包过大便无法通过UDP传输了,因为windows应用程序我没时间去写,是采用别人现成的,所以无奈只有用UDP方式了,如果你能写windows应用程序可以考虑采用TCP方式,然后摄像头就不局限于网眼2000了。下面是UDP传输方式流程:
UDP我就不多废话了,学过网络编程的都知道。
六、程序主流程图
七、结语
之所以去做这个项目是因为听了国嵌的项目视频,听了视频也没理出个思路来,后来查阅了很多资料才知道了大体思路。后来我查到一篇文章是桂林电子科大的硕士论文,将这个项目讲的很详细,也测试很多数据,同时说了windows应用程序的编写。我想这个项目的作者应该是来自此人吧,国嵌给的windows应用程序和文章上贴图的一样,没给源码,且还有BUG也没修复,后来我将此文章往国嵌的交流群一上传便被踢出了。不管这么多了,反正跟我无关。我给大家提供下载:http://download.csdn.net/detail/ayangke/3969255
此文只给了大体上的实现思路,具体实现还有童鞋们多查阅资料和多写代码啊!有问题可以联系我:qq:843308498。