在Windows下,摄像头驱动由厂商开发并提供。但在Linux下,因商业利益有限,只有极少厂商愿意提供摄像头驱动支持。这并不妨碍Linux下摄像头的使用——广大第三方志愿者维护着大大小小的驱动。之前做过一个嵌入式皮毛项目,虽然摄像头驱动不关我的事,在好奇心驱使下简要探索了一番。结果是有些胸闷,它们像蜘蛛丝一样杂乱。写本文的动机是想理清一下主线,给后来者提供一点有限的参考,但无法保证下面的文字完全正确。
常见的摄像头驱动有以下几个系列: OVCam drivers(ov5xx)
该系列驱动是针对OmniVision OV5xx系列芯片,此类芯片被广泛运用于各种USB摄像头中,在嵌入式开发板上尤其常见。凡是使用了OV511/OV511+/OV518 /OV6620/OV6630/OV7610/OV7620/OV7 620AE等图像传感器的摄像头都可以在该驱动下工作。
项目主页:http://alpha.dyndns.org/ov511/
Philips USB Webcam Driver(pwc) 该驱动主要用于Philips及pwc芯片兼容摄像头。由于原开发者与Philips公司签有保密协定,该驱动以二进制形式提供,后来被踢出内核,引起一场口水战:是用户需求重要还是保持内核纯洁重要?所幸后续开发者从原项目上创建了一个新的分支,使得该项目继续存活。
项目主页:http://www.saillard.org/linux/pwc/
QuickCam USB camera driver (qc-usb) 该驱动主要用于Logitech公司的QuickCam Express系列和其它兼容型号摄像头。最初由Georg Acher开发,当时命名为qce-ga。Jean-Frederic Clere参考该驱动创建出了第一个Video4Linux兼容驱动。从那开始,不断有开发者加入,使得该驱动逐渐能够支持新的摄像头和芯片。在此期间,该驱动更名为qc-usb,更为广泛地支持其它QuickCam USB摄像头,而不再是局限于Express系列。
项目主页:http://qce-ga.sourceforge.net/
QuickCam Messenger & Communicate driver(quickcam) 这是另一个针对QuickCam摄像头的驱动,它仅支持某一些型号,并且与qc-usb驱动不兼容。项目主页:http://home.mag.cx/messenger/
SPCA webcam driver(gspca/spca5xx) 该系列驱动适用于Sunplus芯片摄像头,也适用于其它芯片,如目前国内山寨摄像头一哥“中星微”(Z-Star)芯片。Michel Xhaard是该项目的维护者,他在60岁左右的时候(大约是2003年)从一种普通常见的驱动入手,进而不断修改开发成一个支持250种以上摄像头的通用驱动。他还写了流媒体服务器spcaserv与客户端spcaview。不少高校所谓的嵌入式无线网络视频传输项目,就是从这两个东西来的。
项目主页:http://mxhaard.free.fr/spca5xx.html
Linux UVC driver(uvc) 该驱动适用于符合USB视频类(USB Video Class)规范的摄像头设备,它包括V4L2内核设备驱动和用户空间工具补丁。大多数大容量存储器设备(如优盘)都遵循USB规范,因而仅用一个单一驱动就可以操作它们。与此类似,UVC兼容外设只需要一个通用驱动即可。
USB摄像头大体上可以二分为UVC cameras和non-UVC cameras。推荐购买UVC cameras。UVC是一个开放的标准,拥有维护良好的驱动,它属于内核代码的一部分。插入摄像头后就可以工作,而无须编译或安装额外的驱动。non- UVC cameras通常情况下不比UVC cameras工作出色,前者的驱动并不遵循通用的协议,需要针对每种摄像头做出单独的处理,这往往需要一个逆向工程的探索过程。
判断一个摄像头是否属于UVC规范可以使用下面方法:
1.使用lsusb命令或其它硬件信息查看工具找出摄像头的设备号(Vendor ID)和产品号(Product ID)。如Logitech Quickcam for Notebooks Pro摄像头是046d:08cb;
2.查找是否有视频类接口信息
lsusb -d 046d:08cb -v | grep "14 Video"
如果该摄像头兼容UVC,则会输出类似信息
bFunctionClass 14 Video
bInterfaceClass 14 Video
bInterfaceClass 14 Video
bInterfaceClass 14 Video
若无以上信息,则是non-UVC设备。
项目主页:http://linux-uvc.berlios.de/
在Linux下摄像头驱动有三种存在形式,内置于内核(within the kernel),做为一个外挂的模块(module),或者是预编译的二进制程序(pre-compiled binary)。
Linux内核树会不断合并优秀的驱动。从2.4内核起,ov5xx驱动就已经是内核代码的一部分。从2.6.26开始,Linux内核原生包含uvc 驱动。2.6.27内核又吸收进了gspca/spca5xx系列驱动。常见的Linux发行版所配置的内核,一般都已将这些驱动选项打开,而无需用户另外编译。内核的.config文件中有许多配置变量等式,用来说明内核配置的结果。y表示本编译选项对应的内核代码被静态编译进 Linux内核;m表示本编译选项对应的内核代码被编译成模块;n表示不选择此编译选项。
以Fedora12/boot下的config文件为例
cat /boot/config-2.6.31.12-174.2.3.fc12.i686 | grep CONFIG_USB_GSPCA
CONFIG_USB_GSPCA=m
CONFIG_USB_GSPCA_CONEX=m
CONFIG_USB_GSPCA_ETOMS=m
CONFIG_USB_GSPCA_FINEPIX=m
CONFIG_USB_GSPCA_MARS=m
CONFIG_USB_GSPCA_MR97310A=m
CONFIG_USB_GSPCA_OV519=m
CONFIG_USB_GSPCA_OV534=m
CONFIG_USB_GSPCA_PAC207=m
CONFIG_USB_GSPCA_PAC7311=m
CONFIG_USB_GSPCA_SN9C20X=m
CONFIG_USB_GSPCA_SN9C20X_EVDEV=y
CONFIG_USB_GSPCA_SONIXB=m
CONFIG_USB_GSPCA_SONIXJ=m
CONFIG_USB_GSPCA_SPCA500=m
CONFIG_USB_GSPCA_SPCA501=m
CONFIG_USB_GSPCA_SPCA505=m
CONFIG_USB_GSPCA_SPCA506=m
CONFIG_USB_GSPCA_SPCA508=m
CONFIG_USB_GSPCA_SPCA561=m
CONFIG_USB_GSPCA_SQ905=m
CONFIG_USB_GSPCA_SQ905C=m
CONFIG_USB_GSPCA_STK014=m
CONFIG_USB_GSPCA_SUNPLUS=m
CONFIG_USB_GSPCA_T613=m
CONFIG_USB_GSPCA_TV8532=m
CONFIG_USB_GSPCA_VC032X=m
CONFIG_USB_GSPCA_ZC3XX=m
可以看到gspca系列驱动被编译为模块。当插入摄像头后,使用dmesg命令可以打印出以下信息:
usb 1-1.2: new full speed USB device using ehci_hcd and address 6
usb 1-1.2: New USB device found, idVendor=046d, idProduct=08af
usb 1-1.2: New USB device strings: Mfr=0, Product=0, SerialNumber=0
usb 1-1.2: configuration #1 chosen from 1 choice
gspca: probing 046d:08af
zc3xx: probe 2wr ov vga 0x0000
zc3xx: probe sensor -> 0011
zc3xx: Find Sensor HV7131R(c)
gspca: probe ok
这说明该摄像头被识别,且自动挂载了gspca系列下的zc3xx驱动。
如果由于某种原因,已配置的内核中没有包括摄像头驱动,可以重新配置内核选项,用新编译的内核替换原有的旧内核。或者是依据设备号及产品号,直接到对应驱动的项目主页,下载源码进行编译。
最后总结一下
如果你想买一个摄像头,推荐买Logitech的,买符合UVC驱动的,可以到这里挑一款。
如果你已经有了一个摄像头,先插进去看看,Linux对它有没有反应。记录dmesg输出信息,记录lsusb输出设备号,以设备号为关键字上Google搜索。
参考资源 http://www.tldp.org/HOWTO/Webcam-HOWTO/
http://www.chineselinuxuniversity.net/courses/kern el/articles/19988.shtml
http://www.quickcamteam.net/
如果你能在http://linux-uvc.berlios.de/找到你的摄像头的ID,即UVC支持的,那么就可以在linux下使用了。
至于从哪个版本开始内核支持UVC,官方的话是“Linux 2.6.26 and newer includes the Linux UVC driver natively.”
1、查看摄像头ID:
[root@151 dev]# lsusb
Bus 002 Device 013: ID 0ac8:3313 Z-Star Microelectronics Corp.
0xc8:3313在UVC中支持了。
2、插入摄像头后,就可以在/dev/下查看是否有video设备文件:
[root@151 dev]# ls | grep video
video
video0
其中,video是video0的连接。如果没有再现,可能UVC没有配置到内核中,重新配置就可以了
(大致在Device DriversàMultimedia devicesàVideo capture adaptersàV4L USB devices下面)。如果内核配置了,
还是不出现,可以使用modprobe uvcvideo来加载该模块。
3、先看看摄像头的相关信息:
lshal | grep Cam
出现:
info.product = 'Vega USB 2.0 Camera.' (string)
usb_device.product = 'Vega USB 2.0 Camera.' (string)
usb.interface.description = 'Vega USB 2.0 Camera.' (string)
info.product = 'Vega USB 2.0 Camera.' (string)
input.product = 'Vega USB 2.0 Camera.' (string)
info.product = 'Vega USB 2.0 Camera.' (string)
对USB有研究的,就很熟悉这些字段。
再看一下系统能不能识别出摄像头:
[root@151 log]# dmesg | grep Cam
uvcvideo: Found UVC 1.00 device Vega USB 2.0 Camera. (0ac8:3313)
input: Vega USB 2.0 Camera. as /class/input/input6
usb 2-7: Product: Vega USB 2.0 Camera.
uvcvideo: Found UVC 1.00 device Vega USB 2.0 Camera. (0ac8:3313)
input: Vega USB 2.0 Camera. as /class/input/input7
usb 2-7: Product: Vega USB 2.0 Camera.
uvcvideo: Found UVC 1.00 device Vega USB 2.0 Camera. (0ac8:3313)
input: Vega USB 2.0 Camera. as /class/input/input8
usb 2-7: Product: Vega USB 2.0 Camera.
[root@151 ~]# dmesg | grep video
pci 0000:05:00.0: Boot video device
Linux video capture interface: v2.00
usbcore: registered new interface driver uvcvideo
uvcvideo 2-7:1.0: usb_probe_interface
uvcvideo 2-7:1.0: usb_probe_interface - got id
uvcvideo: Found UVC 1.00 device Vega USB 2.0 Camera. (0ac8:3313)
uvcvideo 2-7:1.0: usb_probe_interface
uvcvideo 2-7:1.0: usb_probe_interface - got id
uvcvideo: Found UVC 1.00 device Vega USB 2.0 Camera. (0ac8:3313)
uvcvideo 2-7:1.0: usb_probe_interface
uvcvideo 2-7:1.0: usb_probe_interface - got id
uvcvideo: Found UVC 1.00 device Vega USB 2.0 Camera. (0ac8:3313)
哈哈,识别出来了!可以测试了。
4、我使用的软件是luvcview,这个软件google就可以找到的。安装过程很简单,——make,make install就可以了。(哈哈,这里才说)
下面这个过程是测试过程,从看到图像到结束的过程:
[root@151 dev]# luvcview -d /dev/video0 -f yuv -s 640x480 (直接运行luvcview也可)
uvcview verion 0.1.4
size width: 640 height: 480
Video driver: x11
A window manager is available
video /dev/video0
Stop asked
Clean Up done Quit
[root@151 dev]#
解释命令:
-d 设备名,这里/dev/video或/dev/video0都可以,因为它们都是一个文件
-f 格式,有yuv和jpg两种,后者测试不行
-s 大小,能支持的最大尺度可能由luvcview决定,也可能由摄像头决定,(应该是后者,暂没有研究)
更具体的参见luvcview目录下的README文件。
另外,如果没有插入摄像头,即使modprobe uvcvideo也不会出现/dev/video设备文件;插入摄像头,即使没有modprobe uvcvideo,
也会出现/dev/video设备文件,当然这是我的测试,没有代表性,也没有理论根据的。
注:
1、UVC:USB Video Class
2、gspcav不是不再维护,而是在某一版本开始已经纳入内核了,至于哪个版本(2.6.26),就不太清楚了。特此说明。
Servfox和Spcaview 建立嵌入式视频监控系统
一 移植摄像头驱动
目前摄像头(Webcam)在 Linux 中驱动基本成熟,缺少的是应用程序的支持,比如即时通讯工具支持视频的好程序比较少。在国内,大多摄像头的芯片组是Z-Star,也有显示为Vimmicro(和Z-Star是同样的芯片)的。目前Linux下的摄象头驱动可以使用spca5xx,spca5xx是LINUX下的万能摄象头驱动,也支持支持ZC30X系列摄像头。可以从 http://mxhaard.free.fr/download.html 下载。
在 Linux中,硬件的驱动程序,都是由内核支持的;目前比较新内核版本也集成了一些的摄像头驱动。所以支持也是极为正常的。内核对硬件的支持分为内置于和外挂模块两种方便。对于摄像头来说,大多是模块支持的。比如我用的博创开发板就加入了spca5xx摄象头驱动的支持。如果开发板没有加入,可以把spca5xx稍加修改移植到ARM平台下。
二 移植服务器端程序servfox
下载servfox-R1_1_3.tar.gz,解压,进入其目录,观察,发现没有makefile,但有一个makefile.arm,还有一个makefile.386,将makefile.arm改名为makefile,然后修改Makefile文件将CC改成arm-linux-gcc,然后输入命令make编译即可。
将可执行文件servfox复制到nfs共享目录,启动开发板,挂载nfs服务器,运行servfox,出错,提示为找到该命令,老问题,以前遇到过类似问题,原因是该命令为动态链接,而开发板上没有相关的库文件,所以无法运行,解决方法。
1静态链接 回到PC,打开makefile,将所有用到arm-linux-gcc的地方,都加上一个参数-static,其实就三个地方。然后重新编译,在开发板上运行,输入命令:
./servfox -d /dev/video0 -s 320x240 -w 7070
2 动态链接 把生成的动态链接库加载到开发板
运行中遇到的问题,servfox的设备必须是/dev/video0,直接用这个/dev/v4l/video0不行,提示v4l接口错误,建个链接
(ln -s /dev/v4l/video0 /dev/video0)
三 编译客户端程序spcaview
SpcaView 软件包,包括一组工具:
spcaview工具是用来纪录数据流,也能用来播放数据,既可以做采集端,也可以做接收端。
spcaserv 是流媒体服务器
spcacat 简单图片的抓取工具
下载spcaview-20061208.tar.gz,解压,进入其目录,直接编译,make
生成可执行文件spcaview,运行之
./spcaview -g -s 320x240 -w 192.168.141.236:7070
段错误的解决方法:用mmap方法不行,必须要用read方法,运行servfox时加参数-g。
四 Serfox和Spcaview的命令参数
(1)spcaview的命令参数
Spcaview version: 1.1.7 date: 06:11:2006 (C) [email protected]
usage: spcaview [-h -d -n -c -v -j -z -g -l -s -m -a -f -b -t -p] [-i inputfile
| -o outputfile]
-h print this message
-d /dev/videoX use videoX device
-n norme 0->pal 2->secam 1->ntsc
-c input channels 0..9 exclude 4 and 5
-v disable video output for raw recording
-j disable video output and userspace decoding
-z compress yuv420p video output with DPSH encoder
-g use read method for grab instead mmap
-l default 320x480 use input size 640x480
-s widthxheight use specified input size
-m widthxheight use specified ouput size
-a default 0 -> nosound 1-> microphone 2-> mixer output
-f video format default yuv others options are r16 r24 r32 yuv jpg
-b enable automatic brightness adjustment
-t print statistics
-p x getPicture every x seconds
-p x && -o getPicture every x seconds and record in outfile
-w Address:Port read from Address xxx.xxx.xxx.xxx:Port
-N x take a x pictures and exit if p is not set p = 1 second
(2)serfox的命令参数
-h print this message
-d /dev/videoX use videoX device
-g use read method for grab instead mmap
-s widthxheight use specified input size
-w port server port