全部博文(187)
分类: LINUX
2009-09-26 13:39:58
还是要先看一下重要的数据结构struct videodev,这个自定义的数据结构描述了硬件如何采集视频信号,如何处理再传输到网络上的,由于篇幅,这里只列出重要的几项内容:
struct videodev
{
int fd; /*打开设备文件返回的描述符*/
char *videodevice ;
struct video_mmap vmmap; /*几个重要数据结构*/
struct video_capability videocap;
struct video_mbuf videombuf;
struct video_picture videopict;
struct video_window videowin;
struct video_channel videochan;
struct video_param videoparam;
unsigned char *pFramebuffer; /*内存影射后指向设备影射0地址指针*/
unsigned char *ptframe[4]; /*指向发送要发送到网络的数据指针数组*/
int framelock[4]; /*标示锁 0:可写入,1:不可写入*/
pthread_mutex_t grabmutex; /* 线程互斥锁*/
int framesizeIn ; /*frame*/
int formatIn; /*format of palette*/
int bppIn;
volatile int frame_cour; /*标示正在传送的ptframe*/
..............
}
$数据的采集:
初始化
1.struct videodev *dev;
2.将用户设定的format和depth写入dev->formatIn,bppIn中,bppIn的值有format值来决定;本 设计所使用的OV511芯片的摄像头,支持format = 15的格式,查一下videodev.h,15对应的是 VIDEO_PALETTE_YUV420P,对应的bppIn = 12;
3.dev->fd = open (dev->videodevice, O_RDWR)),使用标准open函数打开设备;通过ioctl的参 数VIDIOCGCAP可以察看各项参数;
4.通过VIDIOCGPICT获取struct video_picture参数,代码如下:
ioctl (vd->fd, VIDIOCGPICT, &vd->videopict);
printf ("VIDIOCGPICT brightnes=%d hue=%d color=%d contrast=%d whiteness=%d"
"depth=%d palette=%d\n", dev->videopict.brightness,
dev->videopict.hue, dev->videopict.colour, dev->videopict.contrast,
dev->videopict.whiteness, dev->videopict.depth,
dev->videopict.palette);
5.修改struct video_picture中format和depth参数并保存设置:
dev->videopict.palette = dev->formatIn;
dev->videopict.depth = GetDepth (dev->formatIn);
dev->bppIn = GetDepth (dev->formatIn);
ioctl (dev->fd, VIDIOCSPICT, &dev->videopict);
dev->framesizeIn = (dev->hdrwidth * dev->hdrheight * dev->bppIn) >> 3;
6.memset (&(dev->videombuf), 0, sizeof (dev->videombuf)) 清空videombuf
ioctl (dev->fd, VIDIOCGMBUF,&(dev->videombuf)) 保存影射buffer准备采集,返回非0表示 设置成功默认采集第一次的数据放在buffer[0],下一次放在buffer[1];再一次buffer[0].....
7.dev->pFramebuffer =
(unsigned char *) mmap (0, dev->videombuf.size, PROT_READ | PROT_WRITE,
MAP_SHARED, vd->fd, 0);
mmap内存影射,影射区大小为videombuf.size,分了videombuf.frames块buffer,每块buffer大 小为videombuf.size/videombuf.frames,偏移量大小等于一块buffer的大小,pFramebuffer指 向内存影射区0地址;
8.初始化时候采集数据填满2块buffer(本课题中videombuf.frames=2,硬件决定);
for (f = 0; f < vd->videombuf.frames; f++)
{
vd->vmmap.frame = f;
if (ioctl (vd->fd, VIDIOCMCAPTURE, &(vd->vmmap)))
{
perror ("cmcapture");
}
dev->vmmap.frame = 0;
采集
1.ioctl (dev->fd, VIDIOCSYNC,&dev->vmmap.frame),frame同步,察看dev->vmmap.frame是否已 经采集完成。
2.处理此frame数据:首先察看framelock[]是否被占用,如果可用则调用压缩算法函数处理ptFramebuffer指向的数据,将处理后的数据保存到ptframebuffer[]中,在这个过程中必须保证为互斥操作,调用线程互斥锁。
3.采集数据:ioctl (dev->fd, VIDIOCMCAPTURE, &(dev->vmmap)
dev->vmmap.frame = (dev->vmmap.frame + 1) % dev->videombuf.frames;
dev->frame_cour = (dev->frame_cour +1) % OUTFRMNUMB;
更新标示。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/legendzjut/archive/2006/09/26/1287349.aspx