?? spcav4l.c
字號:
/****************************************************************************# spcav4l: v4l library. ##This package work with the spca5xx based webcam with the raw jpeg feature. ##All the decoding is in user space with the help of libjpeg. ##. ## Copyright (C) 2003 2004 2005 Michel Xhaard ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## #****************************************************************************//* MOFIFIED by MX for Acme FOX Eltrax 100LX and Arm9 only accept jpeg webcam */#include "spcaframe.h"#include "spcav4l.h"#include "utils.h"#define OUTFRMNUMB 4static int debug = 0;static int init_v4l (struct vdIn *vd);#if 0static int checkpalette (struct vdIn *vd);static int check_palettesize(struct vdIn *vd );static int probePalette ( struct vdIn *vd );static int probeSize ( struct vdIn *vd );#endifstatic int isSpcaChip ( const char * BridgeName );/* return Bridge otherwhise -1 */static int GetStreamId ( const char * BridgeName );/* return Stream_id otherwhise -1 */static intGetDepth (int format);static struct bridge_list Blist[]={ {BRIDGE_SPCA505,"SPCA505"}, {BRIDGE_SPCA506,"SPCA506"}, {BRIDGE_SPCA501,"SPCA501"}, {BRIDGE_SPCA508,"SPCA508"}, {BRIDGE_SPCA504,"SPCA504"}, {BRIDGE_SPCA500,"SPCA500"}, {BRIDGE_SPCA504B,"SPCA504B"}, {BRIDGE_SPCA533,"SPCA533"}, {BRIDGE_SPCA504C,"SPCA504C"}, {BRIDGE_SPCA561,"SPCA561"}, {BRIDGE_SPCA536,"SPCA536"}, {BRIDGE_SONIX,"SN9C102"}, {BRIDGE_ZR364XX,"ZR364XX"}, {BRIDGE_ZC3XX,"ZC301-2"}, {BRIDGE_CX11646,"CX11646"}, {BRIDGE_TV8532,"TV8532"}, {BRIDGE_ETOMS,"ET61XX51"}, {BRIDGE_SN9CXXX,"SN9CXXX"}, {BRIDGE_MR97311,"MR97311"}, {BRIDGE_UNKNOW,"UNKNOW"}, {-1,NULL}};#if 0/* Camera type jpeg yuvy yyuv yuyv grey gbrg*/static struct palette_list Plist[] ={ {JPEG,"JPEG"}, {YUVY,"YUVY"}, {YYUV,"YYUV"}, {YUYV,"YUYV"}, {GREY,"GREY"}, {GBRG,"GBRG"}, {SN9C,"SN9C"}, {GBGR,"GBGR"}, {UNOW,"UNOW"}, {-1,NULL}};#endif/***************************************************************************** Public****************************************************************************/intinit_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, 16); vd->cameraname = (char *) realloc (vd->cameraname, 32); snprintf (vd->videodevice, 12, "%s", device); if(debug) printf("video %s \n",vd->videodevice); memset (vd->cameraname, 0, sizeof (vd->cameraname)); memset(vd->bridge, 0, sizeof(vd->bridge)); vd->signalquit = 1; 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], sizeof(struct frame_t) + (size_t) vd->framesizeIn ); vd->framelock[i] = 0; } vd->frame_cour = 0; pthread_mutex_init (&vd->grabmutex, NULL); return err;}intclose_v4l (struct vdIn *vd){ int i; if (vd->grabMethod) { if(debug) printf ("unmapping frame buffer\n"); munmap (vd->pFramebuffer, vd->mmapsize); } else { free(vd->pFramebuffer); vd->pFramebuffer = NULL; } if(debug) printf ("close video_device\n"); 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; if(debug) printf ("freeing output buffer %d\n",i); } } pthread_mutex_destroy (&vd->grabmutex);}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 ){ static int frame = 0; int len; int size; int erreur = 0; int jpegsize = 0; struct frame_t *headerframe; double timecourant =0; double temps = 0; timecourant = ms_time(); 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 */ while((vd->framelock[vd->frame_cour] != 0) && vd->signalquit) usleep(1000); pthread_mutex_lock (&vd->grabmutex); /* memcpy (vd->ptframe[vd->frame_cour]+ sizeof(struct frame_t), vd->pFramebuffer + vd->videombuf.offsets[vd->vmmap.frame] , vd->framesizeIn); jpegsize =jpeg_compress(vd->ptframe[vd->frame_cour]+ sizeof(struct frame_t),vd->framesizeIn, vd->pFramebuffer + vd->videombuf.offsets[vd->vmmap.frame] ,vd->hdrwidth, vd->hdrheight, qualite); */ temps = ms_time(); jpegsize= convertframe(vd->ptframe[vd->frame_cour]+ sizeof(struct frame_t), vd->pFramebuffer + vd->videombuf.offsets[vd->vmmap.frame], vd->hdrwidth,vd->hdrheight,vd->formatIn,vd->framesizeIn); headerframe=(struct frame_t*)vd->ptframe[vd->frame_cour]; snprintf(headerframe->header,5,"%s","SPCA"); headerframe->seqtimes = ms_time(); headerframe->deltatimes=(int)(headerframe->seqtimes-timecourant); headerframe->w = vd->hdrwidth; headerframe->h = vd->hdrheight; headerframe->size = (( jpegsize < 0)?0:jpegsize); headerframe->format = vd->formatIn; headerframe->nbframe = frame++; // printf("compress frame %d times %f\n",frame, headerframe->seqtimes-temps); pthread_mutex_unlock (&vd->grabmutex); /************************************/ if ((ioctl (vd->fd, VIDIOCMCAPTURE, &(vd->vmmap))) < 0) { perror ("cmcapture"); if(debug) printf (">>cmcapture err \n"); erreur = -1; } vd->vmmap.frame = (vd->vmmap.frame + 1) % vd->videombuf.frames; vd->frame_cour = (vd->frame_cour +1) % OUTFRMNUMB; //if(debug) printf("frame nb %d\n",vd->vmmap.frame); } else { /* read method */ size = vd->framesizeIn; len = read (vd->fd, vd->pFramebuffer, size); if (len < 0 ) { if(debug) printf ("v4l read error\n"); if(debug) printf ("len %d asked %d \n", len, size); return 0; } /* Is there someone using the frame */ while((vd->framelock[vd->frame_cour] != 0)&& vd->signalquit) usleep(1000); pthread_mutex_lock (&vd->grabmutex); /* memcpy (vd->ptframe[vd->frame_cour]+ sizeof(struct frame_t), vd->pFramebuffer, vd->framesizeIn); jpegsize =jpeg_compress(vd->ptframe[vd->frame_cour]+ sizeof(struct frame_t),len, vd->pFramebuffer, vd->hdrwidth, vd->hdrheight, qualite); */ temps = ms_time(); jpegsize= convertframe(vd->ptframe[vd->frame_cour]+ sizeof(struct frame_t), vd->pFramebuffer , vd->hdrwidth,vd->hdrheight,vd->formatIn,vd->framesizeIn); headerframe=(struct frame_t*)vd->ptframe[vd->frame_cour]; snprintf(headerframe->header,5,"%s","SPCA"); headerframe->seqtimes = ms_time(); headerframe->deltatimes=(int)(headerframe->seqtimes-timecourant); headerframe->w = vd->hdrwidth; headerframe->h = vd->hdrheight; headerframe->size = (( jpegsize < 0)?0:jpegsize); headerframe->format = vd->formatIn; headerframe->nbframe = frame++; // if(debug) printf("compress frame %d times %f\n",frame, headerframe->seqtimes-temps); vd->frame_cour = (vd->frame_cour +1) % OUTFRMNUMB; pthread_mutex_unlock (&vd->grabmutex); /************************************/ } return erreur;}/****************************************************************************** Private******************************************************************************/static intGetVideoPict (struct vdIn *vd){ if (ioctl (vd->fd, VIDIOCGPICT, &vd->videopict) < 0) exit_fatal ("Couldnt get videopict params with VIDIOCGPICT"); if(debug) printf ("VIDIOCGPICT brightnes=%d hue=%d color=%d contrast=%d whiteness=%d" "depth=%d palette=%d\n", vd->videopict.brightness, vd->videopict.hue, vd->videopict.colour, vd->videopict.contrast, vd->videopict.whiteness, vd->videopict.depth, vd->videopict.palette); return 0;}static intSetVideoPict (struct vdIn *vd){ if (ioctl (vd->fd, VIDIOCSPICT, &vd->videopict) < 0) exit_fatal ("Couldnt set videopict params with VIDIOCSPICT"); if(debug) printf ("VIDIOCSPICT brightnes=%d hue=%d color=%d contrast=%d whiteness=%d" "depth=%d palette=%d\n", vd->videopict.brightness, vd->videopict.hue, vd->videopict.colour, vd->videopict.contrast, vd->videopict.whiteness, vd->videopict.depth, vd->videopict.palette); return 0;}static void spcaPrintParam (int fd,struct video_param *videoparam);static void spcaSetTimeInterval(int fd, struct video_param *videoparam, unsigned short dtime);static void spcaSetQuality(int fd, struct video_param *videoparam, unsigned char qindex);static intinit_v4l (struct vdIn *vd){ int f; int erreur = 0; 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"); if(debug) printf ("Camera found: %s \n", vd->videocap.name); snprintf (vd->cameraname, 32, "%s", vd->videocap.name); erreur = GetVideoPict (vd); if (ioctl (vd->fd, VIDIOCGCHAN, &vd->videochan) == -1) { if(debug) printf ("Hmm did not support Video_channel\n"); vd->cameratype = UNOW; } else { if (vd->videochan.name){ if(debug) printf ("Bridge found: %s \n", vd->videochan.name); snprintf (vd->bridge, 9, "%s", vd->videochan.name); vd->cameratype = GetStreamId (vd->videochan.name); spcaPrintParam (vd->fd,&vd->videoparam); } else { if(debug) printf ("Bridge not found not a spca5xx Webcam Probing the hardware !!\n"); vd->cameratype = UNOW; } }/* Only jpeg webcam allowed */if(vd->cameratype != JPEG) { exit_fatal ("Not a JPEG webcam sorry Abort !");} if(debug) printf ("StreamId: %d Camera\n", vd->cameratype);/* probe all available palette and size Not need on the FOX always jpeg if (probePalette(vd ) < 0) { exit_fatal ("could't probe video palette Abort !"); } if (probeSize(vd ) < 0) { exit_fatal ("could't probe video size Abort !"); } err = check_palettesize(vd); if(debug) printf (" Format asked %d check %d\n",vd->formatIn, err);*/ 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);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -