📄 capture.c
字号:
/**---------------------文件信息--------------------------------****文 件 名: capture.c**最后修改日期: 2008-01-25**描 述: 摄像头控制程序** 硬件参数: USB接口,型号中微星301p**** 使用说明:调用fnCaptureFromUsb()读摄像头数据,数据存在ptframe,大小为jpegsize, 调用完fnCaptureFromUsb()后必须调用fnCloseVideo(),进行关闭。 fnSaveFromCapture()的作用是将摄像头拍照的数据本地存储。** 需要添加驱动程序:** spca5xx.o*/#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <fcntl.h>#include <errno.h>#include <stdarg.h>#include <linux/types.h>#include <linux/videodev.h>#include <sys/mman.h>#include <sys/ioctl.h>#include <sys/file.h>#include <sys/types.h>#include <sys/stat.h>#include "capture.h"static int init_v4l (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 v4lGrab (VDIN *vd);int get_jpegsize (unsigned char *buf, int insize);void exit_fatal(char *messages);static struct bridge_list Blist[]={ {BRIDGE_ZC3XX,"ZC301-2"},};int init_videoIn (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 (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; } free(vd);}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(VDIN *vd){ 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); vd->jpegsize=jpegsize; return jpegsize; } 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); vd->jpegsize=jpegsize; return jpegsize; } return erreur;}static int GetVideoPict (VDIN *vd){ if (ioctl (vd->fd, VIDIOCGPICT, &vd->videopict) < 0) exit_fatal ("Couldnt get videopict params with VIDIOCGPICT"); return 0;}static int SetVideoPict (VDIN *vd){ if (ioctl (vd->fd, VIDIOCSPICT, &vd->videopict) < 0) exit_fatal ("Couldnt set videopict params with VIDIOCSPICT"); return 0;}static int init_v4l (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;}/***************************************************************************** 名称:fnCaptureFromUsb* 功能:从USB摄像头读数据* 入口参数:无* 出口参数:无* 函数返回值: VDIN结构体指针* 指向VDIN结构体指针* -1-打开摄像头失败* 测试:* 日期: 2008.1.25****************************************************************************/VDIN *fnCaptureFromUsb(){ char videodevice[] = "/dev/video0"; int grabmethod = 0; int format = VIDEO_PALETTE_JPEG; int width = 352; int height = 288; int jpegsize; int i=0; VDIN *vd ; vd = (VDIN *)malloc(sizeof(VDIN)); memset(vd, 0, sizeof (VDIN)); if (init_videoIn(vd, videodevice, width, height, format,grabmethod)== 0) { jpegsize=v4lGrab(vd); if (grabmethod==1) printf("you use mmap method!\n"); else if (grabmethod==0) printf("you use read method!\n"); } else { printf("can't open your camera!\n"); return (VDIN *)-1; } return vd;}/***************************************************************************** 名称:fnSaveFromCapture* 功能:VDIN *vd数据本地存储* 入口参数:jpegfile-保存路径及文件名,VDIN *vd-VDIN结构体.* 出口参数:无* 函数返回值: int型* 0 -成功* -1-失败* 测试:* 日期: 2008.1.25****************************************************************************/int fnSaveFromCapture(VDIN *vd,char *jpegfile){ FILE *fp; fp = fopen(jpegfile, "w"); if (!fp) { printf("Open file error,Please check your Path!\n"); return -1; } printf("save\n"); fwrite(vd->ptframe, vd->jpegsize, 1, fp); fclose(fp); return 0;}/***************************************************************************** 名称:fnCloseVideo* 功能:关闭USB设备* 入口参数:VDIN *vd* 出口参数:无* 函数返回值: int型* 0 -成功* 测试:* 日期: 2008.1.25****************************************************************************/int fnCloseVideo(VDIN *vd){ close_v4l(vd); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -