Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /* Simple Video4Linux image grabber. */
  2 /*
  3  *      Video4Linux Driver Test/Example Framegrabbing Program
  4  *
  5  *      Compile with:
  6  *              gcc -s -Wall -Wstrict-prototypes v4lgrab.c -o v4lgrab
  7  *      Use as:
  8  *              v4lgrab >image.ppm
  9  *
 10  *      Copyright (C) 1998-05-03, Phil Blundell <philb@gnu.org>
 11  *      Copied from http://www.tazenda.demon.co.uk/phil/vgrabber.c
 12  *      with minor modifications (Dave Forrest, drf5n@virginia.edu).
 13  *
 14  *
 15  *      For some cameras you may need to pre-load libv4l to perform
 16  *      the necessary decompression, e.g.:
 17  *
 18  *      export LD_PRELOAD=/usr/lib/libv4l/v4l1compat.so
 19  *      ./v4lgrab >image.ppm
 20  *
 21  *      see http://hansdegoede.livejournal.com/3636.html for details.
 22  *
 23  */
 24 
 25 #include <unistd.h>
 26 #include <sys/types.h>
 27 #include <sys/stat.h>
 28 #include <fcntl.h>
 29 #include <stdio.h>
 30 #include <sys/ioctl.h>
 31 #include <stdlib.h>
 32 
 33 #include <linux/types.h>
 34 #include <linux/videodev.h>
 35 
 36 #define VIDEO_DEV "/dev/video0"
 37 
 38 /* Stole this from tvset.c */
 39 
 40 #define READ_VIDEO_PIXEL(buf, format, depth, r, g, b)                   \
 41 {                                                                       \
 42         switch (format)                                                 \
 43         {                                                               \
 44                 case VIDEO_PALETTE_GREY:                                \
 45                         switch (depth)                                  \
 46                         {                                               \
 47                                 case 4:                                 \
 48                                 case 6:                                 \
 49                                 case 8:                                 \
 50                                         (r) = (g) = (b) = (*buf++ << 8);\
 51                                         break;                          \
 52                                                                         \
 53                                 case 16:                                \
 54                                         (r) = (g) = (b) =               \
 55                                                 *((unsigned short *) buf);      \
 56                                         buf += 2;                       \
 57                                         break;                          \
 58                         }                                               \
 59                         break;                                          \
 60                                                                         \
 61                                                                         \
 62                 case VIDEO_PALETTE_RGB565:                              \
 63                 {                                                       \
 64                         unsigned short tmp = *(unsigned short *)buf;    \
 65                         (r) = tmp&0xF800;                               \
 66                         (g) = (tmp<<5)&0xFC00;                          \
 67                         (b) = (tmp<<11)&0xF800;                         \
 68                         buf += 2;                                       \
 69                 }                                                       \
 70                 break;                                                  \
 71                                                                         \
 72                 case VIDEO_PALETTE_RGB555:                              \
 73                         (r) = (buf[0]&0xF8)<<8;                         \
 74                         (g) = ((buf[0] << 5 | buf[1] >> 3)&0xF8)<<8;    \
 75                         (b) = ((buf[1] << 2 ) & 0xF8)<<8;               \
 76                         buf += 2;                                       \
 77                         break;                                          \
 78                                                                         \
 79                 case VIDEO_PALETTE_RGB24:                               \
 80                         (r) = buf[0] << 8; (g) = buf[1] << 8;           \
 81                         (b) = buf[2] << 8;                              \
 82                         buf += 3;                                       \
 83                         break;                                          \
 84                                                                         \
 85                 default:                                                \
 86                         fprintf(stderr,                                 \
 87                                 "Format %d not yet supported\n",        \
 88                                 format);                                \
 89         }                                                               \
 90 }
 91 
 92 int get_brightness_adj(unsigned char *image, long size, int *brightness) {
 93   long i, tot = 0;
 94   for (i=0;i<size*3;i++)
 95     tot += image[i];
 96   *brightness = (128 - tot/(size*3))/3;
 97   return !((tot/(size*3)) >= 126 && (tot/(size*3)) <= 130);
 98 }
 99 
100 int main(int argc, char ** argv)
101 {
102   int fd = open(VIDEO_DEV, O_RDONLY), f;
103   struct video_capability cap;
104   struct video_window win;
105   struct video_picture vpic;
106 
107   unsigned char *buffer, *src;
108   int bpp = 24, r = 0, g = 0, b = 0;
109   unsigned int i, src_depth = 16;
110 
111   if (fd < 0) {
112     perror(VIDEO_DEV);
113     exit(1);
114   }
115 
116   if (ioctl(fd, VIDIOCGCAP, &cap) < 0) {
117     perror("VIDIOGCAP");
118     fprintf(stderr, "(" VIDEO_DEV " not a video4linux device?)\n");
119     close(fd);
120     exit(1);
121   }
122 
123   if (ioctl(fd, VIDIOCGWIN, &win) < 0) {
124     perror("VIDIOCGWIN");
125     close(fd);
126     exit(1);
127   }
128 
129   if (ioctl(fd, VIDIOCGPICT, &vpic) < 0) {
130     perror("VIDIOCGPICT");
131     close(fd);
132     exit(1);
133   }
134 
135   if (cap.type & VID_TYPE_MONOCHROME) {
136     vpic.depth=8;
137     vpic.palette=VIDEO_PALETTE_GREY;    /* 8bit grey */
138     if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
139       vpic.depth=6;
140       if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
141         vpic.depth=4;
142         if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
143           fprintf(stderr, "Unable to find a supported capture format.\n");
144           close(fd);
145           exit(1);
146         }
147       }
148     }
149   } else {
150     vpic.depth=24;
151     vpic.palette=VIDEO_PALETTE_RGB24;
152 
153     if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
154       vpic.palette=VIDEO_PALETTE_RGB565;
155       vpic.depth=16;
156 
157       if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
158         vpic.palette=VIDEO_PALETTE_RGB555;
159         vpic.depth=15;
160 
161         if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
162           fprintf(stderr, "Unable to find a supported capture format.\n");
163           return -1;
164         }
165       }
166     }
167   }
168 
169   buffer = malloc(win.width * win.height * bpp);
170   if (!buffer) {
171     fprintf(stderr, "Out of memory.\n");
172     exit(1);
173   }
174 
175   do {
176     int newbright;
177     read(fd, buffer, win.width * win.height * bpp);
178     f = get_brightness_adj(buffer, win.width * win.height, &newbright);
179     if (f) {
180       vpic.brightness += (newbright << 8);
181       if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
182         perror("VIDIOSPICT");
183         break;
184       }
185     }
186   } while (f);
187 
188   fprintf(stdout, "P6\n%d %d 255\n", win.width, win.height);
189 
190   src = buffer;
191 
192   for (i = 0; i < win.width * win.height; i++) {
193     READ_VIDEO_PIXEL(src, vpic.palette, src_depth, r, g, b);
194     fputc(r>>8, stdout);
195     fputc(g>>8, stdout);
196     fputc(b>>8, stdout);
197   }
198 
199   close(fd);
200   return 0;
201 }
202 
  This page was automatically generated by the LXR engine.