camv4l.c

Go to the documentation of this file.
00001 #include "camv4l.h"
00009 
00010 int PAL[] ={VIDEO_PALETTE_YUV420P,VIDEO_PALETTE_RGB565,VIDEO_PALETTE_RGB24,VIDEO_PALETTE_RGB32};
00011 
00012 #define LEN_PALLETE     4
00013 
00014 int SIZE[] = { 640,480,384,288,352,288,320,240,192,144,176,144,160,120 };
00015 
00016 
00017 
00018 
00019 
00020 static int GetVideoPict (struct vdIn *vd);
00021 
00022 static int SetVideoPict (struct vdIn *vd);
00023 
00024 static int GetDepth ( int format);
00025 
00026 static int probePalette ( struct vdIn *vd );
00027 
00028 static int probeSize ( struct vdIn *vd );       
00029 
00030 
00031 int init_v4l (struct vdIn *vd)
00032 {
00033         int f;
00034         int erreur = 0;
00035 
00036         if ((vd->fd = open (vd->videodevice, O_RDWR)) == -1){
00037       perror ("ERROR opening V4L interface \n");
00038       exit (1);
00039         }
00040         if (ioctl (vd->fd, VIDIOCGCAP, &(vd->videocap)) == -1){
00041       printf ("wrong device\n");
00042       exit (1);
00043         }
00044         printf ("Camera found: %s \n", vd->videocap.name);
00045         snprintf (vd->cameraname, 32, "%s", vd->videocap.name);
00046         
00047         erreur = GetVideoPict (vd);
00048         vd->formatIn = vd->videopict.palette;
00049         vd->bppIn = vd->videopict.depth;
00050         vd->flipUV = 0;
00051   
00052   /* To Compute the estimate frame size perhaps not need !!! 
00053   if ((vd->bppIn = GetDepth (vd->formatIn)) < 0)
00054     {
00055       perror ("getdepth  failed \n");
00056       exit (1);
00057     }
00058    */
00059         if (ioctl (vd->fd, VIDIOCGCHAN, &vd->videochan) == -1){
00060       printf ("did not support Video_channel\n");
00061       vd->cameratype = UNKNOW;
00062    } else {
00063       printf ("Bridge found: %s \n", vd->videochan.name);
00064       snprintf (vd->bridge, 9, "%s", vd->videochan.name);
00065       vd->cameratype = UNKNOW;// GetStreamId (vd->videochan.name);
00066         }
00067         
00068         if (vd->cameratype == UNKNOW){
00069         /* process others cams default parameters should be set */
00070                 printf ("StreamId: %d Unknow Camera\n", vd->cameratype);
00071                 printf("Probe Pallete\n");
00072                 if (probePalette (vd ) < 0) {
00073                         printf ("Sorry cannot probe Palette for that Unknow Camera\n");
00074                         exit (0);
00075                 }
00076                 printf("Probe Size\n");
00077                 if (probeSize (vd ) < 0) {
00078                         printf ("Sorry cannot probe Size for that Unknow Camera\n");
00079                         exit (0);
00080                 }
00081         } else {
00082                 printf("Find camera with supported bridge\n");
00083         }
00084 
00085         /**********************************************************/
00086         /*          alloc the frame buffer to read                */
00087         vd->framesizeIn = (vd->hdrwidth * vd->hdrheight * (vd->bppIn >> 3));
00088         /***************************            *******************/
00089         if (vd->grabMethod){
00090       printf (" grabbing method default MMAP asked \n");
00091       // MMAP VIDEO acquisition
00092       memset (&(vd->videombuf), 0, sizeof (vd->videombuf));
00093       if (ioctl (vd->fd, VIDIOCGMBUF, &(vd->videombuf)) < 0){
00094                         perror (" init VIDIOCGMBUF FAILED\n");
00095                 }
00096       
00097                 printf ("VIDIOCGMBUF size %d  frames %d  offets[0]=%d offsets[1]=%d\n",
00098                 vd->videombuf.size, vd->videombuf.frames,
00099                 vd->videombuf.offsets[0], vd->videombuf.offsets[1]);
00100 
00101       vd->pFramebuffer = (unsigned char *) mmap (0, vd->videombuf.size, PROT_READ | PROT_WRITE,MAP_SHARED, vd->fd, 0);
00102       vd->mmapsize = vd->videombuf.size;
00103       vd->vmmap.height = vd->hdrheight;
00104       vd->vmmap.width = vd->hdrwidth;
00105       vd->vmmap.format = vd->formatIn;
00106 
00107                 for (f = 0; f < vd->videombuf.frames; f++){
00108                         vd->vmmap.frame = f;
00109                         if (ioctl (vd->fd, VIDIOCMCAPTURE, &(vd->vmmap))){
00110                       perror ("cmcapture");
00111                         }
00112                 }
00113                 vd->vmmap.frame = 0;
00114                 
00115         } else {
00116       /* read method */
00117                 printf (" grabbing method READ asked \n");
00118       if (ioctl (vd->fd, VIDIOCGWIN, &(vd->videowin)) < 0){
00119                         perror ("VIDIOCGWIN failed \n");
00120                 }
00121       
00122                 vd->videowin.height = vd->hdrheight;
00123       vd->videowin.width = vd->hdrwidth;
00124       
00125                 if (ioctl (vd->fd, VIDIOCSWIN, &(vd->videowin)) < 0){
00126                         perror ("VIDIOCSWIN failed \n");
00127                 }
00128       printf ("VIDIOCSWIN height %d  width %d \n", vd->videowin.height, vd->videowin.width);
00129         }
00130 
00131         vd->pixTmp = (unsigned char *) malloc (vd->framesizeIn);
00132         
00133         return erreur;
00134 }
00135 
00136 
00137 int close_v4l (struct vdIn *vd){
00138         if (vd->grabMethod){
00139                 printf ("unmapping frame buffer\n");
00140       munmap (vd->pFramebuffer, vd->mmapsize);
00141         }
00142         printf ("freeing frame buffer\n");
00143         free (vd->pixTmp);
00144         
00145         printf ("close v4l \n");
00146         close (vd->fd);
00147         return 0;
00148 }
00149 
00150 
00151 static void flipUV (unsigned char *src, int format, int w, int h){
00152         __u32 *lpix;
00153         __u16 *pix;
00154         __u8 *V;
00155         __u8 *U;
00156         __u8 *savC = NULL;
00157         unsigned char tmp;
00158         int sizetransfert = 0;
00159         int i;
00160 
00161         if (format == VIDEO_PALETTE_RAW_JPEG){
00162       /*nothing todo */
00163       return;
00164         }
00165 
00166         switch (format){
00167     case VIDEO_PALETTE_YUV420P:{
00168                 /* allocate a helper buffer */
00169                 sizetransfert = (w * h >> 2);
00170                 savC = (__u8 *) realloc (savC, (size_t) sizetransfert);
00171                 U = src + (w * h);
00172                 V = src + (w * h) + sizetransfert;
00173                 /* save U */
00174                 memcpy (savC, U, sizetransfert);
00175                 /* flip UV */
00176                 memcpy (U, V, sizetransfert);
00177                 /* restore U */
00178                 memcpy (V, savC, sizetransfert);
00179                 free (savC);
00180                 savC = NULL;
00181                 }
00182       break;
00183         case VIDEO_PALETTE_RGB565: {
00184                 pix = (__u16 *) src;
00185                 for (i = 0; i < (w * h); i++){
00186                         pix[i] = (((pix[i] & 0xF800) >> 11) | ((pix[i] & 0x001F) << 11) | (pix[i] & 0x07E0));
00187                 }
00188         }
00189       break;
00190    case VIDEO_PALETTE_RGB24:{
00191                 for (i = 0; i < (w * h * 3); i += 3){
00192                         tmp = src[i];
00193                         src[i] = src[i + 2];
00194                         src[i + 2] = tmp;
00195                 }
00196    }
00197       break;
00198    case VIDEO_PALETTE_RGB32:{
00199                 lpix = (__u32 *) src;
00200                 for (i = 0; i < (w * h); i++){
00201                     lpix[i] = (((lpix[i] & 0x00FF0000) >> 16) | ((lpix[i] & 0x000000FF) << 16)
00202                | (lpix[i] & 0x0000FF00));
00203                 }
00204    }
00205       break;
00206    default:
00207          break;
00208   }
00209 }
00210 
00211 
00212 int grab (struct vdIn *vd){
00213         int ff;
00214         int len;
00215         int status=0;
00216         //int count = 0;
00217         int size;
00218         int erreur = 0;
00219 
00220         if (vd->grabMethod){
00221       ff = vd->vmmap.frame;
00222       vd->vmmap.height = vd->hdrheight;
00223       vd->vmmap.width = vd->hdrwidth;
00224       vd->vmmap.format = vd->formatIn;
00225       if (ioctl (vd->fd, VIDIOCSYNC, &ff) < 0){
00226                         perror ("cvsync err\n");
00227                         erreur = -1;
00228                 }
00229       vd->vmmap.frame = ff;
00230       memcpy (vd->pixTmp,vd->pFramebuffer + vd->videombuf.offsets[vd->vmmap.frame], vd->framesizeIn);
00231 
00232       if (vd->flipUV){
00233                         printf("Flip UV\n");
00234                         flipUV (vd->pixTmp, vd->formatIn, vd->hdrwidth, vd->hdrheight);
00235                 }
00236 
00237       if ((ioctl (vd->fd, VIDIOCMCAPTURE, &(vd->vmmap))) < 0){
00238                         perror ("cmcapture");
00239                         printf (">>cmcapture err %d\n", status);
00240                         erreur = -1;
00241                 }
00242       vd->vmmap.frame = (vd->vmmap.frame + 1) % vd->videombuf.frames;
00243       //printf("frame nb %d\n",vd->vmmap.frame);
00244         } else {
00245       /* read method */
00246       size = vd->framesizeIn;
00247       len = read (vd->fd, vd->pixTmp, size);
00248       if (len != size){
00249                         printf ("v4l read error\n");
00250                         printf ("len %d asked %d \n", len, size);
00251                         erreur = -1;
00252                 }
00253       if (vd->flipUV){
00254                         flipUV (vd->pixTmp, vd->formatIn, vd->hdrwidth, vd->hdrheight);
00255                 }
00256         }
00257         return erreur;
00258 }
00259 
00260 int setPalette (struct vdIn *vd)
00261 {
00262         vd->bppIn = GetDepth (vd->formatIn);
00263         vd->videopict.palette = vd->formatIn;
00264         vd->videopict.depth = vd->bppIn;
00265         SetVideoPict (vd);
00266         vd->framesizeIn = ((vd->hdrwidth * vd->hdrheight * vd->bppIn) >> 3);
00267         vd->pixTmp = (unsigned char *) realloc (vd->pixTmp, (size_t) vd->framesizeIn);
00268 
00269         return 1;
00270 }
00271 
00272 /* probe palette and set a default one for unknow cams*/
00273 static int probePalette ( struct vdIn *vd )
00274 {
00275         struct video_picture pict;
00276         int masq = 0x2;
00277         int i;
00278         int availpal = 0;
00279         int defaut = 1;
00280         /* initialize the internal struct */
00281         if (ioctl (vd->fd, VIDIOCGPICT, &pict) < 0)
00282                 {
00283                 perror ("Couldnt get videopict params with VIDIOCGPICT\n");
00284                 return -1;
00285                  }
00286         /* try each palette we have we skip raw_jpeg */
00287         for(i = 0; i < LEN_PALLETE ; i++){
00288                 pict.palette = PAL[i];
00289                 /* maybe correct the bug on qca driver depth always 24 ? */     
00290                 pict.depth = GetDepth (PAL[i]);
00291                 printf("try palette %d depth %d\n",pict.palette,pict.depth);
00292                 if (ioctl (vd->fd, VIDIOCSPICT, &pict) < 0){
00293                         printf("Couldn't set palette first try %d \n", PAL[i]);
00294                 }
00295                 if (ioctl (vd->fd, VIDIOCGPICT, &pict) < 0){
00296                 printf("Couldnt get palette %d \n", PAL[i]);
00297         }
00298                 if (pict.palette != PAL[i]){
00299                         printf("Damned second try fail \n");    
00300                 }
00301                 else {
00302                         availpal = availpal | masq ;
00303                         printf("Available  palette %d \n", PAL[i]);
00304                         if (defaut){
00305                                 defaut = 0;
00306                                 vd->formatIn = PAL[i];
00307                                 vd->bppIn = GetDepth (PAL[i]);
00308                         }
00309                 }
00310                 masq = masq << 1;
00311         }
00312         vd->palette = availpal;
00313         printf("Vybrana paleta je %d\n",availpal);
00314         //should set default palette here ?
00315         return 1;       
00316 }
00317 
00318 
00319 /* probe size and set a default one for unknow cams */
00320 static int probeSize ( struct vdIn *vd )
00321 {
00322         struct video_window win;
00323         int maxw,minw,maxh,minh;
00324         int masq = 0x1;
00325         int i = 0;
00326         int defaut = 1 ;
00327         /* initialize de parameters */
00328         maxw = vd->videocap.maxwidth;
00329         minw = vd->videocap.minwidth;
00330         maxh = vd->videocap.maxheight;
00331         minh = vd->videocap.minheight;
00332         printf("probe size in \n");
00333 
00334         while (SIZE[i] > maxw){
00335                 printf("skip size %d x %d\n",SIZE[i],SIZE[i+1]);
00336                 i += 2;
00337                 masq = masq << 1;
00338                 if (i > 13) break;
00339         }
00340         /* initialize the internal struct */
00341         if (ioctl (vd->fd, VIDIOCGWIN, &win) < 0) {
00342                 perror ("VIDIOCGWIN failed \n");
00343                 return -1;
00344         }
00345         /* now i is on the first possible width */
00346         while ((SIZE[i] >= minw) && i < 13) {
00347                 win.width = SIZE[i];
00348                 win.height = SIZE[i+1];
00349                 if (ioctl (vd->fd, VIDIOCSWIN, &win) < 0) {
00350                 printf ("VIDIOCSWIN reject width %d  height %d \n",
00351                         win.width, win.height);       
00352         } else {
00353                         vd->sizeothers = vd->sizeothers | masq;
00354                         printf ("Available Resolutions width %d  heigth %d \n",
00355                         win.width, win.height);
00356                         if (defaut){
00357                                 vd->hdrwidth = win.width;
00358                                 vd->hdrheight = win.height;
00359                                 defaut = 0;
00360                         }
00361                 }
00362                 masq = masq << 1 ;
00363                 i += 2;
00364         }
00365         return 1;       
00366 }
00367 
00368 int changeSize (struct vdIn *vd)
00369 {
00370         int erreur;
00371         erreur = GetVideoPict (vd);
00372         vd->formatIn = vd->videopict.palette;
00373         vd->bppIn = vd->videopict.depth;
00374         /* To Compute the estimate frame size perhaps not need !!! */
00375         if ((vd->bppIn = GetDepth (vd->formatIn)) < 0){
00376                 perror ("getdepth  failed \n");
00377       exit (1);
00378         }
00379         if (vd->grabMethod){
00380       vd->vmmap.height = vd->hdrheight;
00381       vd->vmmap.width = vd->hdrwidth;
00382       vd->vmmap.format = vd->formatIn;
00383    } else {
00384                 if (ioctl (vd->fd, VIDIOCGWIN, &vd->videowin) < 0)
00385                         perror ("VIDIOCGWIN failed \n");
00386       vd->videowin.height = vd->hdrheight;
00387       vd->videowin.width = vd->hdrwidth;
00388       if (ioctl (vd->fd, VIDIOCSWIN, &vd->videowin) < 0)
00389                         perror ("VIDIOCSWIN failed \n");
00390 
00391       printf ("VIDIOCGWIN height %d  width %d \n",vd->videowin.height, vd->videowin.width);
00392    }
00393         vd->framesizeIn = ((vd->hdrwidth * vd->hdrheight * vd->bppIn) >> 3);
00394         vd->pixTmp =
00395    (unsigned char *) realloc (vd->pixTmp, (size_t) vd->framesizeIn);
00396         return 1;
00397 }
00398 
00399 
00400 static int GetVideoPict (struct vdIn *vd)
00401 {
00402   if (ioctl (vd->fd, VIDIOCGPICT, &vd->videopict) < 0){
00403       perror ("Couldnt get videopict params with VIDIOCGPICT\n");
00404       return -1;
00405   }
00406 
00407   printf ("VIDIOCGPICT brightnes=%d hue=%d color=%d contrast=%d whiteness=%d"
00408           "depth=%d palette=%d\n", vd->videopict.brightness,
00409           vd->videopict.hue, vd->videopict.colour, vd->videopict.contrast,
00410           vd->videopict.whiteness, vd->videopict.depth,
00411           vd->videopict.palette);
00412 
00413   return 0;
00414 }
00415 
00416 static int SetVideoPict (struct vdIn *vd)
00417 {
00418         if (ioctl (vd->fd, VIDIOCSPICT, &vd->videopict) < 0){
00419       perror ("Couldnt set videopict params with VIDIOCSPICT\n");
00420       return -1;
00421         }
00422         
00423         printf ("VIDIOCSPICT brightnes=%d hue=%d color=%d contrast=%d whiteness=%d"
00424           "depth=%d palette=%d\n", vd->videopict.brightness,
00425           vd->videopict.hue, vd->videopict.colour, vd->videopict.contrast,
00426           vd->videopict.whiteness, vd->videopict.depth,
00427           vd->videopict.palette);
00428 
00429   return 0;
00430 }
00431 
00432 static int GetDepth(int format)
00433 {
00434   int depth;
00435   switch (format)
00436     {
00437     case VIDEO_PALETTE_RAW_JPEG:
00438       {
00439         depth = 8;              // be sure spca50x ask raw data
00440       }
00441       break;
00442     case VIDEO_PALETTE_YUV420P:
00443       {
00444         depth = (8 * 3) >> 1;
00445       }
00446       break;
00447     case VIDEO_PALETTE_RGB565:
00448       depth = 16;
00449       break;
00450     case VIDEO_PALETTE_RGB24:
00451       depth = 24;
00452       break;
00453     case VIDEO_PALETTE_RGB32:
00454       {
00455         depth = 32;
00456       }
00457       break;
00458     default:
00459       depth = -1;
00460       break;
00461     }
00462   return depth;
00463 }
00464 
00465 __u8 getBrightness (struct vdIn * vdin)
00466 {
00467   if (GetVideoPict (vdin) < 0)
00468     {
00469       printf (" Error getBrightness \n");
00470       return 0;
00471     }
00472   return ((vdin->videopict.brightness) >> 8);
00473 }
00474 
00475 void setBrightness (struct vdIn *vdin, __u8 bright)
00476 {
00477   vdin->videopict.brightness = bright << 8;
00478   if (SetVideoPict (vdin) < 0)
00479     {
00480       printf (" Error setBrightness \n");
00481     }
00482 
00483 }
00484 
00485 __u8 getContrast (struct vdIn *vdin)
00486 {
00487   if (GetVideoPict (vdin) < 0)
00488     {
00489       printf (" Error getContrast \n");
00490       return 0;
00491     }
00492   return ((vdin->videopict.contrast) >> 8);
00493 }
00494 
00495 void setContrast (struct vdIn *vdin, __u8 contrast)
00496 {
00497   vdin->videopict.contrast = contrast << 8;
00498   if (SetVideoPict (vdin) < 0)
00499     {
00500       printf (" Error setContrast \n");
00501     }
00502 }
00503 __u8 getColors (struct vdIn *vdin)
00504 {
00505   if (GetVideoPict (vdin) < 0)
00506     {
00507       printf (" Error getColors \n");
00508       return 0;
00509     }
00510   return ((vdin->videopict.colour) >> 8);
00511 }
00512 
00513 void setColors (struct vdIn *vdin, __u8 colors)
00514 {
00515   vdin->videopict.colour = colors << 8;
00516   if (SetVideoPict (vdin) < 0)
00517     {
00518       printf (" Error setColors \n");
00519     }
00520 }

Generated on Mon Jan 26 20:51:50 2009 for Camera grab convert to MPEG by  doxygen 1.5.1