V4L是 Video for Linux的缩写,它是Linux 内核中关于视频设备的子系统,它为linux 下的视频驱动提供了统一的接口,使得应用程序可以使用统一的API 函数操作不同的视频设备,极大地简化了视频系统的开发和维护。
由于早期的 V4L 有很多缺陷,Bill Dirks 等人对其进行了重新设计,并取名为Video for Linux 2(V4L2使用),最早出现于Linux2.5.x 版本。V4L2 相比于V4L 有更好的扩展性和灵活性,并且支持的硬件设备更多。
因此在应用程序V4L编程实际是指v4l2,我们这个系列的以V4L2为主,但由于历史的原因,V4L2一般兼容V4L.所以很多程序可以用V4L接口.
1.V4L支持设备
V4L2(video for linux) 可以支持多种设备,它可以有以下几种接口:
1. 视频采集接口(video capture interface):这种应用的设备可以是高频头或者摄像头.V4L2的最初设计就是应用于这种功能的.下面也是着重讲解这种应用.
2. 视频输出接口(video output interface):可以驱动计算机的外围视频图像设备--像可以输出电视信号格式的设备.
3. 直接传输视频接口(video overlay interface):它的主要工作是把从视频采集设备采集过来的信号直接输出到输出设备之上,而不用经过系统的CPU.
4. 视频间隔消隐信号接口(VBI interface):它可以使应用可以访问传输消隐期的视频信号.
5. 收音机接口(radio interface):可用来处理从AM或FM高频头设备接收来的音频流.
2.V4L处理基本流程
跟一般设备处理一样,大体上V4L处理有四个流程.
2.1 打开V4L设备结点
一般V4L设备结点名是 /dev/videoN.如第一个V4L设备是/dev/video0.
int fd = open("/dev/video0",O_RDWR |O_NONBLOCK);
2.2配置设备/查询设备属性
主要通过ioctl来操作,象V4L2 常见的的命令有
格式
int ioctl (int __fd, unsigned long int __request, ...) ;
__request是V4L2一些ioctl命令,常见如下.
- VIDIOC_REQBUFS:分配内存
- VIDIOC_QUERYBUF:把VIDIOC_REQBUFS中分配的数据缓存转换成物理地址
- VIDIOC_QUERYCAP:查询驱动功能
- VIDIOC_ENUM_FMT:获取当前驱动支持的视频格式
- VIDIOC_S_FMT:设置当前驱动的频捕获格式
- VIDIOC_G_FMT:读取当前驱动的频捕获格式
- VIDIOC_TRY_FMT:验证当前驱动的显示格式
- VIDIOC_CROPCAP:查询驱动的修剪能力
- VIDIOC_S_CROP:设置视频信号的边框
- VIDIOC_G_CROP:读取视频信号的边框
- VIDIOC_QBUF:把数据从缓存中读取出来
- VIDIOC_DQBUF:把数据放回缓存队列
- VIDIOC_STREAMON:开始视频显示函数
- VIDIOC_STREAMOFF:结束视频显示函数
- VIDIOC_QUERYSTD:检查当前视频设备支持的标准,例如PAL或NTSC。
完整的IOCTL命令参见http://v4l2spec.bytesex.org/spec/r7624.htm
2.3 处理V4L视频数据
在V4L设备中,有的设备从硬件取出,送到应用程序处理,比如摄像头硬件取得视频数据后,通过V4L接口把视频数据发送应用程序, 比如显示屏幕或保存成为文件.
有的设备是从应用发往硬件处理,如电视接口.
在V4L接口,设定了三种应用程序与驱动的交互方式,分别是
直接读取设备文件方式(read/write)、用户指针方式(userptr)以及mmap 映射方式。
1)mmap方式,驱动将内部数据空间映射到应用程序空间上,双方直接在这个空间进行数据交换,是效果最高的方法,这也是最常用的方式之一
2)
直接读取设备文件方式 直接调用 read()、write()函数进行数据的读入和输出,该方法一般配合select()使用。
3)用户指针方式 首先由应用程序申请一段缓冲区,然后将缓冲区传给驱动,驱动将其作为缓冲区,从而实现了内存共享。这一方法用的较少.
2.4 关闭设备
调用close();如果是内存映射方式,在关闭前还需要调用munmap解除映射.
3.V4L两个版本区别
1.头文件不一样 V4L使用#include
V4L2使用 #include
2.IOCTL命令编号 ,V4L使用 VIDIOCXXXX的形式,而V4L2使用VIDIOC_XXXX 或 VIDIOC_G_XXXX形式.
如V4L中取设备属性命令是VIDIOCGCAP,而V4L2对应的是VIDIOC_QUERYCAP.
3.两者数据结构不一样,V4L以Video_为前缀,而V4L以v4l2_为前缀.如设备属性
V4l1--> struct video_capability video_cap
V4l2-->struct v4l2_capability
4.检测V4L设备版本
在V4L2中,规定必须实现 VIDIOC_QUERYCAP命令,而V4L1,规定必须实现VIDIOCGCAP,用这个方法可以判断设备的版本.参见如下代码.
#include <stdio.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <linux/videodev2.h> #include <linux/videodev.h> int test_v4l_version(int fd) { int ret = 0; char dummy[256]; if (-1 != ioctl(fd,VIDIOC_QUERYCAP,dummy)) { ret = 2; } else if (-1 != ioctl(fd,VIDIOCGCAP,dummy)) { ret = 1; } return ret; } int main(int argc,char * argv[]) { char dev_name[64] = "/dev/video0"; int cam_fd =-1; if(argc>1) { strncpy(dev_name,argv[1],sizeof(dev_name)-1); } printf("open device %s\n",dev_name); cam_fd = open(dev_name,O_RDWR|O_NONBLOCK); if(cam_fd == -1) { printf("open failure \n"); return -1; } switch(test_v4l_version(cam_fd)) { case 0: printf("%s:fd %d isn't v4l deivce\n",dev_name,cam_fd); return -1; break; case 1: printf("\n### video4linux device info [%s] ###\n",dev_name); return -2; break; case 2: printf("\n### v4l2 device info [%s] ###\n",dev_name); break; } close(cam_fd); return 0; }
|
5.测试环境:
开发板 Mini6410,内核 Linux 2.6.28.6
CMOS 摄像头, USB摄像头两个 ZC301,和一般USB 2.0通用摄像头一个
其中 /dev/video0 ,/dev/video1 是CMOS的设备结点,/dev/video2是USB摄像头的结点
一.设备性能查询
在V4L第二步,对用ioctl来查询设备属性和配置,
这里我们用
VIDIOC_QUERYCAP来进设备属性查询操作,这是一个v4l2设备必须实现的操作
这里使用
ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);
这里查询的结果保存在数据结构
struct v4l2_capability cap;当中,它有如下定义
struct v4l2_capability { __u8 driver[16]; __u8 card[32]; __u8 bus_info[32]; __u32 version; __u32 capabilities; __u32 reserved[4]; };
|
另外硬件视频数据输入的参数,可以用VIDIOC_ENUMINPUT来做多次查询.
struct v4l2_input input;
int ret;
memset(&input, 0, sizeof(input));//initialize i.index=0;
PRINT_V4L("inputs\n");
while(ret=ioctl(fd, VIDIOC_ENUMINPUT, &input)>=0)
{
}
其中使用
v4l2_input 数据结构定义如下
struct v4l2_input { __u32 index; __u8 name[32]; __u32 type; __u32 audioset; __u32 tuner; v4l2_std_id std; __u32 status; __u32 reserved[4]; };
|
2.视频格式查询
在 v4l2中,有两种查询视频格式的方法,一个遍历所有视频格式的, 一次查询出一种格式的,使用ioctl VIDIOC_ENUM_FMT
- struct v4l2_fmtdesc fmtdesc;
- int i=0;
- memset(&fmtdesc, 0, sizeof(fmtdesc));
-
- for(i=0;;i++)
- {
- fmtdesc.index = i;
- fmtdesc.type = type;
-
- if(-1== ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc))
- break;
- }
另外是一次性查询所有格式用,VIDIOC_G_FMT
- struct v4l2_format format;
- memset(&format,0,sizeof(format));
- format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- if (-1 == ioctl(fd,VIDIOC_G_FMT,&format))
- {
- perror("VIDIOC_G_FMT(VIDEO_CAPTURE)");
- return -1;
- }
2.具体代码
- /*
- * Author: Andrew Huang <bluedrum@163.com>
- * query v4l2 device capabilities
- * date: 2010/06/16
- */
- #include <stdio.h>
- #include <string.h>
- #include <errno.h>
-
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
-
- #include <linux/videodev2.h>
-
- #define PRINT_V4L printf
-
- #define PRINT_IOCTL_CMD(cmd) printf(" s = (0x%x)\n",#cmd,cmd)
- #define PRINT_IOCTL_CMD2(cmd,n) printf(" %-20s(%d) = (0x%x)\n",#cmd,n,cmd)
-
- #define PRINT_V4L_MEMBER(m) printf(" %-20s:",#m);
- #define PRINT_V4L_STRING(m) printf(" %-20s:\"%s\"\n",#m,m)
- #define PRINT_V4L_INT(m) printf(" %-20s:%d\n",#m,m)
- #define PRINT_V4L_INTX(m) printf(" %-20s:0x%x\n",#m,m)
-
- /* 显示enum 值的之一*/
- #define TEST_V4L_FLAG0(m,f) printf("%s",((m & f)==f)?#f:"")
-
- /* 显示一个组合值的所有内容 */
- #define PRINT_V4L_FLAGS(m) printf(" %-20s:0x%x [",#m,m) /* 组合值开始*/
- #define TEST_V4L_FLAG(m,f) printf("%s",((m & f)==f)?#f",":"") /* 组合值中间值,可以有多个*/
- #define PRINT_V4L_FLAGS2(m) printf("]\n") /* 组合值结束*/
-
-
- #define PRINT_INT(e) printf("%s=%d\n",#e,e)
-
-
-
-
- int v4l2_query_video_cap(int fd)
- {
- int ret;
- struct v4l2_capability cap;
- ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);
- if(ret < 0)
- {
- printf("get vidieo capability error,error code: %d \n", errno);
- return ret;
- }
- PRINT_V4L("general info\n");
- PRINT_IOCTL_CMD(VIDIOC_QUERYCAP);
-
- PRINT_V4L_STRING(cap.driver);
- PRINT_V4L_STRING(cap.card);
- PRINT_V4L_STRING(cap.bus_info);
- PRINT_V4L_MEMBER(cap.version);printf("%u.%u.%u\n",(cap.version>>16)&0XFF,(cap.version>>8)&0XFF,cap.version&0xFF);
-
- PRINT_V4L_FLAGS(cap.capabilities);
- TEST_V4L_FLAG(cap.capabilities,V4L2_CAP_VIDEO_CAPTURE);
- TEST_V4L_FLAG(cap.capabilities,V4L2_CAP_VIDEO_OUTPUT);
- TEST_V4L_FLAG(cap.capabilities,V4L2_CAP_VIDEO_OVERLAY);
- TEST_V4L_FLAG(cap.capabilities,V4L2_CAP_VBI_CAPTURE);
- TEST_V4L_FLAG(cap.capabilities,V4L2_CAP_VBI_OUTPUT);
- TEST_V4L_FLAG(cap.capabilities,V4L2_CAP_SLICED_VBI_CAPTURE);
- TEST_V4L_FLAG(cap.capabilities,V4L2_CAP_SLICED_VBI_OUTPUT);
- TEST_V4L_FLAG(cap.capabilities,V4L2_CAP_RDS_CAPTURE);
- TEST_V4L_FLAG(cap.capabilities,V4L2_CAP_VIDEO_OUTPUT_OVERLAY);
- TEST_V4L_FLAG(cap.capabilities,V4L2_CAP_HW_FREQ_SEEK);
- TEST_V4L_FLAG(cap.capabilities,V4L2_CAP_TUNER);
- TEST_V4L_FLAG(cap.capabilities,V4L2_CAP_AUDIO);
- TEST_V4L_FLAG(cap.capabilities,V4L2_CAP_RADIO);
- TEST_V4L_FLAG(cap.capabilities,V4L2_CAP_READWRITE);
- TEST_V4L_FLAG(cap.capabilities,V4L2_CAP_ASYNCIO);
- TEST_V4L_FLAG(cap.capabilities,V4L2_CAP_STREAMING);
-
- PRINT_V4L_FLAGS2(cap.capabilities);
- return 0;
-
- }
-
- static void _show_capture_type(enum v4l2_buf_type type)
- {
- TEST_V4L_FLAG(type,V4L2_BUF_TYPE_VIDEO_CAPTURE);
- TEST_V4L_FLAG(type,V4L2_BUF_TYPE_VIDEO_OUTPUT);
- TEST_V4L_FLAG(type,V4L2_BUF_TYPE_VIDEO_OVERLAY);
- TEST_V4L_FLAG(type,V4L2_BUF_TYPE_VBI_CAPTURE);
- TEST_V4L_FLAG(type,V4L2_BUF_TYPE_VBI_OUTPUT);
- TEST_V4L_FLAG(type,V4L2_BUF_TYPE_SLICED_VBI_CAPTURE);
- TEST_V4L_FLAG(type,V4L2_BUF_TYPE_SLICED_VBI_OUTPUT);
- TEST_V4L_FLAG(type,V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY);
- TEST_V4L_FLAG(type,V4L2_BUF_TYPE_PRIVATE);
- }
-
-
- //void show_video_std(v4l2_std_id std)
- void show_video_std(v4l2_std_id std)
- {
- // printf("%s:std=%x\n",__FUNCTION__,std);
- TEST_V4L_FLAG(std,V4L2_STD_PAL_B);
- TEST_V4L_FLAG(std,V4L2_STD_PAL_B1);
- TEST_V4L_FLAG(std,V4L2_STD_PAL_G);
- TEST_V4L_FLAG(std,V4L2_STD_PAL_H);
- TEST_V4L_FLAG(std,V4L2_STD_PAL_I);
- TEST_V4L_FLAG(std,V4L2_STD_PAL_D);
- TEST_V4L_FLAG(std,V4L2_STD_PAL_D1);
- TEST_V4L_FLAG(std,V4L2_STD_PAL_M);
- TEST_V4L_FLAG(std,V4L2_STD_PAL_N);
- TEST_V4L_FLAG(std,V4L2_STD_PAL_Nc);
- TEST_V4L_FLAG(std,V4L2_STD_PAL_60);
- TEST_V4L_FLAG(std,V4L2_STD_NTSC_M);
- TEST_V4L_FLAG(std,V4L2_STD_NTSC_M_JP);
- TEST_V4L_FLAG(std,V4L2_STD_NTSC_443);
- TEST_V4L_FLAG(std,V4L2_STD_NTSC_M_KR);
- TEST_V4L_FLAG(std,V4L2_STD_SECAM_B);
- TEST_V4L_FLAG(std,V4L2_STD_SECAM_D);
- TEST_V4L_FLAG(std,V4L2_STD_SECAM_G);
- TEST_V4L_FLAG(std,V4L2_STD_SECAM_H);
- TEST_V4L_FLAG(std,V4L2_STD_SECAM_K);
- TEST_V4L_FLAG(std,V4L2_STD_SECAM_K1);
- TEST_V4L_FLAG(std,V4L2_STD_SECAM_L);
- TEST_V4L_FLAG(std,V4L2_STD_SECAM_LC);
- TEST_V4L_FLAG(std,V4L2_STD_ATSC_8_VSB);
- TEST_V4L_FLAG(std,V4L2_STD_ATSC_16_VSB);
- }
-
-
-
- int v4l2_enum_video_input(int fd)
- {
- struct v4l2_input input;
- int ret;
- memset(&input, 0, sizeof(input));//initialize i.index=0;
-
- PRINT_V4L("inputs\n");
-
- while(ret=ioctl(fd, VIDIOC_ENUMINPUT, &input)>=0)
- {
- PRINT_IOCTL_CMD2(VIDIOC_ENUMINPUT,input.index);
- PRINT_V4L_INT(input.index);
- PRINT_V4L_STRING(input.name);
-
- PRINT_V4L_MEMBER(input.type);
- TEST_V4L_FLAG0(input.type,V4L2_INPUT_TYPE_TUNER);
- TEST_V4L_FLAG0(input.type,V4L2_INPUT_TYPE_CAMERA);
- PRINT_V4L("\n");
-
- PRINT_V4L_INT(input.audioset);
- PRINT_V4L_INT(input.tuner);
-
-
-
- PRINT_V4L_FLAGS(input.std);
-
- show_video_std(input.std);
- PRINT_V4L_FLAGS2(input.std);
-
-
- //printf("input i.name:%s; i.index :%d i.type = %s\n",i.name, i.index, i.type);
- input.index++;
- }
-
- return ret;
- }
-
- static void _show_pixel_format(unsigned int pixelformat )
- {
- if(pixelformat == 0)
- {
- printf("unknow pixelformat %d\n",pixelformat);
- return ;
- }
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_RGB332);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_RGB444);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_RGB555);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_RGB565);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_RGB555X);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_RGB565X);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_BGR24);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_RGB24);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_BGR32);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_RGB32);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_GREY);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_Y16);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_PAL8);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_YVU410);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_YVU420);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_YUYV);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_UYVY);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_YUV422P);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_YUV411P);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_Y41P);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_YUV444);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_YUV555);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_YUV565);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_YUV32);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_NV12);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_NV21);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_YUV410);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_YUV420);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_YYUV);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_HI240);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_HM12);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_SBGGR8);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_SGBRG8);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_SGRBG10);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_SGRBG10DPCM8);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_SBGGR16);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_MJPEG);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_JPEG);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_DV);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_MPEG);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_WNVA);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_SN9C10X);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_PWC1);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_PWC2);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_ET61X251);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_SPCA501);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_SPCA505);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_SPCA508);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_SPCA561);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_PAC207);
- TEST_V4L_FLAG(pixelformat,V4L2_PIX_FMT_YVYU);
- }
-
- int v4l2_enum_video_format(int fd,enum v4l2_buf_type type,char * title)
- {
- struct v4l2_fmtdesc fmtdesc;
- int i=0;
- memset(&fmtdesc, 0, sizeof(fmtdesc));
-
-
-
- PRINT_V4L("%s\n",title);
-
- for(i=0;;i++)
- {
-
- fmtdesc.index = i;
- fmtdesc.type = type;
-
- if(-1== ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc))
- break;
-
-
-
- PRINT_IOCTL_CMD(VIDIOC_ENUM_FMT);
- PRINT_V4L_INT(fmtdesc.index);
-
- PRINT_V4L_FLAGS(fmtdesc.type);
- _show_capture_type(fmtdesc.type);
- PRINT_V4L_FLAGS2(fmtdesc.type);
-
- PRINT_V4L_INT(fmtdesc.flags);
- PRINT_V4L_STRING(fmtdesc.description);
-
-
- PRINT_V4L_FLAGS(fmtdesc.pixelformat);
- _show_pixel_format(fmtdesc.pixelformat);
- PRINT_V4L_FLAGS2(fmtdesc.pixelformat);
-
-
-
-
-
-
- }
- return i;
-
- }
-
- #define v4l2_enum_foramt(fd,type) v4l2_enum_video_format(fd,type,#type)
- #define v4l2_enum_video_capture(fd) v4l2_enum_foramt(fd,V4L2_BUF_TYPE_VIDEO_CAPTURE)
- #define v4l2_enum_video_overlay(fd) v4l2_enum_foramt(fd,V4L2_BUF_TYPE_VIDEO_OVERLAY)
- #define v4l2_enum_video_vbi_capture(fd) v4l2_enum_foramt(fd,V4L2_CAP_VBI_CAPTURE)
-
-
-
- void _show_v4l2_field(unsigned v4l2_filed)
- {
- PRINT_V4L_MEMBER(v4l2_filed);
- TEST_V4L_FLAG0(v4l2_filed,V4L2_FIELD_ANY);
- TEST_V4L_FLAG0(v4l2_filed,V4L2_FIELD_NONE);
- TEST_V4L_FLAG0(v4l2_filed,V4L2_FIELD_TOP);
- TEST_V4L_FLAG0(v4l2_filed,V4L2_FIELD_BOTTOM);
- TEST_V4L_FLAG0(v4l2_filed,V4L2_FIELD_INTERLACED);
- TEST_V4L_FLAG0(v4l2_filed,V4L2_FIELD_SEQ_TB);
- TEST_V4L_FLAG0(v4l2_filed,V4L2_FIELD_SEQ_BT);
- TEST_V4L_FLAG0(v4l2_filed,V4L2_FIELD_ALTERNATE);
- TEST_V4L_FLAG0(v4l2_filed,V4L2_FIELD_INTERLACED_TB);
- TEST_V4L_FLAG0(v4l2_filed,V4L2_FIELD_INTERLACED_BT);
- PRINT_V4L("\n");
- }
-
- int v4l2_get_capture_format(int fd)
- {
- struct v4l2_format format;
- memset(&format,0,sizeof(format));
- format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- if (-1 == ioctl(fd,VIDIOC_G_FMT,&format))
- {
- perror("VIDIOC_G_FMT(VIDEO_CAPTURE)");
- return -1;
- }
-
- PRINT_IOCTL_CMD(VIDIOC_G_FMT);
- PRINT_V4L_FLAGS(format.type);
- _show_capture_type(format.type);
- PRINT_V4L_FLAGS2(format.type);
-
-
-
- PRINT_V4L_INT(format.fmt.pix.width);
- PRINT_V4L_INT(format.fmt.pix.height);
- _show_pixel_format(format.fmt.pix.pixelformat);
-
- PRINT_V4L_INT(format.fmt.pix.bytesperline);
- PRINT_V4L_INT(format.fmt.pix.sizeimage);
-
-
-
- _show_v4l2_field(format.fmt.pix.field);
-
-
-
- return 0;
- }
-
- int main(int argc,char * argv[])
- {
- char dev_name[64] = "/dev/video0";
- int cam_fd =-1;
-
- if(argc>1)
- {
- strncpy(dev_name,argv[1],sizeof(dev_name)-1);
- }
-
- printf("open device %s\n",dev_name);
- cam_fd = open(dev_name,O_RDWR|O_NONBLOCK);
-
- if(cam_fd == -1)
- {
- printf("open failure \n");
- return -1;
- }
-
-
- printf("### v4l2 device info [%s] ###\n",dev_name);
-
-
- v4l2_query_video_cap(cam_fd);
- v4l2_enum_video_input(cam_fd);
-
- v4l2_enum_video_capture(cam_fd);
-
-
- v4l2_get_capture_format(cam_fd);
- close(cam_fd);
-
- return 0;
-
- }
4.测试样例:
- [root@FriendlyARM 3]# ./test_v4l2 /dev/video0
- open device /dev/video0
- ### v4l2 device info [/dev/video0] ###
- general info
- VIDIOC_QUERYCAP = (0x80685600)
- cap.driver :"Samsung FIMC Dris3c-fimc0"
- cap.card :"s3c-fimc0"
- cap.bus_info :"FIMC AHB-bus"
- cap.version :0.0.0
- cap.capabilities :0x4000005 [V4L2_CAP_VIDEO_CAPTURE,V4L2_CAP_VIDEO_OVERLAY,V4L2_CAP_STREAMING,]
- inputs
- VIDIOC_ENUMINPUT (0) = (0xc050561a)
- input.index :0
- input.name :"External Camera Input"
- input.type :V4L2_INPUT_TYPE_CAMERA
- input.audioset :1
- input.tuner :0
- input.std :0x1007 [V4L2_STD_PAL_B,V4L2_STD_PAL_B1,V4L2_STD_PAL_G,V4L2_STD_NTSC_M,]
- VIDIOC_ENUMINPUT (1) = (0xc050561a)
- input.index :1
- input.name :"Memory Input"
- input.type :V4L2_INPUT_TYPE_CAMERA
- input.audioset :2
- input.tuner :0
- input.std :0x1007 [V4L2_STD_PAL_B,V4L2_STD_PAL_B1,V4L2_STD_PAL_G,V4L2_STD_NTSC_M,]
- VIDIOC_G_FMT = (0xc0cc5604)
- format.type :0x1 [V4L2_BUF_TYPE_VIDEO_CAPTURE,]
- format.fmt.pix.width:0
- format.fmt.pix.height:0
- unknow pixelformat 0
- format.fmt.pix.bytesperline:0
- format.fmt.pix.sizeimage:0
- v4l2_filed :V4L2_FIELD_ANY
- [root@FriendlyARM 3]#
- ----------------------------------------------------------------------------------------------------------------
-
- [root@FriendlyARM 3]# ./test_v4l2 /dev/video1
- open device /dev/video1
- ### v4l2 device info [/dev/video1] ###
- general info
- VIDIOC_QUERYCAP = (0x80685600)
- cap.driver :"Samsung FIMC Dris3c-fimc1"
- cap.card :"s3c-fimc1"
- cap.bus_info :"FIMC AHB-bus"
- cap.version :0.0.0
- cap.capabilities :0x4000005 [V4L2_CAP_VIDEO_CAPTURE,V4L2_CAP_VIDEO_OVERLAY,V4L2_CAP_STREAMING,]
- inputs
- VIDIOC_ENUMINPUT (0) = (0xc050561a)
- input.index :0
- input.name :"External Camera Input"
- input.type :V4L2_INPUT_TYPE_CAMERA
- input.audioset :1
- input.tuner :0
- input.std :0x1007 [V4L2_STD_PAL_B,V4L2_STD_PAL_B1,V4L2_STD_PAL_G,V4L2_STD_NTSC_M,]
- VIDIOC_ENUMINPUT (1) = (0xc050561a)
- input.index :1
- input.name :"Memory Input"
- input.type :V4L2_INPUT_TYPE_CAMERA
- input.audioset :2
- input.tuner :0
- input.std :0x1007 [V4L2_STD_PAL_B,V4L2_STD_PAL_B1,V4L2_STD_PAL_G,V4L2_STD_NTSC_M,]
- VIDIOC_G_FMT = (0xc0cc5604)
- format.type :0x1 [V4L2_BUF_TYPE_VIDEO_CAPTURE,]
- format.fmt.pix.width:0
- format.fmt.pix.height:0
- unknow pixelformat 0
- format.fmt.pix.bytesperline:0
- format.fmt.pix.sizeimage:0
- v4l2_filed :V4L2_FIELD_ANY
- [root@FriendlyARM 3]#
-
-
- --------------------------------------------------------------------------------------------------------------------------
-
- [root@FriendlyARM 3]# ./test_v4l2 /dev/video2
- open device /dev/video2
- ### v4l2 device info [/dev/video2] ###
- general info
- VIDIOC_QUERYCAP = (0x80685600)
- cap.driver :"zc3xx"
- cap.card :"PC Camera"
- cap.bus_info :"s3c24xx"
- cap.version :2.3.0
- cap.capabilities :0x5000001 [V4L2_CAP_VIDEO_CAPTURE,V4L2_CAP_READWRITE,V4L2_CAP_STREAMING,]
- inputs
- VIDIOC_ENUMINPUT (0) = (0xc050561a)
- input.index :0
- input.name :"zc3xx"
- input.type :V4L2_INPUT_TYPE_CAMERA
- input.audioset :0
- input.tuner :0
- input.std :0x0 []
- VIDIOC_G_FMT = (0xc0cc5604)
- format.type :0x1 [V4L2_BUF_TYPE_VIDEO_CAPTURE,]
- format.fmt.pix.width:640
- format.fmt.pix.height:480
- V4L2_PIX_FMT_JPEG, format.fmt.pix.bytesperline:640
- format.fmt.pix.sizeimage:115790
- v4l2_filed :V4L2_FIELD_ANYV4L2_FIELD_NONE
- [root@FriendlyARM 3]#