在真正开始编写程序前,我作了大量工作,包括了解Linux支持的摄像头类型、Linux摄像头驱动程序、摄像头采集模型,等等,——当然,还包括去买个摄像头。网上流行的是gspca驱动以及一些老式摄像头的程序,这些摄像头目前市面上比较难找了。而且驱动、应用程序的安装也比较麻烦。此外,网上能搜索到的资料绝大部分均为转载而不注明出处,因此许多资料十分相似。而且许多资料都是介绍基本的流程,每当涉及到关键算法及代码时,均一句话带过。因此,只参考网上资料很难写出一个可能使用的程序。
我相信网上有许多人已经做出来了,不过我未查到能直接使用的程序。因此我决定将我所做的一切公布出来,——这是我的习惯,每当遇到难题而别人没有解决(或自己找不到牛人帮忙),我都会由着自己的性子将解决问题的过程写出来。这不是为了炫耀自己的能力,而是心中有一种怨气,觉得不爽,需要找个地方(用某种方式)发泄一下(下面讲到的那篇文章中,其实我已经删除了部分文字)。
我以“嵌入式 Linux 视频采集”等为关键字查阅许多期刊、论文(在学校的一大好处是可以免费下载万方的期刊、论文),但这些文章都是在一个很高很抽象的层次来讲解,动不动就涉及到系统设计、框架,如果想找点能使用的代码,基本上没有。当然,这是论文的最大特色。但是,我们还没有达到那么高的层次,我们需要的是代码,真正能使用的代码。
经过一段时候的搜索,我终于知道了一些专业名词,比如“UVC”、“V4L2”等,也看了一些介绍视采集的介绍。不过我还是有选择地查阅了V4L2官方的文档,将其中一些用得到的章节反复看几次。我曾一时心血来潮想翻译这个文档,甚至还到论坛上发帖想跟别人一起翻译,然而由于能力及时间问题,还是没有做成这件事(当时翻译了一些IBM developerworks上的文章,有点上瘾了)。这个时候,我发现网上那些号称xx的程序,不过是人家文档中给出的例子,——有意思的是,这个例子中处理图像的函数是空函数。同时,我找到了一个叫luvcview的开源项目,并阅读其中的代码,不过由于一些处理函数太过复杂,自己没能力理解(比如huffman、rgb、yuyv这些东西)。后面将这个项目中采集及显示的部分抽出来,自己整理,成为自己的程序——从中可以看到,这是站在别人肩膀上得到的结果。但不可否认,这中间有我的心血。
这次重新修改以前的代码,由于在编码风格上下了比较大的力气,因此还算顺利,没有遇到连自己也不认识的函数、变量名。此外,为了方便doxygen生成文档,在doxygen风格的注释中使用了中文。大部分相关的源代码文件使用了”UFT-8 无BOM格式编码“保存(实际使用的编辑器为notepad++)。注释也不是一件好差事,它也要讲究技巧及内容。当然,在发布之前必须做一些测试,至少要保证在自己的平台中测试没有问题才敢发布。下面是测试的环境:
虚拟机fc10
内核版本:
[latelee@latelee camera-pc-utf]$ uname -a
Linux latelee.latelee.org 2.6.27.5-117.fc10.i686 #1 SMP Tue Nov 18 12:19:59 EST 2008 i686 i686 i386 GNU/Linux
SDL版本:
[latelee@latelee camera-pc-utf]$ rpm -q “SDL”
SDL-1.2.13-6.fc10.i386
glibc版本:
[latelee@latelee camera-pc-utf]$ rpm -q “glibc”
glibc-2.9-2.i686
gcc版本:
[latelee@latelee camera-pc-utf]$ gcc –version
gcc (GCC) 4.3.2 20081105 (Red Hat 4.3.2-7)
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software ; see the source for copying conditions. There is NO
warranty ; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
摄像头参数:
蓝色妖姬天使系列T629小梅花
帧速: 30帧/秒
感应器: CMOS传感器
动态分辨率: 系统默认640X480
静态分辨率 2560×1920
接口 USB 2.0,兼容USB1.1
(测试图示可以查看文档的“main.c文件参考”)
在一次测试中,出现如下错误(将数据从缓冲区中取出时出现问题):
open success!
format(num):1448695129
fomat(human readable):YUYV
width:640
height:480
field:1 (1 if no fields)
bytesperline:1280
sizeimage:614400
colorspace:0(8 if RGB colorspace)
private field:0
get fomat OK!
===============================
I am ready!
press enter key to capture and display!
v4l2 init OK!
===============================
stream on OK!!
===============================
unable to dequeue buffer
Error grabbing
stream off OK!
===============================
munmap Info[22]:Invalid argument
Clean Up done Quit
未完之事:这个程序是我毕业设计的一部分。我的毕业设计的实际完成情况如下:
在ARM9芯片的Linux(内核2.6.30.2)平台中,使用V4L2采集USB摄像头视频数据,通过RTP(实时传输协议)传输到PC中,在PC使用SDL显示图像,由于传输处理得不好,只能显示176×144的图像。在最后验收过程中,评委老师们只看了显示的图像,并将这个东西与QQ视频那个图像对比,程序代码一行没看。最大的问题是:内存泄漏,当采集到一定帧数时,板子上的内核便挂了。我没有公布这个代码,因为这不一个完整的程序,等何时有空再重新研究这个问题吧。
最后,附上我的毕业设计论文最后的话。
毕业设计题目为“嵌入式Linux视频监控系统前端的设计与实现”,在整个毕设过程中,真正着重的是“前端”,而不是“视频监控系统”本身。
从毕业设计题目的选定到基本内容的完成,其间共跨越整整一个假期和差不多一个学期,时间不可谓不长。从选定题目开始笔者就着手毕业设计的事宜了,在毕业设计过程中笔者亦付出许多辛苦,然而,结果有诸多令笔者不满意之处。
在Linux系统的环境下开发跟在Windows下开发有天渊之别,——无论是帮助文档、可提供的资料还是IDE。笔者利用了假期的时候来锻炼个人Linux使用以及在其环境下编程的能力,包括了基本命令,编辑器和基本程序(如文件操作、IPC、多线程等)编程。如今,Linux对于笔者而言已经不再是一种高级、陌生的OS了,也渐渐习惯了Linux环境。[此段话有一半是假的,是为了应付别人,我很久就开始使用Linux了]
在开学后一个月中,笔者构建了开发环境,完成了Linux内核移植和根文件系统制作,这些网络上虽然有资源,但是到了实际情况中,只有靠摸索才能解决问题。此外,也测试也一些简单的驱动程序。但是,到了视频数据的采集,又遇到不少问题。目前Linux平台视频数据采集,网络上流行的是法国人写的USB摄像头驱动程序spca5xx和gspca在新的内核中编译失败,几经搜索,才知Linux内核已经包含了该驱动,才找到替代的驱动程序。虽然笔者最后采用了UVC驱动,但这些探索,着实花费了不少时间和精力。
此时,又遇到许多跟视频、图像格式相关的知识,比如RGB、YUYV、MPEG、MJPEG等等。由于接触时间短,至今对这些知识还是不太了解。[这个过程主要向Litte Crab(李迟好友之一)请教]
最后便是网络部分了。以前学习网络课程时,只有一些理论基础,未真正在某一环境下编写过程序。虽然研究过基于AVR芯片的ENC28J60的程序,但也只限于程序的阅读,并没有实践。这次的实践,尝试了TCP和UDP两种方式,但不理想,最后决定还是使用RTP(RTP库,使用UDP传输方式),这才使网络部分得以完成。
为了使系统有一个“整体”性,笔者编写了Linux下的“上位机”,它个体使用SDL库来显示图像,编写过程中又花费不少时间。最终,才能使整个系统有一个粗糙的完整性。当然这个系统存在许多漏洞,有待进一步完善。
在选题中,笔者并没有看到日后出现的问题。笔者的本意是学习嵌入式Linux,但是这学习代码太大,牵涉到内容太广,这倒是笔者始料未及的。
但是,无论怎样,笔者的付出也得到一定的回报,——虽然在做毕业设计过程中的辛苦不亚于当初学习单片机的辛苦。这些付出和回报,将成为我人生的一笔珍贵的财富。
本次修改代码下载:camera-pc-utf.latelee.org.tar.bz2下载在Linux公社的1号FTP服务器里,下载地址:
FTP地址:ftp://www.linuxidc.com
用户名:www.linuxidc.com
密码:www.muu.cc
在 2011年LinuxIDC.com\3月\关于Linux平台视频采集程序的修改
下载方法见 http://www.linuxidc.net/thread-1187-1-1.html