📄 spcav4l.c
字号:
/****************************************************************************Mouse-capture Version 1:2006-6-29This program is used to get one picture from a jpeg webcam to test whether the webcam's drive is successfully installed.It is made for ARM9.Of course it can be used on PC if you modify the complier:)It is modified from servfox by daily3(戴丽-戴小鼠 in Hefei University of Technology and HHCN-BBS).Thanks to 我爱狗熊.If you have problems ,you can contact me.Email:daily3@126.comWish you some useful help!Best Wish to the orignal authors! Thank you very much!*************************************************************************************static int GetVideoPict (struct vdIn *vd);//获取图片属性信息。static int SetVideoPict (struct vdIn *vd);//设置图片属性。static int isSpcaChip (const char *BridgeName);//测试芯片类型static int GetStreamId (const char *BridgeName); //测试输出数据的格式static int GetDepth (int format);//获取颜色深度。void exit_fatal(char *messages);//错误显示。int init_videoIn(struct vdIn *vd,char *device,int width,int height,int format,intgrabmethod);//初始化设备。int convertframe(unsigned char *dst,unsigned char *src, int width,int height, intformatIn, int size);//把共享缓冲区中的数据放到一个变量中,通知系统已获得一帧。int v4lGrab (struct vdIn *vd,char *filename );//从摄像头采集图片。int close_v4l (struct vdIn *vd);//关闭摄像头。int get_jpegsize (unsigned char *buf, int insize);//获取jpeg图片大小int init_videoIn(struct vdIn *vd,char *device,int width,int height,int format,intgrabmethod);//初始化设备。****************************************************************************/#include "spcav4l.h"static int init_v4l (struct vdIn *vd);static int isSpcaChip ( const char * BridgeName );//测试芯片类型static int GetStreamId ( const char * BridgeName );//测试输出数据的格式static int GetDepth (int format);//获取颜色深度static struct bridge_list Blist[]={ {BRIDGE_ZC3XX,"ZC301-2"},};int init_videoIn (struct vdIn *vd, char *device, int width, int height, int format, int grabmethod){ int err = -1; int i; if (vd == NULL || device == NULL) return -1; if (width == 0 || height == 0) return -1; if(grabmethod < 0 || grabmethod > 1) grabmethod = 1; //read by default; vd->videodevice = NULL; vd->cameraname = NULL; vd->videodevice = NULL; vd->videodevice = (char *) realloc (vd->videodevice, 32); vd->cameraname = (char *) realloc (vd->cameraname, 32); snprintf (vd->videodevice, 32, "%s", device); memset (vd->cameraname, 0, sizeof (vd->cameraname)); memset(vd->bridge, 0, sizeof(vd->bridge)); vd->hdrwidth = width; vd->hdrheight = height; vd->formatIn = format; vd->bppIn = GetDepth (vd->formatIn); vd->grabMethod = grabmethod; vd->pFramebuffer = NULL; err = init_v4l (vd); vd->ptframe = NULL; vd->ptframe = (unsigned char *) realloc (vd->ptframe, (size_t) vd->framesizeIn ); return err;}int close_v4l (struct vdIn *vd){ int i; if (vd->grabMethod) { munmap (vd->pFramebuffer, vd->mmapsize); } else { free(vd->pFramebuffer); vd->pFramebuffer = NULL; } close (vd->fd); /* dealloc the whole buffers */ if (vd->videodevice) { free (vd->videodevice); vd->videodevice = NULL; } if (vd->cameraname) { free (vd->cameraname); vd->cameraname = NULL; } if (vd->ptframe) { free (vd->ptframe); vd->ptframe = NULL; }}int convertframe(unsigned char *dst,unsigned char *src, int width,int height, int formatIn, int size){ int jpegsize =0; switch (formatIn){ case VIDEO_PALETTE_JPEG: jpegsize = get_jpegsize(src, size); if (jpegsize < 0) break; memcpy(dst,src,jpegsize); break; default: break; }return jpegsize;}int v4lGrab(struct vdIn *vd, char *filename){ FILE *fp; static int frame = 0; int len; int size; int erreur = 0; int jpegsize = 0; if (vd->grabMethod) { vd->vmmap.height = vd->hdrheight; vd->vmmap.width = vd->hdrwidth; vd->vmmap.format = vd->formatIn; if ((ioctl (vd->fd, VIDIOCMCAPTURE, &(vd->vmmap))) < 0) { perror ("cmcapture"); } if (ioctl (vd->fd, VIDIOCSYNC, &vd->vmmap.frame) < 0) { perror ("cvsync err\n"); erreur = -1; } jpegsize= convertframe(vd->ptframe, vd->pFramebuffer + vd->videombuf.offsets[vd->vmmap.frame], vd->hdrwidth,vd->hdrheight,vd->formatIn,vd->framesizeIn); } else { /* read method */ size = vd->framesizeIn; len = read (vd->fd, vd->pFramebuffer, size); if (len < 0 ) { return -1; } jpegsize= convertframe(vd->ptframe, vd->pFramebuffer ,vd->hdrwidth,vd->hdrheight,vd->formatIn,vd->framesizeIn); fp = fopen(filename, "w"); if(!fp) return -1; fwrite(vd->ptframe, jpegsize, 1, fp); fclose(fp); return 0; } return erreur;}static int GetVideoPict (struct vdIn *vd){ if (ioctl (vd->fd, VIDIOCGPICT, &vd->videopict) < 0) exit_fatal ("Couldnt get videopict params with VIDIOCGPICT"); return 0;}static int SetVideoPict (struct vdIn *vd){ if (ioctl (vd->fd, VIDIOCSPICT, &vd->videopict) < 0) exit_fatal ("Couldnt set videopict params with VIDIOCSPICT"); return 0;}static int init_v4l (struct vdIn *vd){ int f; int erreur = 0; int err; if ((vd->fd = open (vd->videodevice, O_RDWR)) == -1) exit_fatal ("ERROR opening V4L interface"); if (ioctl (vd->fd, VIDIOCGCAP, &(vd->videocap)) == -1) exit_fatal ("Couldn't get videodevice capability"); snprintf (vd->cameraname, 32, "%s", vd->videocap.name); erreur = GetVideoPict (vd); if (ioctl (vd->fd, VIDIOCGCHAN, &vd->videochan) == -1) { vd->cameratype = UNOW; } else { if (vd->videochan.name){ snprintf (vd->bridge, 9, "%s", vd->videochan.name); vd->cameratype = GetStreamId (vd->bridge); } else { vd->cameratype = UNOW; } }/* Only jpeg webcam allowed */if(vd->cameratype != JPEG) { exit_fatal ("Not a JPEG webcam sorry Abort !");} vd->videopict.palette = vd->formatIn; vd->videopict.depth = GetDepth (vd->formatIn); vd->bppIn = GetDepth (vd->formatIn); vd->framesizeIn = (vd->hdrwidth * vd->hdrheight >> 2 ); // here alloc the output ringbuffer jpeg only erreur = SetVideoPict (vd); erreur = GetVideoPict (vd); if (vd->formatIn != vd->videopict.palette || vd->bppIn != vd->videopict.depth) exit_fatal ("could't set video palette Abort !"); if (erreur < 0) exit_fatal ("could't set video palette Abort !"); if (vd->grabMethod) { // MMAP VIDEO acquisition memset (&(vd->videombuf), 0, sizeof (vd->videombuf)); if (ioctl (vd->fd, VIDIOCGMBUF, &(vd->videombuf)) < 0) { perror (" init VIDIOCGMBUF FAILED\n"); } vd->pFramebuffer =(unsigned char *) mmap (0, vd->videombuf.size, PROT_READ | PROT_WRITE,MAP_SHARED, vd->fd, 0); vd->mmapsize = vd->videombuf.size; vd->vmmap.height = vd->hdrheight; vd->vmmap.width = vd->hdrwidth; vd->vmmap.format = vd->formatIn; vd->vmmap.frame = 0; if (ioctl (vd->fd, VIDIOCMCAPTURE, &(vd->vmmap))) { perror ("cmcapture"); } } else { vd->pFramebuffer =(unsigned char *) realloc (vd->pFramebuffer, (size_t) vd->framesizeIn); } return erreur;}static int isSpcaChip (const char *BridgeName){ int i = -1; int find = -1; int size = 0; for (i = 0; i < MAX_BRIDGE -1; i++) { size = strlen (Blist[i].name) ; if (strncmp (BridgeName, Blist[i].name, size) == 0) { find = i; break; } } return find;}static int GetStreamId (const char *BridgeName){ int i = -1; int match = -1; if ((match = isSpcaChip (BridgeName)) < 0) { return match; } switch (match) { case BRIDGE_ZC3XX: i = JPEG; break; break; } return i;}static int GetDepth (int format){ int depth; switch (format) { case VIDEO_PALETTE_JPEG: { depth = 8; } break; default: depth = -1; break; } return depth;}void exit_fatal(char *messages){ printf("%s \n",messages); exit(1);}int get_jpegsize (unsigned char *buf, int insize){ int i; for ( i= 1024 ; i< insize; i++) { if ((buf[i] == 0xFF) && (buf[i+1] == 0xD9)) return i+2; } return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -