基于ARMLINUX 视频采集系统项目<B>总结报告<╲╱B>_第1页
基于ARMLINUX 视频采集系统项目<B>总结报告<╲╱B>_第2页
基于ARMLINUX 视频采集系统项目<B>总结报告<╲╱B>_第3页
基于ARMLINUX 视频采集系统项目<B>总结报告<╲╱B>_第4页
基于ARMLINUX 视频采集系统项目<B>总结报告<╲╱B>_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

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

文档简介

1、 基于ARMLinux 视频采集系统 项 目 总 结 报 告 目录1 项目的基本情况及市场需求.32 项目的实现 .3 2.1 硬件的体系结构 .3 2.2 嵌入式系统软件平台 .4 2.3 图像采集和显示设计 .103 项目测试 .22 3.1 测试环境 .22 3.2 测试范围 .22 3.3 测试内容 .22 3.4 测试用例 .234 实验结果 .235 项目总结 .23一、项目的基本情况及市场需求 视频采集系统是当前应用十分广泛的一种视频采集设备,随着信息技术的迅速发展,计算机产业的发展已经到了所谓的后PC 时代。在传统的视频采集中,系统一般由CCD 摄像头,采集卡组成,功能齐全,但

2、价格高,体积大。嵌入式系统在各行业的应用,特别是工业现场、信息家电、机顶盒等方面的广泛使用,使嵌入式系统的研究开发成为计算机领域的一个热点。嵌入式图像采集则弥补了上述的缺点,并且可以复杂环境下的图像采集嵌入式Linux 操作系统是从Linux 衍生出来的一种操作系统,它支持众多嵌入式处理器,并具有Unix 的很多优点,而成为当前主流的嵌入式操作系统。本项目选择三星系的嵌入式处理器S3C2440,高速清晰摄像头和LCD 组成,软件则用嵌入式Linux 为操作系统,在嵌入式开发板上先进行Linux 的移植后完成,其次对摄像头在ARM 下的驱动进行修改和更新使其适应所采用的ARM 开发板,再者完成驱

3、动的加载和交叉编译应用程序来完成对图像的采集,最后从滤波算法和优化所采集的图片,使图片完成各种场合实验的要求。本系统体积小,占用内存低,模块化的系统通过协调的工作,形成了一套完整的图像采集系统,本系统所用的ARM9 系列的实验箱完全是从底层开发开始,成本低,加上Linux 并不是商业的软件,使得嵌入式视频采集系统有很好的扩展空间和广泛的前景。二 项目的实现2.1硬件的体系结构 本系统从硬件方面来看具体实现框图如2.1 所示。该系统平台采用SAMSUNG公司的处理器S3C2410。 图2.1 该处理器是内部集成ARM 公司的ARM920T 处理器核32 位微控制器,资源丰富,带独立的16KB 指

4、令Cache 和16KB 数据Cache,LCD 控制器,RAM 控制器,NAND 闪存控制器,3 路UART,4 路DMA,4 路带PWM的Timer,并行I/O 口,8 路10 位ADC,TouchScreen 接口,112C 接口,IIS 接口,2 个USB 接口控制器,2 路SPI,主频最高可达203MHz。 在处理器丰富资源的基础上进行了相关的配置和扩展,平台配置了一片32Mxl6 位的FLASH 和两16Mxl6 位的SDRAM,通过以太网控制器芯片DM9000 扩展了一个网口,另外引出一个串行接口和一个HOSTUSB 接口。通过在USB 接口上外接一个带USB 口的网络摄像头,将

5、采集到的视频图像数据放入存储器缓冲区中,接着或者保存成文件的形式,并且利用avilib 库来实现对已经压缩的peg 格式的图片进行avi 格式的组织来保存在U 盘里。2.2 嵌入式系统软件平台2.2.1交叉编译环境 通常嵌入式系统的软件编译和执行是在两个不同平台上进行的。编译是在宿主机,一般为桌面主机;执行是在目标机,即嵌入式系统的硬件平台。一般是在宿主机上通过跨平台交叉编译器把源文件编译成目标平台上可执行的文件,再通过串口、并口或者网络下载至目标平台上的FLASH 或者其它存储介质,然后由目标机来运行这些软件。这里所说的跨平台编译器和一般的编译器功能类似,都是把源代码通过编译器编译成目标文件

6、,然后通过链接器、可重定位器程序和定位器把目标文件重新定位成可执行文件。和通用的编译器之间最大的差别就在于跨平台编译器编译出来的可执行程序通常只能在特定CPU 所属平台上运行。所以一般来说每种CPU 都对应有不同的跨平台编译器。本系统采用基于ARM 920T 的是S3C2410X,可以使用常用的ARM 交叉编译器。要成功构建完整的交叉编译环境,需要在宿主机上创建一系列的工具,包括C/C+编译器、汇编器、链接器、嵌入式系统的标准C 库和GDB 代码级调试器。成功建立好开发环境后便可以运用这些工具进行嵌入式系统开发了。交叉编译环境的安装步骤,如图3.1 所示: 2.2.2 嵌入式Linux 系统移

7、植 在一个嵌入式Linux 系统中,从软件的角度般一般可以粗略的分为引导加载程序、Linux 内核、文件系统和用户应用程序等3 个层次,如图3.2(1)第一部分是引导加载程序,它包括固化在固件内的boot 代码和Bootloader 代码两个部分。许多CPU 在运行Bootloader 之前会先运行一段被称之为固件的程序,例如x86 结构的CPU 就是先运行BIOS 中的固件,然后再运行硬盘主引导记录MBR(Master Boot Record)d?的Bootloader。在系统中本没有固件程序,Bootloader 是上电后执行的第一个程序。(2)第二部分是Linux 内核。这一般是为特定于

8、某种体系结构的嵌入式板子定制的内核和内核的启动参数。一般而言,内核的启动参数是内核默认的,或是由Bootloader 传递给它的。(3)第三部分文件系统。里面包含了Linux 系统能够运行所必需的应用程序、库等,例如给用户提供操作控制界面的shell 程序,动态连接程序运行时所需要的glibe 或uClibc 库等,本设计中我们使用的文件系统是yaffs 文件系统。a)BootLoader BootLoader 是系统加电后运行的第一段代码。一般只是在启动时运行很短的时间,然而对一个嵌入式系统来说,这一部分却是整个系统的一个无比重要的组成部分,不可缺少。在一般嵌入式系统中,系统复位或者加电后通

9、常从地址ox00000000 处开始执行,而这个地址一般正是存放的BootLoader 启动代码。通过这段程序,可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终加载操作系统内核准备好正确的环境。一般BootLoader 都包含两种不同的操作模式:“启动加载”模式和“下载”模式,这种区别仅对于开发人员才有意义。从最终用户的角度看,BootLoader 的作用就是用来加载操作系统,而并不存在所谓的启动加载模式与下载模式的区别。 (1)启动加载(Boot loading)模式:这种模式也称为“自主”(Autonomous)模式,即BootLoader 从

10、目标机上的某个固态存储设备上将操作系统加载到RAM 中运行,整个过程并没有用户的介入。这种模式是BootLoader 的正常工作模式,因此在嵌入式产品发布的时候,BootLoader 显然必须工作在这种模式下。 (2)下载(Downloading)模式:在这种模式下,目标机上的BootLoader 将通过串口连接或者网络连接等通信手段从主机(HOST)下载文件,比如下载内核映像和根文件系统映像等。从主机下载的文件通常首先被BootLoader 保存到目标机的AM 中,然后再被BootLoader 写到目标机上的FLASH 类固态存储设备中。BootLoader 的这种模式通常在第一次安装内核与

11、根文件系统时被使用,此外,以后的系统更新也会使用BootLoader 的这种工作模式。工作于这种模式下的BootLoader 通常都会向它的终端用户提供一个简单的命令行接口。BootLoader 的实现依赖于CPU 的体系结构,一般来说启动过程分为两个阶段。第一阶段依赖于CPU 体系结构的代码,比如设备初始化代码等,通常都放在第一阶段中,而且通常都用汇编语言来实现,运行效率比较高。这个阶段完成的任务一般如下: (1)硬件设备初始化(屏蔽所有的中断、关闭处理器内部的指令数据cache); (2)为第二阶段准备RAM 空间; (3)复制BootLoader 的第二阶段代码到RAM 空间中; (4)

12、设置好堆栈并跳转到第二阶段的C 程序入口点。而第二阶段则通常用C 语言来实现,这样可以实现复杂的功能,而且代码会具有更好的可读性和可移植性。这个阶段主要任务有: (1)初始化本阶段要使用的硬件设备; (2)检测系统内存映射; (3)将内核映像和根文件系统从FLASH 读到RAM 中; (4)为内核设置启动参数; (5)调用内核文件运行。b) Linux 内核移植 本系统选用嵌入式Linux 作为目标机操作系统,一方面由于Linux 是一款免费的操作系统,能很好的降低成本,同时Linux 的开发应用现在已经成为热门,有大量的资源可用于学习与重复应用,并且Linux 系统具有良好的可移植性和可裁剪

13、性,能自动支持多任务管理。一般常用的GUI 如QT/E,MiniGUI 等都支持Linux。Linux 的开发工具也都可以很方便的免费获得。在Linux 系统内核代码中有arch 目录,其中包括了不同平台的代码,与体系结构相关的代码都存放在arch 下面相应的目录中,本系统采用ARM 开发平台,所以依赖ARM 硬件平台的代码都在archarm 下面。根目录下面只需要修改Makefile文件,该文件主要任务是产生vmlinux 文件和内核模块。对该文件的修改主要是设置目标平台和制定交叉编译器,代码如下:ARCH=armCROSS_COMPILE=arm-linux-接下来的工作便是修改arm 目

14、录下面的相应文件,具体的工作主要就是在内核文件中添加S3C2410 处理器信息,在arm 目录下面的Makefile 文件添加:ifeq($(CONFIG_ARCH_S3C2410),y)TEXTADDR=0Xc0008000MACHINE=s3c241 0Endif配置文件config.in 也需要添加处理器信息,这样在后面makemenuconifig 命令时可以看到S3C2410 的选项。具体为添加代码:If“$CONFIG_ARCH_S3C241 0”=”y”;thencommentS3C2410 Implementationdep_boolSMDK(MERI TECH BOARD)C

15、ONFIG_S3C24 10_SMDK/CONFIG_ARCH_S3C241 0fi编译出来的内核存放在arm 目录下的boot 目录里面,该目录下面的Makefile 文件也需要添加代码:ifeq($(CONFIG_ARCH_S3C241 O),y)ZTEXTADDR=Ox30008000ZRELADDR=Ox30008000endif其它还有一些小的修改,基本上都是添加处理器的信息。更改完成之后需要对内核进行配置和编译。配置命令可以选用make config,make oldconfig,make menuconfig 或makexconfig 其中一个。编译内核需要创建内核依赖关系、创建

16、内核镜像文件和创建内核模块。首先执行make dep 命令,读取配置过程生成的配置文件,来创建对应于配置的依赖关系树,从而决定哪些需要编译而哪些不需要;接着需要make clean 删除前面步骤留下的文件,以避免出现一些错误;然后便可以生成所需要的内核文件了,用makezlmage 来实现得到可移植的内核。内核文件传至开发板便可以通过BootLoader 加载运行。C) 嵌入式文件系统 理论上嵌入式系统也可以使用硬盘和光盘,但是这与嵌入式系统的便携性相违背,所以一般采用FLASH 作为存储介质。FLASH 具有独特的物理特性,所以必须使用专门的嵌入式文件系统。嵌入式系统对文件的操作是通过层次结

17、构实现的。对于用户程序来说,文件是有结构的文件,用户程序通过对文件IO函数操作文件。嵌入式文件系统是嵌入式操作系统的一部分,它的任务是对逻辑文件进行管理,其工作包括提供对逻辑文件的操作(复制、删除、修改等)接口,方便用户操作文件和目录。在文件系统内部,根据存储设备的特点,使用不同的文件组织模式来实现文件的逻辑结构。此外,文件系统要对管理文件的安全性负责。文件系统不能直接控制物理设备,它是通过FLASH 驱动实现控制的。目前FLASH 支持的文件系统技术主要有JFFS2,YAFFS2,TrueFFS,FTLNTFL,RAMFS,CRAMFS 和ROMFS 等等。本系统采用的是CRAMFS 文件系

18、统和YAFFS文件系统并存,并采用RAMDISK 在内存中模拟硬盘分区。CRAMFS 是针对Linux 内核24 之后的版本所设计的一种新型文件系统,是一个只读压缩的文件系统,其主要优点是将文件数据以压缩形式存储,在需要时进行解压缩。一般嵌入式存储器价格比较高,用CRAMFS 文件系统比较省空间,对于FLASH 这样的小系统,CRAMFS 是十分不错的选择。不过也J 下是由于文件形式是压缩的格式,所以文件系统不能在FLASH 上直接运行。虽然可以节约不少FLASH 空间,但是文件系统运行时需要将大量的数据复制到RAM 中,因此消耗了RAM 空间。YAFFS 类似于JFFSJFFS2,是专门为N

19、AND 闪存设计的嵌入式文件系统,根据NAND 闪存以页面为单位存取的特点,将文件组织成固定大小的数据段。利用NAND 闪存提供的每个页面16 字节的备用空间来存放ECC(ErrorCorrection Code)和文件系统的组织信息,不仅能够实现错误检测和坏块处理,也能够提高文件系统的加载速度。YAFFS 采用一种多策略混合的垃圾回收算法,结合了贪心策略的高效性和随机选择的平均性,达到了兼顾损耗平均和系统开销的目的。它是日志结构的文件系统,提供了损耗平衡和掉电保护,可以有效地避免意外掉电对文件系统一致性和完整性的影响。YAFFS 文件系统是按层次结构设计的,分为文件系统管理层接口、YAFFS

20、 内部实现层和NAND 接口层,这样就简化了其与系统的接口设计,可以方便地集成到系统中去。与JFFS 相比,它减少了一些功能,因此速度更快,占用内存更少。综合考虑,本系统采用两种文件系统相结合的方法,使用CRAMFS 作为根文件系统,并添加对YAFFS 文件系统的支持。RAMDISK 相当于一块硬盘空间,可以理解为在内存中虚拟出来一块硬盘,所以上面有系统支持的各种文件系统。RAMDISK 的特点之一就是速度快,因为它是在RAM 中运行的。不过由于RAM 是掉电不保存的,所以系统在每次重启时,前面的工作无法保存,所以需要在FLASH 中划出一个RAMDISK 和另一个文件系统YAFFS,这样,数

21、据文件可以保存在YAFFS 分区中。另外,本系统需要MTD(MemoryTechnology Devices,内存技术设备)的支持。MTD 是对FLASH 操作的接口,提供了一系列的标准接口函数,将硬件驱动和系统程序设计分开,硬件驱动人员不用了解存储设备的组织方法,只需要提供标准的函数调用,比如读、写等等。2.3 图像采集和显示设计2.3.1 摄像头驱动程序的移植和加载 Linux 本身自带了采用ov511 芯片的摄像头,而市场上应用最广泛的是采用中芯微公司生产的zc301 芯片的摄像头,下面我将针对这两大系列的摄像头分别做介绍。1、OV511 驱动的加载 1静态加载 (1)在arm linu

22、x 的kernel 目录下make menuconfig。 (2)首先(*)选择Multimedia device->下的Video for linux。加载video41inux 模块,为视频采集设备提供了编程接口。 (3)然后在usb support->目录下(*)选择support for usb 和usb cameraov511 support。这使得在内核中加入了对采用ov511 接口芯片的USB 数字摄像头的驱动支持。 (4)保存配置退出。 (5)make dep;make zlmage 2动态加载 (1)在arm linux 的kernel 目录下make menuc

23、onfig。 (2)首先<*>选择Multimedia device->下的Video for linux。 (3)然后在usb support->目录下<*>选择support for usb 和<M>选择usb camera ov51 1 support。 (4)保存退出。 (5)Make dep;make zlmage;make modules 然后就在/driver/usb 下生成ov511.ko,同时生成的zImage 自动放在/tftpboot 下。 (6)然后用新内核启动板子后insmod ov511.ko 就可以成功加载。动态方式

24、与静态方式相比,测试时要简单的多。不需要下载整个内核,只需通过nfs,加载驱动即可测试。在测试成功后就可以编译进内核。模块加载中出现的问题。 1insmod 和modprobe 间的一个区别是后者不会在当前目录中查找模块,它只在/lib/modules 下的缺省目录下查找,这是因为该程序只是一个系统实用例程,不是一个交互工具。可以通过在/ere/ modules.conf 中指定自己的目录,来把它们加到缺省目录集中。 2如果插入模块ov511.ko 时,出现以下信息:ov511.ko:unresolved symbol Video*之类的,说明还有其它模块videodev.o 没有加。 3出现

25、错误:ov511.ko:couldnt find the kernel version this moduleswas compiLCD for。这是试图插入一个不是可装入模块的目标文件。因为在内核配置阶段,是把ov511 模块静态加到内核中的,虽然看起来和可装入模块的文件名ov511.ko 完全一样,但是不能用insmod 命令加入。 4如果出现ov511.ko:unresolved symbol video*,那就<M>选中videofor linux,用新生成的内核启动系统,再insmod videodevo,insmod ov511.ko2、zc301 驱动加载 摄像头的驱

26、动是从http:/mxhaard.free.fr/下的针对embeded 环境,有专门的patch,如usb-2.4.3 1 LE06.patch。 (1)把它放到kemel/driver/usb 下,解压,打补丁。就会在此目录下看到spca5xx 文件夹了。Patch 时会将修改方法写到Makefile.rej 和eonfig.in.rej文件中,把这两个文件里的内容加到Makefile 和Kconfig 中就行了。 (2)编译内核,/kernel,make menuconfig。采用和上面介绍的ov511 驱动的方法一样,动态加载。(M)选中SPCA5XX 这一项。 (3)make dep

27、;make zlmage;make modules。就会在/kernel/drive r/usb/spca5xx 中生成spca5xx.ko,spcadecoder.ko,spca_core. Ko.这就是我们要的驱动。 (4)用新内核启动,insmod 这三个.ko 文件(可以不用加载spcadecoder.ko),摄像头就加载成功。2.3.2 Video41inux 编程 Vide04Linux 是Linux 中关于视频设备的内核驱动,它为针对视频设备的应用程序编程提供一系列接口函数,这些视频设备包括现今市场上流行的TV 卡、视频对于USB 口摄像头,其驱动程序中需要提供基本的IO 操作接

28、口函数open、read、write、close 的实现。对中断的处理实现,内存映射功能以及对IO 通道的控制接口函数ioctl 的实现等,并把它们定义在struct file operations 中。这样当应用程序对设备文件进行诸如open、close、read、write 等系统调用操作时,Linux 内核将通过file operations 结构访问驱动程序提供的函数。例如,当应用程序对设备文件执行读操作时,内核将调用file operations 结构中的read 函数。在系统平台上对USB 口数码摄像头驱动,首先把USB 控制器驱动模块静态编译进内核,使平台中支持USB 接口,再在

29、需要使用摄像头采集时,使用insmode 动态加载其驱动模块,这样摄像头就可正常工作了,接着进行了下一步对视频流的采集编程。在USB 摄像头被驱动后,只需要再编写一个对视频流采集的应用程序就可以了。根据嵌入式系统开发特征,先在宿主机上编写应用程序,再使用交叉编译器进行编译链接,生成在目标平台的可执行文件。宿主机与目标板通信采用打印终端的方式进行交叉调试,成功后移植到目标平台。本文编写采集程序是在安装Linux操作系统的宿主机PC 机上进行的,下面是具体论述。1 视频编程的流程 (1)打开视频设备。 (2)读取设备信息。 (3)更改设备当前设置(可以不做)。 (4)进行视频采集,两种方法: a内

30、存映射。 b直接从设备读取。 (5)对采集的视频进行处理。 (6)关闭视频设备。2定义的数据结构及使用函数Struct_v41_structInt fd;struot video_capability capability;struct video_buffer buffer;struct video_Windows Windows;struct video_channel channel8;struet video_picture picture;struct video_mmap mmap;struct video_mbufmbuf;unsigned char*map;typedef st

31、ruct_v41_struct v41_device;extem int v41_open(char *,v41_device *);extem int v41_close(v41_device *);extern int v41_get_capability(v41_device *);extem int v41 set norm(v41_device*,int);extern int v41_get_picture(v41_device*);extem int v41_grab_init(v41_device*,int,int);extem int v41_grab_frame(v41_d

32、evice*,int);extem hat v41_grab_sync(v41_device*);extem hat v41_mmap_init(v41_device*);extern hat v41_get_mbuf(v41_device*);extem int v41_get_picture(v41_device*);extern int v41_grab_picture(v41_device*,unsigned int);extern int v41 set buffer(v41_device*);extern int v41_get_buffer(v41_device*);extern

33、 int v41_switch_channel(v41_device*,int);3Video41inux 支持的数据结构及其用途(1)video_capability 包含设备的基本信息(设备名称、支持的最大最小分辨率、信号源信息等)。name32设备名称。maxwidthmaxheightMinwidthminheightChannels 信号源个数type 是否能capture,彩色还是黑白,是否能裁剪等等。其值如VID_TYPE_CAPTURE(2)video_picture 设备采集的图像的各种属性。Brightness 065535huecolourcontrastwhitenes

34、sdepth 8 16 24 32paleRe VIDEO_PALETTE_RGB24| VIDEO_PALETTE_RGB565|VIDEO_PALETTE_JPEGI|VIDEO_PALETTE_RGB32(3)video channel 关于各个信号源的属性。Channel 信号源的编号nametunersType VIDEO_TYPE_TV|IDEO_TYPE_CAMERANorm 制式PAL|NSTC|SECAM|AUTO(4)video Windows 包含关于capture area 的信息。x xWindows 中的坐标。YYWindows 中的坐标。(5)video _mbu

35、f 利用mmap 进行映射的帧的信息。size 每帧大小。Frames 最多支持的帧数。Offsets 每帧相对基址的偏移。(6)video _mmap 用于mmap。5.3 编程中关键步骤介绍1. Usb hub 接到开发板的usb host 上。cat/proc/devices 可以知道videocapture device 的major 是81,再ls -1/dev 看到video0 的次设备号是0,mknod/dev/video1 c 81 1。(1)打开视频:Int v41_open(char *dev,v41_device *vd)if(!dev)dev=”/dev/video0”

36、;if(vd->fd=open(dev,O_RDWR)<0)perror(“v41_open:”);return -1;if(v41_get_capability(vd)return -1;if(v41_get_picture(vd)retum-1;return 0;(2)读video_capability 中信息int v41_get capability(v41 device *vd)if(ioctl(vd->fd,VIDIOCGCAP,&(vd->capability)<0)perror("v41_get_capability:"

37、);return-1;)return 0;成功后可读取vd->capability 各分量。(3)读video_picture 中信息int v41_get_picture(v41_device*vd)if(ioctl(vd->fd,VIDIOCGPICT,&(Vd->picture)<0)perror(“v41_get_picture:”);return-1;)return O;成功后可读取图像的属性。(4)改变video_picture 中分量的值先为分量赋新值,再调用VIDIOCSPICTVd->picture.colour=65535;if(ioc

38、tl(vd->fd,VIDIOCSPICT,(Vd->picture)<o)perror(”VIDIOCSPICT”);return-1;(5)初始化channel必须先做得到vd->capability 中的信息int v41_getchannels(v41_device *vd)int i;for(i=O;i<vd->capability.channels;i+)vd->channelichannel=i;if(ioctl(vd->fd,VIDIOCGCHAN,&(Vd->channeli)<0)perror(“v41_g

39、et_channel: ”);return-1;)return 0;(6)关闭设备int v41_close(v41_device *vd)close(vd->fd);return 0;2.重点:截取图像的方法,我们采用的是mmap(内存映射)的方式截取视频。mmap()系统调用使得进程之间通过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后,进程可以向访问普通内存一样对文件进行访问,不必再调用read(),write()等操作。两个不同进程A、B 共享内存的意思是,同一块物理内存被映射到进程A、B 各自的进程地址空间。进程A 可以即时看到进程B对共享内存中数据的更新,反之

40、亦然。采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝。(1)设置picture 的属性。vd->mmapformat=VIDEO_PALETTE_RGB24(2)初始化video _mbuf,以得到所映射的buffer 的信息。ioctl(vd->fd,VIDIOCGMBUF,(vd->mbuf)(3)可以修改video _mmap 和帧状态的当前设置。(4)将mmap 与video_ mbuf 绑定。Void *mmap(void*addr,size_t len,int prot,int flags,int fd,off_to

41、ffset)len:映射到调用进程地址空间的字节数,它从被映射文件开头offset 个字节开始算起;Prot:指定共享内存的访问权限PROT _READ(可读),PROT _WRITE (可写),PROT_ EXEC(可执行)Flags:MAP_SHARED MAP_PRIVATE 中必选一个,MAP_FIXED 不推荐使用。Addr:共内存享的起始地址,一般设0,表示由系统分配。Mmap()返回值是系统实际分配的起始地址。int v41_mmap_init(v41_deviee *vd)if(v41_get_mbuf(vd)<0)return-1;if(vd->map=mmap(

42、0,vd->mbuf.size,PROT_READ|PROT_WRITE,MAP_SHARED, vd->fd, 0)<0)perror(”v4 l_mmap_init:mmap”);return-1;return 0;(5)Mmap 方式下真正做视频截取的VIDIOCMCAPTURE。ioctl(vd->fd,VIDIOCMCAPTURE,&(vd->rnmap);若调用成功,开始一帧的截取,是非阻塞的,是否截取完毕留给VIDIOCSYNC来判(6)调用VIDIOCSYNC 等待一帧截取结束。if(ioctl(vd->fd,VIDIOCSYNC,&

43、amp;frame)<0)perror(”v4 l_mmap_init:mmap”);return-1;return 0;(5)Mmap 方式下真正做视频截取的VIDIOCMCAPTURE。ioctl(vd->fd,VIDIOCMCAPTURE,&(vd->rnmap);若调用成功,开始一帧的截取,是非阻塞的,是否截取完毕留给VIDIOCSYNC来判(6)调用VIDIOCSYNC 等待一帧截取结束。if(ioctl(vd->fd,VIDIOCSYNC,&frame)<O)perror(”v41_sync:VIDIOCSYNC”);return-1;

44、若成功,表明一帧截取已完成。可以开始做下一次VIDIOCMCAPTURE。frame 是当前截取的帧的序号。关于双缓冲Video_ bmuf bmuf.frames=2:一帧被处理时可以采集另一帧。int frame;当前采集的是哪一帧。int framestat2;帧的状态没开始采集I 等待采集结束,帧的地址由vd->map+vd->mbuf.offsetsvd->frame得到。采集工作结束后调用munmap 取消绑定。munmap(vd->map,vd->mbuf.size)在实际应用时还可以采用缓冲队列等方式。2.3.3本系统中使用的采集和显示方案 不管是

45、ov511 还是zc301 的摄像头,它们采集的方式都是相同的,只不过采集到的数据有所差异,ov511 的就是rgb 的位流,而zc301 是jpeg 编码的位流。 LCD 实时显示从ov511 摄像头上采集的图像 由于lcd 液晶屏显示的是16bits 的RGB 图片,所以,ov511 输出的图片格式也应该是16bits 的RGB 图片数据,宏VIDEO_ PALETTE_ RGB565 定义的就是16bits的RGB 数据图片。而linux 自带的ov511 驱动中图像采集是32 位的,这样采集到的图片显示在lcd 上是雪花点。因此需要修改驱动。在kemetdriverusb

46、目录下有ov51l 芯片的驱动ov511.e,驱动里的ov51x _set_ default_ params 函数是设置芯片默认的输出图片的格式,该函数中的for(i=O;i<OV511_NUMFRAMES;i+)ov51 1->framei.width=ov5 1 1->maxwidth;ov51 1->framei.height=ov5 1 1->maxheight;ov51 1->framei.bytesread=0;if(force_palette)ov511->framei.format=force_palette;elseov51 1-&g

47、t;framei.format=VIDEO_PALETTE_RGB24;ov51l->framei.depth=ov51l_get_depth(ov511->framei.format) ;部分语句是主要设置ov511 默认输出图片格式的,其中maxwidth 和maxheight设置了图片的最大的宽度和高度。If-else 语句设置了图片的格式,作如下的修改:for(i=O;i<OV511_NUMFRAMES;i+)ov511->framei.width=ov511->maxwidth;ov511->framei.height=ov511->maxh

48、eight;ov51 1->framei.bytes_read=0;ov51 1->framei.format=VIDEO_PALETTE_RGB565;ov511->framei.depth=ov51l_getdepth(ov511->framei.format) 如果需要,也可以改变图片的默认输出大小。本系统在采集的软件设计上采用了双缓冲,视频采集必须用到VIDIOCMCAPTURE和VIDIOCSYNC 这两个ioctl 函数。VIDIOCGMBUF 包含有所用缓冲器的设置与地址。VIDIOCMCAPTURE 用于开始采集; VIDIOCSYNC 用于等待捕捉完成

49、。为加快数据处理速度,本装置采用了双缓冲,即buffer0 采集数据时,buffer1 的数据用于显示;buffer1 采集数据,buffer0 的数据用于显示。双缓冲的含义是每次采集两帧分别为0,1 帧,分别放在两个帧缓冲区如下伪代码:VIDIOCMCAPTURE(0) /开始采集第一帧;while(1)VIDIOCMCAPTURE(1) /开始采集第N 次第二帧VIDIOCSYNC(0) /第N 次第一帧是否完成,没完成等待/在采集第N 次第二帧的时候开始显示第N 第一帧;VIDIOCMCAPTURE(0) /又开始采集第N+1 次第一帧VIDIOCSYNC(1) /等待第N 次采集的第二帧;/在第N+1 次

温馨提示

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

评论

0/150

提交评论