视频采集
2006-09-26 13:46
183 查看
还是要先看一下重要的数据结构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;
更新标示。
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;
更新标示。
相关文章推荐
- linux下视频采集服务器(UDP传输、多线程模式)
- 入门视频采集与处理
- 用DirectShow实现视频采集-流程构建
- 转----Android用MediaRecorder 视频采集
- GStreamer资料整理(包括摄像头采集,视频保存,远程监控,流媒体RTP传输)
- javascript正则表达式提取指定的字符 分享如何随机播放采集的优酷视频地址
- 入门视频采集与处理(BT656简介)
- v4l2视频采集的基本流程
- 网页视频采集
- 摄像头视频采集压缩及传输
- 入门视频采集与处理(学会分析YUV数据)
- DM642视频采集程序注释
- [引]C# WinForm DirectShow视频采集及图片抓取实例DxSnap
- DM6467 之视频采集(linux)下mmap
- 基于ZedBoard的Webcam设计(三):视频的采集和动态显示
- Android 音视频开发(四):使用 Camera API 采集视频数据
- DirectShow&DirectSound采集音频视频数据 vs2013
- iOS视频采集(一)
- 摄像头视频采集压缩及传输
- 玩转摄像头之 基于SDRAM缓冲 USB2.0视频采集系统 MT9T001、MT9P031 演示 展示