http://blog.sina.com.cn/s/blog_602f87700100znq7.html
最近有个需求,要在ARM Linux上实现USB Camera 拍照功能。
0. 背景知识:
首先要确认的是,Kernel是否支持USB Camera。因为Linux下,USB协议除了电气协议和标准,还有很多Class。 这些Class就是为了支持和定义某一类设备接口和交互数据格式。只要符合这类标准,则不同厂商的USB设备,不需要特定的driver就能在Linux下使用。
例如:USB Input class,则使所有输入设备都可以直接使用。还有类似Audio Class, Pring Class,Mass
其中Video Class 就是我们常说的UVC(USB Video Class). 只要USB Camera符合UVC标准。理论上在2.6 Kernel Linux 就可以正常使用。
网络上有人谈到怎样判断是否UVC Camera设备:
#lsusb
Bus 001 Device 010: ID 046d:0825 Logitech, Inc.
#lsusb -d 046d:0825 -v | grep "14 Video"
如果出现:
则说明是支持UVC.
1. Kernel配置:
Device Drivers
Device Drivers
--- V4L USB devices
分析:
"Video For Linux": 对应driver是:videodev.ko
安装driver顺序如下:
insmod
insmod
insmod
driver会创建一个或多个主设备号为81,次设备号:0-255的设备。
除了camera会创建为:/dev/videoX 之外,还有VBI设备-/dev/vbiX. Radio设备--/dev/radioX.
2. V4L2一些概念:
2.1:Video Input and Output:
video input and output是指device物理连接。
只有video 和VBI capture拥有input.
Radio设备则没有video input 和output.
2.2: Video Standards:
Video Device支持一个或多个Video 标准。
3. 使用V4L2编程:
使用V4L2(Video for Linux 2) API的过程大致如下:
Opening the device
Changing device properties, selecting a video and audio input, video standard, picture brightness a.
Negotiating a data format
Negotiating an input/output method
The actual input/output loop
Closing the device
3.1:打开设备:
fd = open ("/dev/video0", O_RDWR, 0); //以阻塞模式打开设想头
3.2: 查询设备能力:Querying Capabilities:
因为V4L2可以对多种设备编程,所以并不是所有API可以对所有设备编程,哪怕是同类型的设备,使用ioctl--VIDIOC_QUERYCAP去询问支持什么功能。
struct v4l2_capability cap;
rel = ioctl(fdUsbCam, VIDIOC_QUERYCAP, &cap);
if(rel != 0)
{
perror("ioctl VIDIOC_QUERYCAP");
return -1;
}
结构体如下:
struct v4l2_capability
{
};
这里面最重要的是:capabilities:头文件linux/videodev2.h和kernel头文件linux/videodev2.h中都有描述:
#define V4L2_CAP_VIDEO_CAPTURE 0x00000001
#define V4L2_CAP_VIDEO_OUTPUT 0x00000002
#define V4L2_CAP_VIDEO_OVERLAY 0x00000004
#define V4L2_CAP_VBI_CAPTURE 0x00000010
#define V4L2_CAP_VBI_OUTPUT 0x00000020
#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040
#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080
#define V4L2_CAP_RDS_CAPTURE 0x00000100
#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000200
#define V4L2_CAP_HW_FREQ