[特别推荐]视频编程.doc_第1页
[特别推荐]视频编程.doc_第2页
[特别推荐]视频编程.doc_第3页
[特别推荐]视频编程.doc_第4页
[特别推荐]视频编程.doc_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

海龙新科技有限公司/ 电子围栏 Linux下视频编程 收藏 关于Linux的视频编程(v4l2编程) Posted on 星期一, 2月 23rd, 2009 at 11:47 下午 前言:目前正在忙于ARM 平台的Linux 应用程序的开发(其实是刚刚起步学习啦)。底层的东西不用考虑了,开发板子提供了NAND Bootloader ,和Linux 2.6 的源码,而且都编译好了。自己编译的bootloader 可以用,但是Linux 编译后,文件很大,暂且就用人家编译的系统,先专心写应用程序 吧。 正文:要做的任务是,把一块板子上的摄像头采集的图像和声卡采集的声音(貌似很啰嗦哈)通过TCP/IP 协议传输到另一块板子上。第一步,先把视频获取并且在本地LCD 上显示。看了板子提供的文档,视频传输需要用V4L2 的API 。 一. 什么是video4linuxVideo4linux2 (简称V4L2), 是linux 中关于视频设备的内核驱动。在Linux 中,视频设备是设备文件,可以像访问普通文件一样对其进行读写,摄像头在/dev/video0 下。 二、一般操作流程(视频设备):1. 打开设备文件。 int fd=open(”/dev/video0,O_RDWR);2. 取得设备的capability ,看看设备具有什么功能,比如是否具有视频输入, 或者音频输入输出等。VIDIOC_QUERYCAP,struct v4l2_capability3. 选择视频输入,一个视频设备可以有多个视频输入。VIDIOC_S_INPUT,struct v4l2_input4. 设置视频的制式和帧格式,制式包括PAL ,NTSC ,帧的格式个包括宽度和高度等。VIDIOC_S_STD,VIDIOC_S_FMT,struct v4l2_std_id,struct v4l2_format5. 向驱动申请帧缓冲,一般不超过5 个。struct v4l2_requestbuffers6. 将申请到的帧缓冲映射到用户空间,这样就可以直接操作采集到的帧了,而不必去复制。mmap7. 将申请到的帧缓冲全部入队列,以便存放采集到的数据.VIDIOC_QBUF,struct v4l2_buffer8. 开始视频的采集。VIDIOC_STREAMON9. 出队列以取得已采集数据的帧缓冲,取得原始采集数据。VIDIOC_DQBUF10. 将缓冲重新入队列尾, 这样可以循环采集。VIDIOC_QBUF11. 停止视频的采集。VIDIOC_STREAMOFF12. 关闭视频设备。close(fd);三、常用的结构体( 参见/usr/include/linux/videodev2.h) : struct v4l2_requestbuffers reqbufs;/ 向驱动申请帧缓冲的请求,里面包含申请的个数struct v4l2_capability cap;/ 这个设备的功能,比如是否是视频输入设备struct v4l2_input input; / 视频输入struct v4l2_standard std;/ 视频的制式,比如PAL ,NTSCstruct v4l2_format fmt;/ 帧的格式,比如宽度,高度等 struct v4l2_buffer buf;/ 代表驱动中的一帧v4l2_std_id stdid;/ 视频制式,例如:V4L2_STD_PAL_Bstruct v4l2_queryctrl query;/ 查询的控制struct v4l2_control control;/ 具体控制的值 下面具体说明开发流程(网上找的啦,也在学习么) 打开视频设备 在V4L2 中,视频设备被看做一个文件。使用open 函数打开这个设备: / 用非阻塞模式打开摄像头设备 int cameraFd ; cameraFd = open (“/dev/video0 , O_RDWR | O_NONBLOCK , 0); / 如果用阻塞模式打开摄像头设备,上述代码变为: /cameraFd = open(”/dev/video0, O_RDWR, 0); 关于阻塞模式和非阻塞模式 应用程序能够使用阻塞模式或非阻塞模式打开视频设备,如果使用非阻塞模式调用视频设备,即使尚未捕获到信息,驱动依旧会把缓存(DQBUFF )里的东西返回给应用程序。 设定属性及采集方式 打开视频设备后,可以设置该视频设备的属性,例如裁剪、缩放等。这一步是可选的。在Linux 编程中,一般使用ioctl 函数来对设备的I/O 通道进行管理: extern int ioctl (int _fd , unsigned long int _request , ) _THROW ; _fd :设备的ID ,例如刚才用open 函数打开视频通道后返回的cameraFd ; _request :具体的命令标志符。 在进行V4L2 开发中,一般会用到以下的命令标志符: 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 。 这些IO 调用,有些是必须的,有些是可选择的。 检查当前视频设备支持的标准 在亚洲,一般使用PAL (720X576 )制式的摄像头,而欧洲一般使用NTSC (720X480 ),使用VIDIOC_QUERYSTD 来检测: v4l2_std_id std ; do ret = ioctl (fd , VIDIOC_QUERYSTD , &std ); while (ret = -1 & errno = EAGAIN ); switch (std ) case V4L2_STD_NTSC : / case V4L2_STD_PAL : / 设置视频捕获格式 当检测完视频设备支持的标准后,还需要设定视频捕获格式: struct v4l2_format fmt ; memset ( &fmt , 0, sizeof (fmt ) ); fmt .type = V4L2_BUF_TYPE_VIDEO_CAPTURE ; fmt .fmt .pix .width = 720 ; fmt .fmt .pix .height = 576 ; fmt .fmt .pix .pixelformat = V4L2_PIX_FMT_YUYV ; fmt .fmt .pix .field = V4L2_FIELD_INTERLACED ; if (ioctl (fd , VIDIOC_S_FMT , &fmt ) = -1) return -1; v4l2_format 结构体定义如下: struct v4l2_format enum v4l2_buf_type type ; / 数据流类型,必须永远是/V4L2_BUF_TYPE_VIDEO_CAPTURE union struct v4l2_pix_format pix ; struct v4l2_window win ; struct v4l2_vbi_format vbi ; _u8 raw_data 200; fmt ; ; struct v4l2_pix_format _u32 width ; / 宽,必须是16 的倍数 _u32 height ; / 高,必须是16 的倍数 _u32 pixelformat ; / 视频数据存储类型,例如是/YUV4 :2 :2 还是RGB enum v4l2_field field ; _u32 bytesperline ; _u32 sizeimage ; enum v4l2_colorspace colorspace ; _u32 priv ; ; 分配内存 接下来可以为视频捕获分配内存: struct v4l2_requestbuffers req ; if (ioctl (fd , VIDIOC_REQBUFS , &req ) = -1) return -1; v4l2_requestbuffers 定义如下: struct v4l2_requestbuffers _u32 count ; / 缓存数量,也就是说在缓存队列里保持多少张照片 enum v4l2_buf_type type ; / 数据流类型,必须永远是V4L2_BUF_TYPE_VIDEO_CAPTURE enum v4l2_memory memory ; / V4L2_MEMORY_MMAP 或 V4L2_MEMORY_USERPTR _u32 reserved 2; ; 获取并记录缓存的物理空间 使用VIDIOC_REQBUFS ,我们获取了req.count 个缓存,下一步通过调用VIDIOC_QUERYBUF 命令来获取这些缓存的地址,然后使用mmap 函数转换成应用程序中的绝对地址,最后把这段缓存放入缓存队列: typedef struct VideoBuffer void *start ; size_t length ; VideoBuffer ; VideoBuffer * buffers = calloc ( req .count , sizeof (*buffers ) ); struct v4l2_buffer buf ; for (numBufs = 0; numBufs req .count ; numBufs +) memset ( &buf , 0, sizeof (buf ) ); buf .type = V4L2_BUF_TYPE_VIDEO_CAPTURE ; buf .memory = V4L2_MEMORY_MMAP ; buf .index = numBufs ; / 读取缓存 if (ioctl (fd , VIDIOC_QUERYBUF , &buf ) = -1) return -1; buffers numBufs .length = buf .length ; / 转换成相对地址 buffers numBufs .start = mmap (NULL , buf .length , PROT_READ | PROT_WRITE , MAP_SHARED , fd , buf .m .offset ); if (buffers numBufs .start = MAP_FAILED ) return -1; / 放入缓存队列 if (ioctl (fd , VIDIOC_QBUF , &buf ) = -1) return -1; 关于视频采集方式 操作系统一般把系统使用的内存划分成用户空间和内核空间,分别由应用程序管理和操作系统管理。应用程序可以直接访问内存的地址,而内核空间存放的是 供内核访问的代码和数据,用户不能直接访问。v4l2 捕获的数据,最初是存放在内核空间的,这意味着用户不能直接访问该段内存,必须通过某些手段来转换地 址。 一共有三种视频采集方式:使用read 、write 方式;内存映射方式和用户指针模式。 read 、write 方式 : 在用户空间和内核空间不断拷贝数据,占用了大量用户内存空间,效率不高。 内存映射方式: 把设备里的内存映射到应用程序中的内存控件,直接处理设备内存,这是一种有效的方式。上面的mmap 函数就是使用这种方式。 用户指针模式 :内存片段由应用程序自己分配。这点需要在v4l2_requestbuffers 里将memory 字段设置成V4L2_MEMORY_USERPTR 。 处理采集数据 V4L2 有一个数据缓存,存放req.count 数量的缓存数据。数据缓存采用FIFO 的方式,当应用程序调用缓存数据时,缓存队列将最先采集到的 视频数据缓存送出,并重新采集一张视频数据。这个过程需要用到两个ioctl 命令,VIDIOC_DQBUF 和VIDIOC_QBUF : struct v4l2_buffer buf ; memset (&buf ,0,sizeof (buf ); buf .type =V4L2_BUF_TYPE_VIDEO_CAPTURE ; buf .memory =V4L2_MEMORY_MMAP ; buf .index =0; / 读取缓存 if (ioctl (cameraFd , VIDIOC_DQBUF , &buf ) = -1) return -1; / 视频处理算法 / 重新放入缓存队列 if (ioctl (cameraFd , VIDIOC_QBUF , &buf ) = -1) return -1; 关闭视频设备 V4L2视频采集设备应用程序编程总结(转) 收藏 V4L2视频采集设备应用程序编程总结(转)Linux2.x内核中,一部分视频设备(特别是视频输入和采集设备)采用了V4L2模型进行驱动编程。同时提供V4L2的API函数及相关数据结构以供应用程序使用.这里对V4L2视频采集设备的应用程序编程进行总结.1. 使用的头文件: V4L2模型使用统一的头文件来包含相关的数据结构和宏,它存在于”Linux源码目录/include/linux/videodev.h”以及”Linux源码目录/include/linux/videodev2.h”.通常一个视频设备的驱动程序头文件会包含它.因此,编程时只需要包含视频驱动对应的头文件就可以了.在这里是“/media/davinci_vpfe.h”.2. 由于在应用程序编程中涉及到V4L2数据结构。而该文件包含于Linux源码中,因此在makefile文件中要包含源码头文件的路径“-I XXX/include”.3. 编程流程如下: 动作 函数 变量及参数 备注 1 打开视频设备(阻塞或非阻塞) Open 设备对应路径和名称 一般为“/dev/videoX”X=0,1,2 2 询问设备的能力和性质 Ioctl 对于输入设备,必然要支持内存映射或用户指针 3 验证视频标准的有效性,并设置设备视频标准 Ioctl 验证标准为设备支持的标准并进行设置后要稍微延时并查询,检查设备是否已设置为相应的标准 4 设置采集设备采集格式 Ioctl 通过配置该结构体,驱动会根据硬件调整像素实际宽,高,每行的字节个数,一幅图像字节数四个参数。程序应根据实际情况修改返回的结果,重新赋值。 5 请求缓冲区,并通过mmap函数映射到用户进程内存空间 Ioctl 1.申请缓冲可能不成功。因此通过v4l2_requestbuffers.count返回值判断是否申请到足够的缓存.一般设置23个buffers.在DaVinci的vpfe驱动中默认就设置了3个buffers.多余3个申请失败,少于三个依然使用三个.2.映射内存出现失败的情况后一定要将已经映射的区域取消映射后再关闭设备 6 将申请到的buffers加入到缓冲队列当中,开始采集 Ioctl 进行采集时先通过VIDIOC_DQBUF将一个buffer从队列中取出来,然后得到它对应映射后的起始地址。进行必要的处理。完毕后一定要将该buffer重新放入队列中,否则程序到最后将无buffer可用。PS:由于无论是数字视频还是模拟视频,都会有一个i2c配置的过程。从vpfe的驱动代码来看,当设置视频标准时,驱动程序将会调用i2c驱动配置视频源的输出格式。(对于模拟信号通常是TVP5150之类的解码芯片,通过I2C配置,而对于MT9T001之类的芯片则通过I2C直接对其进行配置.)本文来自CSDN博客,转载请标明出处:/zjbo_123/archive/2010/01/06/5139685.aspx嵌入式视频采集编程思路(Video 4 Linux)2010-01-29 16:32:33标签:4 Video 嵌入式 Linux 视频原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。/1043164/271954嵌入式视频采集编程思路(Video 4 Linux)【1】linux 内核有video for linux简称V4L。V4L是Linux影像系统与嵌入式影像的基础,是Linux kernel里支持影像设备的一组APIs,配合适当的视频采集卡与视频采集卡驱动程序,V4L可以实现影像采集、AM/FM无线广播、影像CODEC、频道切换等功能。目前,V4L主要应用在影像串流系统与嵌入式影像系统里,其应用范围相当广泛,例如:远程教学、远程医疗、视频会议、视频监控、可视电话等。V4L为2层式架构,最上层为V4L驱动程序,最下层则是影像设备驱动程序。【2】接上USB摄像头,硬件设备在linux下都是作为文件访问,所以只需在/dev/下查找,一般情况下为video0。当摄像机通过USB接口连接到视频采集终端后,在程序中调用V4L APIs对设备文件video0的读操作即可实现摄像头视频数据采集。其主要过程如下:1) 打开设备文件: int v4l_open(char *dev, v4l_device *vd)打开影像源的设备文件;2) 初始化picture: int v4l_get_picture(v4l_device *vd) 获取输入的影像信息;3) 初始化channel:int v4l_get_channels(v4l_devi

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论