⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spcav4l.c

📁 linux下基于video for linux的编程
💻 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 + -