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

📄 spcav4l.c

📁 2410下面摄像头抓图程序
💻 C
字号:
/****************************************************************************
Mouse-capture Version 2:2006-7-5
This program is used to get continuous pictures from a jpeg webcam to show them in lcd(240x320,Of course,you can modify the size).
It is made for ARM9.
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"


/****************************************************************************
*			Public
****************************************************************************/
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;
	// check format 
  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;
  /*          compute the max frame size   */
  vd->formatIn = format; 
  vd->bppIn = GetDepth (vd->formatIn);
  vd->grabMethod = grabmethod;		//mmap or read 
  vd->pFramebuffer = NULL;
  /* init and check all setting */
  err = init_v4l (vd);
  /* allocate the 4 frames output buffer */
 
 for (i = 0; i < OUTFRMNUMB; i++)
    {
      vd->ptframe[i] = NULL;
      vd->ptframe[i] =
	(unsigned char *) realloc (vd->ptframe[i],  (size_t) vd->framesizeIn );
      vd->framelock[i] = 0;
    }
  vd->frame_cour = 0;
  
  
  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;
    }
  for (i = 0; i < OUTFRMNUMB; i++)
    {
      if (vd->ptframe[i])
	{
	  free (vd->ptframe[i]);
	  vd->ptframe[i] = NULL;
	  vd->framelock[i] = 0;
	}
    }
}

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)
{
  int len;
  int size;
  int erreur = 0;
  int jpegsize = 0;
      FILE *fp;


	if (vd->grabMethod) {  
      vd->vmmap.height = vd->hdrheight;
      vd->vmmap.width = vd->hdrwidth;
      vd->vmmap.format = vd->formatIn;
      if (ioctl (vd->fd, VIDIOCSYNC, &vd->vmmap.frame) < 0)
	{
	  perror ("cvsync err\n");
	  erreur = -1;
	}
     
	/* Is there someone using the frame */  
	
	 jpegsize= convertframe(vd->ptframe[vd->frame_cour],
	 		vd->pFramebuffer + vd->videombuf.offsets[vd->vmmap.frame],
			vd->hdrwidth,vd->hdrheight,vd->formatIn,vd->framesizeIn);
	
	
	/************************************/
	
      if ((ioctl (vd->fd, VIDIOCMCAPTURE, &(vd->vmmap))) < 0)
	{
	  perror ("cmcapture");
	  erreur = -1;
	}
      vd->vmmap.frame = (vd->vmmap.frame + 1) % vd->videombuf.frames;
      vd->frame_cour = (vd->frame_cour +1) % OUTFRMNUMB;

    }
  else
    {
      /* read method */
      size = vd->framesizeIn;
      len = read (vd->fd, vd->pFramebuffer, size);
      if (len < 0 )
	{
	  return -1;
	}
	
      /* Is there someone using the frame */
	 jpegsize= convertframe(vd->ptframe[vd->frame_cour],
	 		vd->pFramebuffer ,
			vd->hdrwidth,vd->hdrheight,vd->formatIn,vd->framesizeIn); 
	
	
	vd->frame_cour = (vd->frame_cour +1) % OUTFRMNUMB;  
      fp = fopen(filename, "w");
	if(!fp) return -1;
	fwrite(vd->ptframe[vd->frame_cour], jpegsize, 1, fp);
	fclose(fp);

      /************************************/
	return 0;
    }
  return erreur;
}

/*****************************************************************************
* 				Private
******************************************************************************/
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 * vd->bppIn) >> 3; // here alloc the output ringbuffer 
   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;
      for (f = 0; f < vd->videombuf.frames; f++)
	{
	  vd->vmmap.frame = f;
	  if (ioctl (vd->fd, VIDIOCMCAPTURE, &(vd->vmmap)))
	    {
	      perror ("cmcapture");
	    }
	}
      vd->vmmap.frame = 0;
    }
  else
    {
      /* read method */
      /* allocate the read buffer */
      vd->pFramebuffer =
	(unsigned char *) realloc (vd->pFramebuffer, (size_t) vd->framesizeIn);
      if (ioctl (vd->fd, VIDIOCGWIN, &(vd->videowin)) < 0)
	perror ("VIDIOCGWIN failed \n");

      if (ioctl (vd->fd, VIDIOCSWIN, &(vd->videowin)) < 0)
	perror ("VIDIOCSWIN failed \n");
    }
  vd->frame_cour = 0;
  return erreur;
}



static int
isSpcaChip (const char *BridgeName)
{
  int i = -1;
  int find = -1;
  int size = 0;
  
  /* Spca506 return more with channel video, cut it */
  
  /* return Bridge otherwhise -1 */
  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;
/* return Stream_id otherwhise -1 */
  if ((match = isSpcaChip (BridgeName)) < 0)
    {
      return match;
    }
  switch (match)
    {
    case BRIDGE_ZC3XX:

      i = JPEG;
      break;
    default:
      i = UNOW; // -1;
      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 + -