📄 ov511_test.c
字号:
/*OV511
* CAMIF test
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <linux/videodev.h>
#include <sys/time.h> /* gettimeofday() */
#include <linux/videodev2.h>
static int cam_fp = -1;
static char *cam_mmap = NULL;
static inline int camera_init(void)
{
int dev_fp = -1;
dev_fp = open("/dev/video0",O_RDWR);
if (dev_fp < 0) {
printf("open /dev/video0 error\n");
return -1;
}
printf("video device opened (%d)\n",dev_fp);
return dev_fp;
}
double ms_time (void) //返回值单位为毫秒
{
static struct timeval tod;
gettimeofday (&tod, NULL); //gttimeofday()会把目前的时间由tod所指的结构返回,//时区的信息则放到NULL所指的结构中
return ((double)tod.tv_sec * 1000.0 + (double)tod.tv_usec / 1000.0);
}
int main(int argc, char *argv[])
{ double ms_time0, ms_time1; typedef struct v4l_struct { int fd;//设备名 struct video_capability cap; //video_capability包含设备的基本信息(设备名称、支持的最大最小分辨率、信号源信息等)。name[32] 设备名称,maxwidth, /* maxheight,minwidth,minheight,Channels 信号源个数,type 是否能capture,彩色还是黑白,是否能裁剪等等。值如VID_TYPE_CAPTURE等*/ struct video_picture pict;//摄像头缓冲区内图像信息 设备采集图象的各种属性 struct video_window window;//窗口信息 struct video_capture v_capture; struct video_mmap v_mmap; //video_mmap 用于mmap,利用mmap进行映射的帧信息,实际上是/*输入到摄像头存储器缓冲中的帧信息 struct video_mbuf v_mbuf; //video_mbuf 利用mmap进行映射的帧的信息。映射区长度,Frames 最多支持的帧数,Offsets 每帧相对基址的偏移 unsigned char *map;//用于存储映射得到的图片的首地址 }v4l_device;
int frame = 0;
int ret;
int i,size; int framestate[2]={0,0};
int width,height; width = atoi(argv[1]); height = atoi(argv[2]);
FILE *filedata;
v4l_device *vd; vd=(v4l_device *)malloc(sizeof(v4l_device));
// write to file
filedata = fopen("OV511.YUV", "ab+"); //fopen是C的库函数,返回的是一个指向文件结构的指针。
if(!filedata){
printf("picmmap.yuv open error\n");
return 0;
}
printf("file.yuv opened \n");
if ((cam_fp = camera_init()) < 0) //open
goto err;
/// //Get capabilities
ret = ioctl(cam_fp,VIDIOCGCAP,&vd->cap); //通过ioctl函数的VIDIOCGCAP控制命令,来获取关于视频采集设备所能显示的最大图像大小,信号源的通道数
if(ret<0) { perror("v4l_get_capability:"); return -1; }
printf("cap:ch=%d,max=%d:%d,min=%d:%d\n",
vd->cap.channels,
vd->cap.maxwidth,vd->cap.maxheight,
vd->cap.minwidth, vd->cap.minheight);
printf("cap:[%s]\n",vd->cap.name);
printf("cap:0x%X\n",vd->cap.type);
///
ret = ioctl(cam_fp,VIDIOCGCAPTURE,&vd->v_capture);
if(ret<0) { perror("v4l_get_capture:"); return -1; }
printf("capture:offset:%d:%d.\n",vd->v_capture.x, vd->v_capture.y);
printf("w=%d,h=%d\n",vd->v_capture.width,vd-> v_capture.height);
printf("decimation=0x%x\n",vd->v_capture.decimation);
printf("flags=%d\n",vd->v_capture.flags);
vd->v_capture.x = 0;
vd->v_capture.y = 0;
vd->v_capture.width = width;
vd->v_capture.height = height;
vd->v_capture.flags = VIDEO_CAPTURE_ODD; //在videodev.h中有宏定义 #define VIDEO_CAPTURE_ODD 0
vd->v_capture.decimation = VIDEO_CAPTURE_ODD;
ret = ioctl(cam_fp,VIDIOCSCAPTURE,&vd->v_capture); // Set subcapture
if(ret<0){ perror("v4l_set_capture:") ; return -1; }
ret = ioctl(cam_fp,VIDIOCGCAPTURE,&vd->v_capture); //Get subcapture
if(ret<0) { perror("v4l_get_capture:"); return -1; }
printf("capture:offset:%d:%d.\n",vd->v_capture.x,vd-> v_capture.y);
printf("w=%d,h=%d\n",vd->v_capture.width,vd-> v_capture.height);
printf("decimation=0x%x\n",vd->v_capture.decimation);
printf("flags=%d\n",vd->v_capture.flags);
///
//Get picture properties
ret = ioctl(cam_fp,VIDIOCGPICT,&vd->pict); //通过ioctl函数的VIDIOCGPICT来获取一些关于图像的亮度,对比度等信息. if(ret<0) { perror("v4l_get_picture:"); return -1; } printf("pict:brightness=%d:hue=%d.\n",vd->pict.brightness,vd->pict.hue);
printf(":color=%d,contrast=%d\n",vd->pict.colour,vd->pict.contrast);
printf(":whiteness=%d,depth=%d\n",vd->pict.whiteness,vd->pict.depth);
printf(":palette=0x%X\n",vd->pict.palette);
vd-> pict.brightness=19968; //新加的,改变亮度
vd-> pict.colour=65535; //
vd-> pict.depth=16;
vd->pict.palette = VIDEO_PALETTE_YUV420; //采用VIDEO_PALETTE_YUV420格式
ret = ioctl(cam_fp,VIDIOCSPICT,&vd->pict); // Set picture properties
if(ret<0) { perror("v4l_set_picture:"); return -1; }
//ret = ioctl(cam_fp,VIDIOCGPICT,&vd->pict); // 否则会再次恢复默认值
printf("pict:brightness=%d:hue=%d.\n",vd->pict.brightness,vd->pict.hue);
printf(":color=%d,contrast=%d\n",vd->pict.colour,vd->pict.contrast);
printf(":whiteness=%d,depth=%d\n",vd->pict.whiteness,vd->pict.depth);
printf(":palette=0x%X\n",vd->pict.palette);
// get mbuf attribute Memory map buffer info ret=ioctl(cam_fp,VIDIOCGMBUF,&vd->v_mbuf);
if ( ret< 0) {
printf("get mbuf attribute error, ret(%d)\n",ret);
goto err;
}
printf("video_mbuf:size=%d frames=%d\n",vd->v_mbuf.size,vd->v_mbuf.frames);
printf("video_mbuf:offsets[0]=%d offsets[1]=%d\n",vd->v_mbuf. offsets[0],vd->v_mbuf .offsets[1]);
//mmap 将视频设备的文件映射进内存
cam_mmap = (char*)mmap(0, vd->v_mbuf.size,
PROT_READ | PROT_WRITE, //页内容可以被读取,可以被写入
MAP_SHARED, cam_fp, 0); //MAP_SHARED与其它所有映射这个对象的进程共享映射空间
if(cam_mmap < 0){
printf("mmap() video error\n");
return -1;
}
size=width*height*3/2;
i = atoi(argv[3]); //把字符串转换成整型数
while(i){ ms_time0 = ms_time(); /* milli seconds */
//v_mmap.frame = 0; //对于单帧采集只需设置v_mmap.frame=0,即采集其中的第一帧
vd->v_mmap.frame = frame;
vd->v_mmap.width = width; //设置内存区里图片的属性,与video_capture匹配
vd->v_mmap.height =height;
vd->v_mmap.format = VIDEO_PALETTE_YUV420;
printf("i=%d\n",i);
if(framestate[frame]==0){ if ((ret =ioctl(cam_fp,VIDIOCMCAPTURE,&vd->v_mmap)) < 0) //Grab frames真正开始视频截取。将图像映射到内存中,
// 若调用成功,开始一帧的截取,是非阻塞的,是否截取完毕留给VIDIOCSYNC来判断
{
printf("get capture error, ret(%d)\n",ret);
goto err;
} framestate[frame]=1; }
if(framestate[frame]==1){
while(ioctl(cam_fp, VIDIOCSYNC, &vd->v_mmap.frame) < 0){ //Sync with mmap grabbing !!
//若成功,表明一帧截取已完成。可以开始做下一次 VIDIOCMCAPTURE
//frame是当前截取的帧的序号
sleep(1); //执行挂起1秒 等待一帧映射结束;
printf("sleep 1s\n");
} framestate[frame]=0; }
fwrite((cam_mmap + vd->v_mbuf.offsets[frame]),size, 1,filedata);
printf("a picture ok\n"); ms_time1 = ms_time () - ms_time0; //统计采集一帧的时间,单位ms printf("%f\n",ms_time1);
frame = (frame == 0)?1:0; //next frame 或者frame=frame^ 1 取异或
i--;
}
err:
fclose(filedata);
if(cam_mmap)
munmap(cam_mmap, vd->v_mbuf.size); //解除内存映射
if(cam_fp)
close(cam_fp);
printf("done.\n");
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -