您好,欢迎访问三七文档
1#includestdio.h#includestdlib.h#includesys/types.h#includesys/ioctl.h#includesys/mman.h#includesys/stat.h#includesys/time.h#includefcntl.h#includeunistd.h#includelinux/types.h#includelinux/videodev.h#includemalloc.h#includestring.h#includesys/time.h#defineUSB_VIDEO_DEV/dev/video0#defineFILE_NAME/tmp/1.jpg#defineSTILL_IMAGE-1#defineVIDEO_START0#defineVIDEO_STOP1#defineVIDEO_PALETTE_RAW_JPEG20#defineVIDEO_PALETTE_JPEG21staticintdebug=1;intget_jpegsize(unsignedchar*buf,intsize){inti;for(i=1024;isize;i++){if((buf[i]==0xFF)&&(buf[i+1]==0xD9))returni+2;//jpeg文件格式中是以0xFF0xD9结尾的,//以此判断文件大小}return-1;}intmain(intargc,char*argv[]){intusb_camera_fd=-1,framesize=0,jpegsize=0;char*usb_video_dev=USB_VIDEO_DEV;char*filename=FILE_NAME;FILE*fp;structvideo_capabilityvideo_caps;2structvideo_channelvideo_chan;structvideo_picturevideo_pic;structvideo_mbufvideo_mbuffer;structvideo_mmapvid_mmap;unsignedchar*mapaddr=NULL,*framebuffer=NULL,*destbuffer=NULL;usb_camera_fd=open(usb_video_dev,O_RDWR);//打开设备,可读写if(usb_camera_fd==-1){fprintf(stderr,Can'topendevice%s,usb_video_dev);return1;}/**********************video_capability**************/if(ioctl(usb_camera_fd,VIDIOCGCAP,&video_caps)==-1)//getvideodevicecapability获取设备基本信息{perror(Couldn'tgetvideodevicecapability);return-1;}if(debug){printf(videoname:%s\n,video_caps.name);printf(video_caps.channels:%d\n,video_caps.channels);printf(video_caps.type:0x%x\n,video_caps.type);printf(videomaxwidth:%d\n,video_caps.maxwidth);printf(videomaxheight:%d\n,video_caps.maxheight);printf(videominwidth:%d\n,video_caps.minwidth);printf(videominheight:%d\n,video_caps.minheight);}/************************video_channel****************//*video_chan.channel=video_caps.channels;if(ioctl(usb_camera_fd,VIDIOCGCHAN,&video_chan)==-1)//获取信号源的属性{perror(ioctl(VIDIOCGCAP));return-1;}if(debug){printf(videochannel:%d\n,video_chan.channel);printf(videochannelname:%s\n,video_chan.name);printf(videochanneltype:%d\n,video_chan.type);}*/3/*************************video_picture****************/if(ioctl(usb_camera_fd,VIDIOCGPICT,&video_pic)==-1)//获取设备采集的图象的各种属性{perror(ioctl(VIDIOCGPICT));return-1;}/*video_pic.palette=VIDEO_PALETTE_JPEG;video_pic.depth=8;video_pic.hue=50110;video_pic.whiteness=41380;if(ioctl(usb_camera_fd,VIDIOCSPICT,&video_pic)==-1)//设置设备采集的图象的属性{perror(ioctl(VIDIOCSPICT));//return-1;}*/if(debug){printf(video_pic.brightness:%d\n,video_pic.brightness);printf(video_pic.colour:%d\n,video_pic.colour);printf(video_pic.contrast:%d\n,video_pic.contrast);printf(video_pic.depth:%d\n,video_pic.depth);printf(video_pic.hue:%d\n,video_pic.hue);printf(video_pic.whiteness:%d\n,video_pic.whiteness);printf(video_pic.palette:%d\n,video_pic.palette);}/************************video_mbuf**********************/memset(&video_mbuffer,0,sizeof(video_mbuffer));//初始化video_mbuf,以得到所映射的buffer的信息if(ioctl(usb_camera_fd,VIDIOCGMBUF,&video_mbuffer)==-1)//video_mbuf{perror(ioctl(VIDIOCGMBUF));return-1;}if(debug){printf(video_mbuffer.frames:%d\n,video_mbuffer.frames);printf(video_mbuffer.offsets[0]:%d\nvideo_mbuffer.offsets[1]:%d\n,video_mbuffer.offsets[0],video_mbuffer.offsets[1]);4printf(video_mbuffer.size:%d\n,video_mbuffer.size);}//将mmap与video_mbuf绑定mapaddr=(unsignedchar*)mmap(0,video_mbuffer.size,PROT_READ,MAP_SHARED,usb_camera_fd,0);if(mapaddr0){perror(v4lmmap);return-1;}/********************video_mmap*************************/vid_mmap.width=320;vid_mmap.height=240;vid_mmap.frame=0;//单帧采集vid_mmap.format=VIDEO_PALETTE_JPEG;/**********************startcapture********************///Mmap方式下真正开始视频截取//若调用成功,开始一帧的截取,是非阻塞的是否截取完毕留给VIDIOCSYNC来判断if(ioctl(usb_camera_fd,VIDIOCCAPTURE,VIDEO_START)==-1){perror(ioctl(VIDIOCCAPTURE));return-1;}/***********************waitforready*******************///调用VIDIOCSYNC等待一帧截取结束//若成功,表明一帧截取已完成。可以开始做下一次VIDIOCMCAPTURE//frame是当前截取的帧的序号/*if(ioctl(usb_camera_fd,VIDIOCSYNC,&vid_mmap.frame)==-1){perror(ioctl(VIDIOCSYNC));//return-1;}*/framesize=320*2402;//实际采集到的jpeg图像的大小最多也就十几KB//获取刚刚采集到的图像数据帧的地址framebuffer=mapaddr+video_mbuffer.offsets[vid_mmap.frame];5//获取图像的大小//jpegsize=get_jpegsize(framebuffer,framesize);if(jpegsize0){printf(Can'tgetsizeofjpegpicture\n);return1;}//分配空间,准备将destbuffer缓冲区中的图像数据写入文件destbuffer=(unsignedchar*)malloc(video_mbuffer.size);if(destbuffer==NULL){printf(mallocmemoryfordestbuffererror\n);return-1;}memcpy(destbuffer,framebuffer,video_mbuffer.size);fp=fopen(filename,wb);//打开文件if(!fp){printf(Can'topenfile%s,filename);//return-1;}fwrite(destbuffer,video_mbuffer.size,1,fp);//写入文件fclose(fp);//关闭文件free(destbuffer);//释放空间munmap(mapaddr,video_mbuffer.size);//取消绑定close(usb_camera_fd);return1;}v4l2驱动编写篇一--介绍原文网址:笔者最近有机会写了一个摄像头的驱动,是“Onelaptopperchild”项目的中摄像头专用的。这个驱动使用了为此目的而设计的内核API:theVideo4Linux2API。在写这个驱动的过程中,笔者发现了一个惊人的问题:这个API的文档工作做得并不是很好,而用户层的文档则写的,实际上,相当不错。为了补救现在的状况,LWN将在未来的内个月里写一系列文章,告诉大家如何写V4L2接口的驱动。V4L2有一段历史了。大约在1998的秋天,它的光芒第一次出现在BillDirks的眼中。经过长足的发展,它于2002年11月,发布2.5.46时,融入了内核主干之中。然而直到今天,仍6有一部分内核驱不支持新的API,这种新旧API的转换工作仍在进行。同时,V4L2API也在发展
本文标题:v4l2编程经典
链接地址:https://www.777doc.com/doc-1521674 .html