BCNG 项 目
组
技 术 文
档
版
本:
1.0
作
者:hgang
日
期:
2008-07-12
目
录
一. 概述... 2
二. 编译内核与驱动加载... 3
1. 静态加载... 3
2. 动态加载... 3
三. 设计方案... 3
3. 定义的数据结构... 3
4. 视频编程流程及函数实现... 5
四. 调试过程... 9
五. 存在的问题和拟采取的解决方案... 11
六. 作者简介... 11
一.
概述
本项目是在基于
S3C2440
的嵌入式开发板上实现视频图像采集,压缩,传输等功能,本文主要介绍视频采集部分。
视频采集使用的是带有
OV511
芯片的
V2000
摄像头,
linux
系统自带了
OV511
的驱动程序,所以无需另外安装驱动,只需在编译内核时加载进去
二.
编译内核与驱动加载
1.
静态加载
(1)
在
/home/xiyong/bcng2440/linux-bcng2440-xiyong
目录下
make menuconfig
。
(即板子的内核目录,如果要在
PC
上使用摄像头则在
/usr/src/linux-2.4
下操作)
(2)
首先
(*)
(“
y
”键)选择
Multimedia device->
下的
Video for linux
。加载
video4linux
模块,为视频采集设备提供编程接口;
(3)
然后在
usb support->
目录下
(*)
选择
support for usb
和
usb camera ov511
support
。这使得在内核中加入了对采用
OV511
接口芯片的
USB
数字摄像头的驱动支持。
(4)
保存配置退出。
(5)
make dep
;
(6)
修改
/home/xiyong/bcng2440/linux-bcng2440-xiyong/drivers/media/video
目录下
videodev.c
程序(修改方法在后面调试过程部分有叙述)。
(7)
make zImage
,然后
cp ./arch/arm/boot/zImage /tftpboot/;
2.
动态加载
(1)
在
arm linux
的
kernel
目录下
make menuconfig
。
(2)
首先
<*>
选择
Multimedia device->
下的
Video for linux
。
(3)
然后在
usb support->
目录下
<*>
选择
support for usb
和
<M>
选择
usb camera
ov511 support
。
(4)
保存退出。
(5)
Make dep;
(6)
修改
videodev.c
程序。
(7)
make zImage;make modules
然后就在
/driver/usb
下生成
ov511.o
,同
时生成的
zImage
自动放在
/tftpboot
下。
(8)
然后用新内核启动板子后
insmod ov511.o
就可以成功加载。
我们使用的是静态加载;内核编译完以后板子的启动命令为
t 30008000 zImage; go 30008000;
需要注意的是:
(1)
编译内核是要选择正确的路径,编译
PC
机内核路径是
/usr/src/linux-2.4.18-14,
编译板子是
/home/xiyong/bcng2440/linux-bcng2440-xiyong
。
(2)
注意“
*
”(
y
键)选和“
M”
选的不同。
三.
设计方案
3.
定义的数据结构
typedef struct v4l_struct
{
int fd;//
设备名
struct video_capability capability;//
设备信息
struct video_picture picture;//
摄像头缓冲区内图像信息
struct video_window window;//
窗口信息
struct video_mmap mmap;//
用于内存映射
struct video_mbuf mbuf;//
利用
mmap
进行映射的帧的信息
unsigned char *map;//
用于存储映射得到的图片的首地址
int framestat[2];//
定义帧状态
}v4l_device;
(1)
video_capability
包含设备的基本信息(设备名称、支持的最大最小分辨
率、信号源信息等)
name[32]
设备名称
maxwidth
maxheight
minwidth
minheight
Channels
信号源个数
type
是否能
capture
,
彩色还是黑白,
是否能裁剪等等。值如
VID_TYPE_CAPTURE
等
可以调用
ioctl(vd->fd,VIDIOCGCAP,&(vd->capability)
来读取这些信息。
(2)
video_picture
设备采集的图象的各种属性
Brightness 0~65535
hue
colour
contrast
whiteness
depth 8 16 24 32
palette VIDEO_PALETTE_RGB24 | VIDEO_PALETTE_RGB565|
VIDEO_PALETTE_JPEG| VIDEO_PALETTE_RGB32|VIDEO_PALETTE_YUV420
等。
可以调用
ioctl(vd->fd,VIDIOCGPICT,&(vd->picture))
读取各信息,
ioctl(vd->fd,VIDIOCSPICT,&(vd->picture))
重新设置各信息分量。
(3)
video_mbuf
利用
mmap
进行映射的帧的信息
size
每帧大小
Frames
最多支持的帧数
Offsets
每帧相对基址的偏移
可以调用
ioctl(vd->fd, VIDIOCGMBUF, &vd->mbuf)
读取各信息分量。
这部分出现的问题:
(1)
在程序开始之时声明一个
v4l_device
结构之后一定要为其分配内存空间
v4l_device *vd;
vd=(v4l_device *)malloc(sizeof(v4l_device));
否则会导致问题,在读取
vd->mbuf
信息时
vd->mbuf.offsets
为一个非常大的负值,然后在读取映射图片的地址时(
vd->map + vd->mbuf.offsets[frame]
)就会导致读取数据失败。