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
00053
00054
00055
00056
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;
00066 }
00067
00068 if (vd->cameratype == UNKNOW){
00069
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
00087 vd->framesizeIn = (vd->hdrwidth * vd->hdrheight * (vd->bppIn >> 3));
00088
00089 if (vd->grabMethod){
00090 printf (" grabbing method default MMAP asked \n");
00091
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
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
00163 return;
00164 }
00165
00166 switch (format){
00167 case VIDEO_PALETTE_YUV420P:{
00168
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
00174 memcpy (savC, U, sizetransfert);
00175
00176 memcpy (U, V, sizetransfert);
00177
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
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
00244 } else {
00245
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
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
00281 if (ioctl (vd->fd, VIDIOCGPICT, &pict) < 0)
00282 {
00283 perror ("Couldnt get videopict params with VIDIOCGPICT\n");
00284 return -1;
00285 }
00286
00287 for(i = 0; i < LEN_PALLETE ; i++){
00288 pict.palette = PAL[i];
00289
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
00315 return 1;
00316 }
00317
00318
00319
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
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
00341 if (ioctl (vd->fd, VIDIOCGWIN, &win) < 0) {
00342 perror ("VIDIOCGWIN failed \n");
00343 return -1;
00344 }
00345
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
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;
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 }