免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 900 | 回复: 0
打印 上一主题 下一主题

V4L的使用[转] [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-12-26 18:45 |只看该作者 |倒序浏览
原文地址http://blog.ednchina.com/yuliang0321/24516/category.aspx
/* Video4Linux是Linux下用于获取视频和音频数据的API接口,在这篇文章中,着重阐述如何利用Video4Linux获取摄像头数据,以实现连续影像的播放。 */
/*   1. 摄像头的安装 */
/*
  在Linux下常用的摄像头驱动是spca5xx, 这是一个通用驱动,读者可以在以下网站下到这个驱动
http://mxhaard.free.fr/download.html。这个网站还给出了这款驱动支持的摄像头的种类。另外,ov511芯片直接就
支持Linux,使用者款芯片的摄像头有网眼V2000。我使用的是网眼V2000的摄像头,和Z-Star
301p+现代7131R芯片的摄像头。后一种需要spca5xx的驱动。关于spca5xx的安装方法,网上有很多介绍,这里就不说了。 */
/*   2. 摄像头的调试 */
/*   安装好摄像头后,为了测试摄像头能否正常工作,可以用一下软件。比较著名的是xawtv,在网上搜以下可以下载到。安装好后,打开xawtv则可以调试摄像头。 */
/*   3. Video4Linux 编程获取数据 */
/*   现有的video4linux有两个版本,v4l和v4l2。本文主要是关于v4l的编程。利用v4l API获取视频图像一般有以下几步: */
/*   a> 打开设备 */
/*   b> 设置设备的属性,比如图像的亮度,对比度等等 */
/*   c> 设定传输格式和传输方式 */
/*   d> 开始传输数据,一般是一个循环,用以连续的传输数据 */
/*   e> 关闭设备 */
/*   下面具体介绍v4l编程的过程。首先指出,在video4linux编程时要包含头文件,其中包含了video4linux的数据结构和函数定义。 */
/*   1)v4l的数据结构 */
/*   在video4linux API中定义了如下数据结构,详细的数据结构定义可以参考v4l API的文档,这里就编程中经常使用的数据结构作出说明。 */
/*   首先我们定义一个描述设备的数据结构,它包含了v4l中定义的所有数据结构: */
typedef struct _v4ldevice
{
     int fd;//设备号
     struct video_capability capability;
     struct video_channel channel[10];
     struct video_picture picture;
     struct video_clip clip;
     struct video_window window;
     struct video_capture capture;
     struct video_buffer buffer;
     struct video_mmap mmap;
     struct video_mbuf mbuf;
     struct video_unit unit;
     unsigned char *map;//mmap方式获取数据时,数据的首地址
     pthread_mutex_t mutex;
     int frame;
     int framestat[2];
     int overlay;
}v4ldevice;
/*   下面解释上面这个数据结构中包含的数据结构,这些结构的定义都在中。 */
/* * struct video_capability */
/* name[32] Canonical name for this interface */
/* type Type of interface */
/* channels Number of radio/tv channels if appropriate */
/* audios Number of audio devices if appropriate */
/* maxwidth Maximum capture width in pixels */
/* maxheight Maximum capture height in pixels */
/* minwidth Minimum capture width in pixels */
/* minheight Minimum capture height in pixels */
/*   这一个数据结构是包含了摄像头的属性,name是摄像头的名字,maxwidth maxheight是摄像头所能获取的最大图像大小,用像素作单位。 */
/*   在程序中,通过ioctl函数的VIDIOCGCAP控制命令读写设备通道已获取这个结构,有关ioctl的使用,比较复杂,这里就不说了。下面列出获取这一数据结构的代码: */
int v4lgetcapability(v4ldevice *vd)
{
     if(ioctl(vd->fd, VIDIOCGCAP, &(vd->capability)) fd, VIDIOCGMBUF, &(vd->mbuf))map + vd->mbuf.offsets[vd->frame]);
}
/*   2)获取影像mmap方式。 */
/*   在video4linux下获取影像有两种方式:overlay和mmap。由于我的摄像头不支持overlay方式,所以这里只谈mmap方式。 */
/*
  mmap方式是通过内存映射的方式获取数据,系统调用ioctl的VIDIOCMCAPTURE后,将图像映射到内存中,然后可以通过前面的
v4lgetmbuf(vd)函数和v4lgetaddress(vd)函数获得数据的首地址,这是你可以选择是将它显示出来还是放到别的什么地方。
*/
/*   下面给出获取连续影像的最简单的方法(为了简化,将一些可去掉的属性操作都去掉了): */
char* devicename="/dev/video0";
char* buffer;
v4ldevice device;
int width = 640;
int height = 480;
int frame = 0;
v4lopen("/dev/video0",&device);//打开设备
v4lgrabinit(&device,width,height);//初始化设备,定义获取的影像的大小
v4lmmap(&device);//内存映射
v4lgrabstart(&device,frame);//开始获取影像
while(1){
     v4lsync(&device,frame);//等待传完一帧
     frame = (frame+1)%2;//下一帧的frame
     v4lcapture(&device,frame);//获取下一帧
     buffer = (char*)v4lgetaddress(&device);//得到这一帧的地址
//buffer给出了图像的首地址,你可以选择将图像显示或保存......
//图像的大小为 width*height*3
     ..........................
          }
/*   为了更好的理解源码,这里给出里面的函数的实现,这里为了简化,将所有的出错处理都去掉了。 */
int v4lopen(char *name, v4ldevice *vd)
{
     int i;
     if((vd->fd = open(name,O_RDWR)) mmap.width = width;
     vd->mmap.height = height;
     vd->mmap.format = vd->picture.palette;
     vd->frame = 0;
     vd->framestat[0] = 0;
     vd->framestat[1] = 0;
     return 0;
}
int v4lmmap(v4ldevice *vd)
{
     if(v4lgetmbuf(vd)map = mmap(0, vd->mbuf.size, PROT_READ|PROT_WRITE, MAP_SHARED, vd->fd, 0)) mmap.frame = frame;
     if(ioctl(vd->fd, VIDIOCMCAPTURE, &(vd->mmap)) framestat[frame] = 1;
     return 0;
}
int v4lsync(v4ldevice *vd, int frame)
{
     if(ioctl(vd->fd, VIDIOCSYNC, &frame) framestat[frame] = 0;
     return 0;
}
int v4lcapture(v4ldevice *vd, int frame)
{
     vd->mmap.frame = frame;
     if(ioctl(vd->fd, VIDIOCMCAPTURE, &(vd->mmap)) framestat[frame] = 1;
     return 0;
}
                    


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/16231/showart_1745072.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP