00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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
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
00084
00085 struct {
00086 void *start;
00087 size_t length;
00088 } *buffers;
00089 unsigned int i;
00090
00091
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
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
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
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
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
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
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
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
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
00283
00284
00285 for(frame=0; frame<vidbuf.frames;frame++){
00286 mapbuf.frame = frame;
00287 if (ioctl(video_dev_fd,VIDIOCMCAPTURE, &mapbuf)<0){
00288 perror("VIDIOCMCAPTURE");
00289 exit(-1);}
00290 }
00291
00292 frame = 0;
00293
00294
00295
00296
00297
00298
00299 while (1){
00300 i = -1;
00301 while(i<0){
00302
00303 i= ioctl(video_dev_fd,VIDIOCSYNC, &frame);
00304 if(i < 0 && errno == EINTR) continue;
00305 if (i < 0) {
00306 perror ("VIDIOCSYNC");
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");
00319 exit(-1);
00320 }
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