grab_v4l_c.c

Go to the documentation of this file.
00001 /* Gnome gxsm - Gnome X Scanning Microscopy
00002  * universal STM/AFM/SARLS/SPALEED/... controlling and
00003  * data analysis software
00004  *
00005  * Gxsm Hardware Interface Plugin Name: grab_v4l.C
00006  * ===============================================
00007  * 
00008  * Copyright (C) 1999 The Free Software Foundation
00009  *
00010  * Authors: Percy Zahl <zahl@fkp.uni-hannover.de>
00011  * additional features: Andreas Klust <klust@fkp.uni-hannover.de>
00012  *
00013  * This program is free software; you can redistribute it and/or modify
00014  * it under the terms of the GNU General Public License as published by
00015  * the Free Software Foundation; either version 2 of the License, or
00016  * (at your option) any later version.
00017  *
00018  * This program is distributed in the hope that it will be useful,
00019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  * GNU General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU General Public License
00024  * along with this program; if not, write to the Free Software
00025  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00026  */
00027 
00028 /* irnore this module for docuscan
00029 % PlugInModuleIgnore
00030  */
00031 
00032 
00033 #include "config.h"
00034 #include <stdio.h>
00035 #include <stdlib.h>
00036 #include <glib.h>
00037 #include <string.h>
00038 #include <sys/types.h>
00039 
00040 #include <unistd.h>
00041 #include <linux/videodev.h>
00042 #include <sys/ioctl.h>
00043 #include <sys/mman.h>
00044 #include <sys/types.h>
00045 #include <sys/stat.h>
00046 #include <time.h>
00047 #include <fcntl.h>
00048 #include <signal.h>
00049 #include <linux/types.h> 
00050 #include <linux/videodev.h>
00051 #include <errno.h>
00052 
00053 /*
00054  * GXSM V4L Hardware Interface Class -- plain c module
00055  * ============================================================
00056  */
00057 
00058 gint gxsm_v4l_open_video4l ();
00059 gint gxsm_v4l_close_video4l ();
00060 gint gxsm_v4l_maxwidth  ();
00061 gint gxsm_v4l_maxheight ();
00062 gint gxsm_v4l_win_width  ();
00063 gint gxsm_v4l_win_height ();
00064 gint gxsm_v4l_grab_video4l ();
00065 gint gxsm_v4l_get_pixel (int *r, int *g, int *b);
00066 
00067 int    video_dev_fd=0;
00068 struct video_capability cap;
00069 struct video_picture pic;
00070 struct video_window win;
00071 struct video_capture vicap;
00072 struct video_channel vidcan;
00073 struct video_mbuf vidbuf;
00074 struct video_buffer buffer;
00075 struct video_mmap mapbuf;
00076 guchar *bigbuf;
00077 guchar *buf;
00078 int gray[3];
00079 guchar  *src;
00080 
00081 
00082 gint gxsm_v4l_open_video4l (){
00083 //    struct v4l2_capability v4l2_cap;
00084 //    struct v4l2_requestbuffers reqbuf;
00085     struct {
00086         void *start;
00087         size_t length;
00088     } *buffers;
00089     unsigned int i;
00090 //-------------------------------------------------------------------
00091               /* OPEN VIDEO DEVICE */
00092 //-------------------------------------------------------------------   
00093         
00094         video_dev_fd = open("/dev/video", O_RDWR );
00095 
00096         if (video_dev_fd<0){
00097                 printf("ERROR: THERE IS NO CAMERA CONECTED\n");
00098                 exit(-1);
00099         }
00100 
00101 //--------------------------------------------------------------------
00102                 /* VIDEO CAPABILITIES*/
00103 //---------------------------------------------------------------------
00104 
00105         if (-1==ioctl(video_dev_fd,VIDIOCGCAP,&cap)){
00106                 perror("ioctl VIDIOCGCAP");
00107                 exit(-1);
00108         }
00109         printf("------------------------------------\n");
00110         printf("------------------------------------\n");
00111         printf("name      -> %s\n", cap.name);
00112         printf("type      -> %d\n", cap.type);
00113         printf("channels  -> %d\n", cap.channels);
00114         printf("audios    -> %d\n", cap.audios );
00115         printf("maxwidth  -> %d\n", cap.maxwidth );
00116         printf("maxheight -> %d\n", cap.maxheight);
00117         printf("minwidth  -> %d\n", cap.minwidth );
00118         printf("minheight -> %d\n", cap.minheight );
00119         printf("------------------------------------\n");
00120 
00121 //---------------------------------------------------------------------
00122                 /* FRAME GRABBERS DETECTION*/
00123 //---------------------------------------------------------------------
00124 
00125         if (-1==ioctl(video_dev_fd,VIDIOCSFBUF,&buffer))
00126                 printf ("Not a decteced frame grabber\n");
00127         else {
00128  
00129                 if (-1==ioctl(video_dev_fd,VIDIOCGFBUF,&buffer)) {
00130                         perror ("ioctl VIDIOCGFBUF");
00131                         exit(-1);
00132                 }
00133                 printf("------------------------------------\n"); 
00134                 printf ("add -> %d\n", buffer.base);
00135                 printf ("height -> %d\n", buffer.height);
00136                 printf ("width -> %d\n", buffer.width);
00137                 printf ("depth -> %d\n", buffer.depth);
00138                 printf ("BPL -> %d\n", buffer.bytesperline);
00139         }
00140         printf("------------------------------------\n");                                       
00141 
00142 /*
00143         reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00144         reqbuf.memory = V4L2_MEMORY_MMAP;
00145         reqbuf.count = 20;
00146 
00147         if (-1 == ioctl (video_dev_fd, VIDIOC_REQBUFS, &reqbuf)) {
00148             if (errno == EINVAL)
00149                 printf ("Video capturing or mmap-streaming is not supported\n");
00150             else
00151                 perror ("ioctl VIDIOC_REQBUFS");
00152 
00153             //      exit (EXIT_FAILURE);
00154         }
00155 
00156         if (-1 == ioctl (video_dev_fd, VIDIOC_QUERYCAP, &v4l2_cap)) {
00157             if (errno == EINVAL)
00158                 printf ("not supported request by kernel\n");
00159             else
00160                 perror ("ioctl V4L2 VIDIOC_QUERYCAP");
00161         } else {
00162             printf("------------------------------------\n");
00163             printf("v4l2 driver    -> %s\n", v4l2_cap.driver);
00164             printf("v4l2 card      -> %s\n", v4l2_cap.card);
00165             printf("v4l2 bus info  -> %s\n", v4l2_cap.bus_info);
00166             printf("v4l2 driver    -> %s\n", v4l2_cap.driver);
00167             printf("v4l2 version   -> %06X\n", v4l2_cap.version);
00168             printf("v4l2 capabilities -> %X\n", v4l2_cap.capabilities);
00169             printf("---| V4L2_CAP_VIDEO_CAPTURE .. %s\n", v4l2_cap.capabilities&V4L2_CAP_VIDEO_CAPTURE ? "Yes":"No");
00170             printf("   | V4L2_CAP_VIDEO_OUTPUT ... %s\n", v4l2_cap.capabilities&V4L2_CAP_VIDEO_OUTPUT ? "Yes":"No");
00171             printf("   | V4L2_CAP_VIDEO_OVERLAY .. %s\n", v4l2_cap.capabilities&V4L2_CAP_VIDEO_OVERLAY ? "Yes":"No");
00172             printf("   | V4L2_CAP_VBI_CAPTURE .... %s\n", v4l2_cap.capabilities&V4L2_CAP_VBI_CAPTURE ? "Yes":"No");
00173             printf("   | V4L2_CAP_VBI_OUTPUT... .. %s\n", v4l2_cap.capabilities&V4L2_CAP_VBI_OUTPUT ? "Yes":"No");
00174             printf("   | V4L2_CAP_TUNER .......... %s\n", v4l2_cap.capabilities&V4L2_CAP_TUNER ? "Yes":"No");
00175             printf("   | V4L2_CAP_AUDIO .......... %s\n", v4l2_cap.capabilities&V4L2_CAP_AUDIO ? "Yes":"No");
00176             printf("   | V4L2_CAP_READWRITE ...... %s\n", v4l2_cap.capabilities&V4L2_CAP_READWRITE ? "Yes":"No");
00177             printf("   | V4L2_CAP_ASYNCIO ........ %s\n", v4l2_cap.capabilities&V4L2_CAP_ASYNCIO ? "Yes":"No");
00178             printf("   | V4L2_CAP_STREAMING ...... %s\n", v4l2_cap.capabilities&V4L2_CAP_STREAMING ? "Yes":"No");
00179             printf("------------------------------------\n");
00180         }
00181 */
00182 
00183         return 0;
00184 }
00185 
00186 gint gxsm_v4l_close_video4l (){
00187         close (video_dev_fd);
00188         video_dev_fd = 0;
00189         return 0;
00190 }
00191 
00192 inline gint gxsm_v4l_maxwidth  () { return cap.maxwidth; }
00193 inline gint gxsm_v4l_maxheight () { return cap.maxheight; }
00194 
00195 inline gint gxsm_v4l_win_width  () { return win.width; }
00196 inline gint gxsm_v4l_win_height () { return win.height; }
00197 
00198 gint gxsm_v4l_grab_video4l (){ 
00199 
00200         int frame;
00201         int i;
00202 
00203 //-----------------------------------------------------------------------
00204                 /* CAPTURE FRAME */
00205 //-----------------------------------------------------------------------
00206 
00207 /*
00208         win.x = 0;
00209         win.y = 0;
00210         win.width = COLS;
00211         win.height = ROWS;
00212         win.clipcount = 0;
00213         win.chromakey = 1;
00214         win.flags = VIDEO_CLIPMAP_SIZE;
00215         
00216         if (-1== ioctl(video_dev_fd, VIDIOCSWIN,&win)){
00217                 perror ("ioctl VIDIOCSWIN");
00218                 exit (-1);
00219         }
00220 */
00221         if (ioctl(video_dev_fd, VIDIOCGWIN, &win) < 0) {
00222                 perror("ioctl VIDIOCGWIN");
00223                 close (video_dev_fd);
00224                 exit(1);
00225         }       
00226 
00227         fprintf(stderr, "V4L Window [%d x %d]...\n", win.width, win.height);
00228 
00229 //---------------------------------------------------------------------
00230                 /* IMAGE PROPERTIES*/
00231 //---------------------------------------------------------------------
00232 
00233         pic.depth = 24;
00234         pic.palette = VIDEO_PALETTE_RGB24;
00235         pic.brightness = 100;
00236         pic.contrast = 30;
00237         pic.whiteness = 0;
00238         pic.colour = 0;
00239         pic.hue = 0;
00240         
00241         
00242         if (-1==ioctl( video_dev_fd, VIDIOCSPICT, &pic )){perror("ioctl VIDIOCSPICT");
00243                 exit(-1);}
00244         
00245         ioctl( video_dev_fd, VIDIOCGPICT, &pic );
00246 
00247         printf("------------------------------------\n");
00248         printf("brightness -> %d \n", pic.brightness/256 );
00249         printf("hue -> %d\n", pic.hue/256);
00250         printf("colour -> %d\n", pic.colour/256 );
00251         printf("contrast -> %d \n", pic.contrast/256 );
00252         printf("whiteness -> %d\n", pic.whiteness/256 );
00253         printf("depth -> %d\n", pic.depth );
00254         printf("palette -> %d \n", pic.palette );
00255         printf("------------------------------------\n");
00256 
00257 //-----------------------------------------------------------------------
00258                 /* MAPPING BUFFER */
00259 //------------------------------------------------------------------------
00260 
00261 
00262         if (-1==ioctl(video_dev_fd,VIDIOCGMBUF,&vidbuf)){
00263                 perror("ioctl VIDIOCGMBUF"); 
00264                 exit(-1);
00265         }
00266         
00267         printf("------------------------------------\n");
00268         printf("size  -> %d\n",vidbuf.size);
00269         printf("frames -> %d\n",vidbuf.frames);
00270         printf("offsets -> %d\n",vidbuf.offsets);
00271         printf("------------------------------------\n");
00272 
00273         bigbuf = (guchar *)mmap(0,vidbuf.size, PROT_READ | PROT_WRITE, MAP_SHARED, video_dev_fd, 0);
00274 
00275 
00276         mapbuf.width  = win.width;
00277         mapbuf.height = win.height;
00278         mapbuf.format = VIDEO_PALETTE_RGB24;
00279 
00280 
00281 //----------------------------------------------------------------------
00282                     /* SET BUFFERS*/
00283 //----------------------------------------------------------------------                 
00284 
00285         for(frame=0; frame<vidbuf.frames;frame++){                                      // turn on both of the buffers
00286                 mapbuf.frame = frame;                                                   // to start capture process.
00287                 if (ioctl(video_dev_fd,VIDIOCMCAPTURE, &mapbuf)<0){                             // Now they can store images.
00288                         perror("VIDIOCMCAPTURE");
00289                         exit(-1);}
00290                 }
00291         
00292         frame = 0;
00293 
00294     
00295 //---------------------------------------------------------------------
00296                        /* CAPTURING*/
00297 //---------------------------------------------------------------------         
00298 
00299         while (1){
00300                 i = -1;
00301                 while(i<0){
00302         
00303                         i= ioctl(video_dev_fd,VIDIOCSYNC, &frame);                              // Wait until the actual buffer
00304                         if(i < 0 && errno == EINTR) continue;                           // is full. When it happends 
00305                         if (i < 0) {                                                    // it start to capture to       
00306                                 perror ("VIDIOCSYNC");                                  // the other buffer.
00307                                 exit(-1);
00308                         }
00309                 }
00310                 break;
00311         }
00312 
00313 
00314         buf = bigbuf + vidbuf.offsets[frame];
00315         mapbuf.frame = frame;
00316                                                 
00317         if (ioctl(video_dev_fd,VIDIOCMCAPTURE, &mapbuf)<0) {
00318                 perror("VIDIOCMCAPTURE");               // Turn on the buffer that
00319                 exit(-1);
00320         }                                                               // was being used.
00321 
00322         frame++;
00323 
00324 
00325         if (frame>=vidbuf.frames) frame=0;
00326 
00327         src = buf;
00328 
00329         return 0;
00330 }
00331 
00332 #define READ_VIDEO_PIXEL(buf, format, depth, r, g, b)                   \
00333 {                                                                       \
00334         switch (format)                                                 \
00335         {                                                               \
00336                 case VIDEO_PALETTE_GREY:                                \
00337                         switch (depth)                                  \
00338                         {                                               \
00339                                 case 4:                                 \
00340                                 case 6:                                 \
00341                                 case 8:                                 \
00342                                         (r) = (g) = (b) = (*buf++ << 8);\
00343                                         break;                          \
00344                                                                         \
00345                                 case 16:                                \
00346                                         (r) = (g) = (b) =               \
00347                                                 *((unsigned short *) buf);      \
00348                                         buf += 2;                       \
00349                                         break;                          \
00350                         }                                               \
00351                         break;                                          \
00352                                                                         \
00353                                                                         \
00354                 case VIDEO_PALETTE_RGB565:                              \
00355                 {                                                       \
00356                         unsigned short tmp = *(unsigned short *)buf;    \
00357                         (r) = tmp&0xF800;                               \
00358                         (g) = (tmp<<5)&0xFC00;                          \
00359                         (b) = (tmp<<11)&0xF800;                         \
00360                         buf += 2;                                       \
00361                 }                                                       \
00362                 break;                                                  \
00363                                                                         \
00364                 case VIDEO_PALETTE_RGB555:                              \
00365                         (r) = (buf[0]&0xF8)<<8;                         \
00366                         (g) = ((buf[0] << 5 | buf[1] >> 3)&0xF8)<<8;    \
00367                         (b) = ((buf[1] << 2 ) & 0xF8)<<8;               \
00368                         buf += 2;                                       \
00369                         break;                                          \
00370                                                                         \
00371                 case VIDEO_PALETTE_RGB24:                               \
00372                         (r) = buf[0] << 8; (g) = buf[1] << 8;           \
00373                         (b) = buf[2] << 8;                              \
00374                         buf += 3;                                       \
00375                         break;                                          \
00376                                                                         \
00377                 default:                                                \
00378                         fprintf(stderr,                                 \
00379                                 "Format %d not yet supported\n",        \
00380                                 format);                                \
00381         }                                                               \
00382 }                                               
00383 
00384 inline gint gxsm_v4l_get_pixel (int *r, int *g, int *b){
00385         READ_VIDEO_PIXEL(src, pic.palette, pic.depth, *r, *g, *b);
00386         return (*r + *g + *b);
00387 }
00388 
00389 

Generated on Sat Apr 1 09:04:15 2006 for GXSM by  doxygen 1.4.6