📄 spcav4l.c
字号:
/****************************************************************************
Mouse-capture Version 1:2006-6-29
This 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.com
Wish you some useful help!
Best Wish to the orignal authors! Thank you very much!
****************************************************************************/
#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 + -