Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 204 | chris | 1 | /* |
| 2 | * Revision: 5.2 Date: 2000/08/25 |
||
| 3 | * Video capture subrutine for Linux/Video4Linux devices |
||
| 4 | * author: Nakazawa,Atsushi ( nakazawa@inolab.sys.es.osaka-u.ac.jp ) |
||
| 5 | * Hirokazu Kato ( kato@sys.im.hiroshima-cu.ac.jp ) |
||
| 6 | * |
||
| 7 | * Modified by Wayne Piekarski (wayne@tinmith.net) - 2005/03/29 |
||
| 8 | * Added support to automatically adjust camera parameters if needed |
||
| 9 | * |
||
| 10 | * Revision: 5.3 Date: 2004/11/18 |
||
| 11 | * Rev Date Who Changes |
||
| 12 | * 5.3 2004-11-18 RG -adding patch done by Uwe Woessner for YUV support on V4L. |
||
| 13 | * (Thanks a lot for this contribution !!) |
||
| 14 | * -modify default video options |
||
| 15 | * (no overhead if define externally) |
||
| 16 | * -adding full V4L options support |
||
| 17 | * -adding eyetoy support |
||
| 18 | * |
||
| 19 | */ |
||
| 20 | #include <sys/ioctl.h> |
||
| 21 | #include <sys/types.h> |
||
| 22 | #include <sys/stat.h> |
||
| 23 | #include <sys/mman.h> |
||
| 24 | #include <fcntl.h> |
||
| 25 | #include <unistd.h> |
||
| 26 | #include <stdio.h> |
||
| 27 | #include <stdlib.h> |
||
| 28 | #include <string.h> |
||
| 29 | #include <linux/types.h> |
||
| 30 | #include <linux/videodev.h> |
||
| 31 | #include <AR/config.h> |
||
| 32 | #include <AR/ar.h> |
||
| 33 | #include <AR/video.h> |
||
| 34 | #include "ccvt.h" |
||
| 35 | #ifdef USE_EYETOY |
||
| 36 | #include "jpegtorgb.h" |
||
| 37 | #endif |
||
| 38 | |||
| 39 | #define MAXCHANNEL 10 |
||
| 40 | |||
| 41 | static AR2VideoParamT *gVid = NULL; |
||
| 42 | |||
| 43 | int arVideoDispOption( void ) |
||
| 44 | { |
||
| 45 | return ar2VideoDispOption(); |
||
| 46 | } |
||
| 47 | |||
| 48 | int arVideoOpen( char *config ) |
||
| 49 | { |
||
| 50 | if( gVid != NULL ) { |
||
| 51 | printf("Device has been opened!!\n"); |
||
| 52 | return -1; |
||
| 53 | } |
||
| 54 | gVid = ar2VideoOpen( config ); |
||
| 55 | if( gVid == NULL ) return -1; |
||
| 56 | |||
| 57 | return 0; |
||
| 58 | } |
||
| 59 | |||
| 60 | int arVideoClose( void ) |
||
| 61 | { |
||
| 62 | int result; |
||
| 63 | |||
| 64 | if( gVid == NULL ) return -1; |
||
| 65 | |||
| 66 | result = ar2VideoClose(gVid); |
||
| 67 | gVid = NULL; |
||
| 68 | return (result); |
||
| 69 | } |
||
| 70 | |||
| 71 | int arVideoInqSize( int *x, int *y ) |
||
| 72 | { |
||
| 73 | if( gVid == NULL ) return -1; |
||
| 74 | |||
| 75 | return ar2VideoInqSize( gVid, x, y ); |
||
| 76 | } |
||
| 77 | |||
| 78 | ARUint8 *arVideoGetImage( void ) |
||
| 79 | { |
||
| 80 | if( gVid == NULL ) return NULL; |
||
| 81 | |||
| 82 | return ar2VideoGetImage( gVid ); |
||
| 83 | } |
||
| 84 | |||
| 85 | int arVideoCapStart( void ) |
||
| 86 | { |
||
| 87 | if( gVid == NULL ) return -1; |
||
| 88 | |||
| 89 | return ar2VideoCapStart( gVid ); |
||
| 90 | } |
||
| 91 | |||
| 92 | int arVideoCapStop( void ) |
||
| 93 | { |
||
| 94 | if( gVid == NULL ) return -1; |
||
| 95 | |||
| 96 | return ar2VideoCapStop( gVid ); |
||
| 97 | } |
||
| 98 | |||
| 99 | int arVideoCapNext( void ) |
||
| 100 | { |
||
| 101 | if( gVid == NULL ) return -1; |
||
| 102 | |||
| 103 | return ar2VideoCapNext( gVid ); |
||
| 104 | } |
||
| 105 | |||
| 106 | /*-------------------------------------------*/ |
||
| 107 | |||
| 108 | int ar2VideoDispOption( void ) |
||
| 109 | { |
||
| 110 | printf("ARVideo may be configured using one or more of the following options,\n"); |
||
| 111 | printf("separated by a space:\n\n"); |
||
| 112 | printf("DEVICE CONTROLS:\n"); |
||
| 113 | printf(" -dev=filepath\n"); |
||
| 114 | printf(" specifies device file.\n"); |
||
| 115 | printf(" -channel=N\n"); |
||
| 116 | printf(" specifies source channel.\n"); |
||
| 117 | printf(" -noadjust\n"); |
||
| 118 | printf(" prevent adjusting the width/height/channel if not suitable.\n"); |
||
| 119 | printf(" -width=N\n"); |
||
| 120 | printf(" specifies expected width of image.\n"); |
||
| 121 | printf(" -height=N\n"); |
||
| 122 | printf(" specifies expected height of image.\n"); |
||
| 123 | printf(" -palette=[RGB|YUV420P]\n"); |
||
| 124 | printf(" specifies the camera palette (WARNING:all are not supported on each camera !!).\n"); |
||
| 125 | printf("IMAGE CONTROLS (WARNING: every options are not supported by all camera !!):\n"); |
||
| 126 | printf(" -brightness=N\n"); |
||
| 127 | printf(" specifies brightness. (0.0 <-> 1.0)\n"); |
||
| 128 | printf(" -contrast=N\n"); |
||
| 129 | printf(" specifies contrast. (0.0 <-> 1.0)\n"); |
||
| 130 | printf(" -saturation=N\n"); |
||
| 131 | printf(" specifies saturation (color). (0.0 <-> 1.0) (for color camera only)\n"); |
||
| 132 | printf(" -hue=N\n"); |
||
| 133 | printf(" specifies hue. (0.0 <-> 1.0) (for color camera only)\n"); |
||
| 134 | printf(" -whiteness=N\n"); |
||
| 135 | printf(" specifies whiteness. (0.0 <-> 1.0) (REMARK: gamma for some drivers, otherwise for greyscale camera only)\n"); |
||
| 136 | printf(" -color=N\n"); |
||
| 137 | printf(" specifies saturation (color). (0.0 <-> 1.0) (REMARK: obsolete !! use saturation control)\n\n"); |
||
| 138 | printf("OPTION CONTROLS:\n"); |
||
| 139 | printf(" -mode=[PAL|NTSC|SECAM]\n"); |
||
| 140 | printf(" specifies TV signal mode (for tv/capture card).\n"); |
||
| 141 | printf("\n"); |
||
| 142 | |||
| 143 | return 0; |
||
| 144 | } |
||
| 145 | |||
| 146 | AR2VideoParamT *ar2VideoOpen( char *config_in ) |
||
| 147 | { |
||
| 148 | AR2VideoParamT *vid; |
||
| 149 | struct video_capability vd; |
||
| 150 | struct video_channel vc[MAXCHANNEL]; |
||
| 151 | struct video_picture vp; |
||
| 152 | char *config, *a, line[256]; |
||
| 153 | int i; |
||
| 154 | int adjust = 1; |
||
| 155 | |||
| 156 | |||
| 157 | /* If no config string is supplied, we should use the environment variable, otherwise set a sane default */ |
||
| 158 | if (!config_in || !(config_in[0])) { |
||
| 159 | /* None suppplied, lets see if the user supplied one from the shell */ |
||
| 160 | char *envconf = getenv ("ARTOOLKIT_CONFIG"); |
||
| 161 | if (envconf && envconf[0]) { |
||
| 162 | config = envconf; |
||
| 163 | printf ("Using config string from environment [%s].\n", envconf); |
||
| 164 | } else { |
||
| 165 | config = NULL; |
||
| 166 | printf ("No video config string supplied, using defaults.\n"); |
||
| 167 | } |
||
| 168 | } else { |
||
| 169 | config = config_in; |
||
| 170 | printf ("Using supplied video config string [%s].\n", config_in); |
||
| 171 | } |
||
| 172 | |||
| 173 | arMalloc( vid, AR2VideoParamT, 1 ); |
||
| 174 | strcpy( vid->dev, DEFAULT_VIDEO_DEVICE ); |
||
| 175 | vid->channel = DEFAULT_VIDEO_CHANNEL; |
||
| 176 | vid->width = DEFAULT_VIDEO_WIDTH; |
||
| 177 | vid->height = DEFAULT_VIDEO_HEIGHT; |
||
| 178 | #if (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_BGRA) |
||
| 179 | vid->palette = VIDEO_PALETTE_RGB32; /* palette format */ |
||
| 180 | #elif (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_BGR) || (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_RGB) |
||
| 181 | vid->palette = VIDEO_PALETTE_RGB24; /* palette format */ |
||
| 182 | #endif |
||
| 183 | vid->contrast = -1.; |
||
| 184 | vid->brightness = -1.; |
||
| 185 | vid->saturation = -1.; |
||
| 186 | vid->hue = -1.; |
||
| 187 | vid->whiteness = -1.; |
||
| 188 | vid->mode = DEFAULT_VIDEO_MODE; |
||
| 189 | vid->debug = 0; |
||
| 190 | vid->videoBuffer=NULL; |
||
| 191 | |||
| 192 | a = config; |
||
| 193 | if( a != NULL) { |
||
| 194 | for(;;) { |
||
| 195 | while( *a == ' ' || *a == '\t' ) a++; |
||
| 196 | if( *a == '\0' ) break; |
||
| 197 | if( strncmp( a, "-dev=", 5 ) == 0 ) { |
||
| 198 | sscanf( a, "%s", line ); |
||
| 199 | if( sscanf( &line[5], "%s", vid->dev ) == 0 ) { |
||
| 200 | ar2VideoDispOption(); |
||
| 201 | free( vid ); |
||
| 202 | return 0; |
||
| 203 | } |
||
| 204 | } |
||
| 205 | else if( strncmp( a, "-channel=", 9 ) == 0 ) { |
||
| 206 | sscanf( a, "%s", line ); |
||
| 207 | if( sscanf( &line[9], "%d", &vid->channel ) == 0 ) { |
||
| 208 | ar2VideoDispOption(); |
||
| 209 | free( vid ); |
||
| 210 | return 0; |
||
| 211 | } |
||
| 212 | } |
||
| 213 | else if( strncmp( a, "-width=", 7 ) == 0 ) { |
||
| 214 | sscanf( a, "%s", line ); |
||
| 215 | if( sscanf( &line[7], "%d", &vid->width ) == 0 ) { |
||
| 216 | ar2VideoDispOption(); |
||
| 217 | free( vid ); |
||
| 218 | return 0; |
||
| 219 | } |
||
| 220 | } |
||
| 221 | else if( strncmp( a, "-height=", 8 ) == 0 ) { |
||
| 222 | sscanf( a, "%s", line ); |
||
| 223 | if( sscanf( &line[8], "%d", &vid->height ) == 0 ) { |
||
| 224 | ar2VideoDispOption(); |
||
| 225 | free( vid ); |
||
| 226 | return 0; |
||
| 227 | } |
||
| 228 | } |
||
| 229 | else if( strncmp( a, "-palette=", 9 ) == 0 ) { |
||
| 230 | if( strncmp( &a[9], "RGB", 3) == 0 ) { |
||
| 231 | #if (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_BGRA) |
||
| 232 | vid->palette = VIDEO_PALETTE_RGB32; /* palette format */ |
||
| 233 | #elif (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_BGR)|| (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_RGB) |
||
| 234 | vid->palette = VIDEO_PALETTE_RGB24; /* palette format */ |
||
| 235 | #endif |
||
| 236 | } |
||
| 237 | else if( strncmp( &a[9], "YUV420P", 7 ) == 0 ) { |
||
| 238 | vid->palette = VIDEO_PALETTE_YUV420P; |
||
| 239 | } |
||
| 240 | } |
||
| 241 | else if( strncmp ( a, "-noadjust", 9 ) == 0 ) { |
||
| 242 | adjust = 0; |
||
| 243 | } |
||
| 244 | else if( strncmp( a, "-contrast=", 10 ) == 0 ) { |
||
| 245 | sscanf( a, "%s", line ); |
||
| 246 | if( sscanf( &line[10], "%lf", &vid->contrast ) == 0 ) { |
||
| 247 | ar2VideoDispOption(); |
||
| 248 | free( vid ); |
||
| 249 | return 0; |
||
| 250 | } |
||
| 251 | } |
||
| 252 | else if( strncmp( a, "-brightness=", 12 ) == 0 ) { |
||
| 253 | sscanf( a, "%s", line ); |
||
| 254 | if( sscanf( &line[12], "%lf", &vid->brightness ) == 0 ) { |
||
| 255 | ar2VideoDispOption(); |
||
| 256 | free( vid ); |
||
| 257 | return 0; |
||
| 258 | } |
||
| 259 | } |
||
| 260 | else if( strncmp( a, "-saturation=", 12 ) == 0 ) { |
||
| 261 | sscanf( a, "%s", line ); |
||
| 262 | if( sscanf( &line[12], "%lf", &vid->saturation ) == 0 ) { |
||
| 263 | ar2VideoDispOption(); |
||
| 264 | free( vid ); |
||
| 265 | return 0; |
||
| 266 | } |
||
| 267 | } |
||
| 268 | else if( strncmp( a, "-hue=", 5 ) == 0 ) { |
||
| 269 | sscanf( a, "%s", line ); |
||
| 270 | if( sscanf( &line[5], "%lf", &vid->hue ) == 0 ) { |
||
| 271 | ar2VideoDispOption(); |
||
| 272 | free( vid ); |
||
| 273 | return 0; |
||
| 274 | } |
||
| 275 | } |
||
| 276 | else if( strncmp( a, "-whiteness=", 11 ) == 0 ) { |
||
| 277 | sscanf( a, "%s", line ); |
||
| 278 | if( sscanf( &line[11], "%lf", &vid->whiteness ) == 0 ) { |
||
| 279 | ar2VideoDispOption(); |
||
| 280 | free( vid ); |
||
| 281 | return 0; |
||
| 282 | } |
||
| 283 | } |
||
| 284 | else if( strncmp( a, "-color=", 7 ) == 0 ) { |
||
| 285 | sscanf( a, "%s", line ); |
||
| 286 | if( sscanf( &line[7], "%lf", &vid->saturation ) == 0 ) { |
||
| 287 | ar2VideoDispOption(); |
||
| 288 | free( vid ); |
||
| 289 | return 0; |
||
| 290 | } |
||
| 291 | } |
||
| 292 | else if( strncmp( a, "-mode=", 6 ) == 0 ) { |
||
| 293 | if( strncmp( &a[6], "PAL", 3 ) == 0 ) vid->mode = VIDEO_MODE_PAL; |
||
| 294 | else if( strncmp( &a[6], "NTSC", 4 ) == 0 ) vid->mode = VIDEO_MODE_NTSC; |
||
| 295 | else if( strncmp( &a[6], "SECAM", 5 ) == 0 ) vid->mode = VIDEO_MODE_SECAM; |
||
| 296 | else { |
||
| 297 | ar2VideoDispOption(); |
||
| 298 | free( vid ); |
||
| 299 | return 0; |
||
| 300 | } |
||
| 301 | } |
||
| 302 | else if( strncmp( a, "-debug", 6 ) == 0 ) { |
||
| 303 | vid->debug = 1; |
||
| 304 | } |
||
| 305 | else { |
||
| 306 | ar2VideoDispOption(); |
||
| 307 | free( vid ); |
||
| 308 | return 0; |
||
| 309 | } |
||
| 310 | |||
| 311 | while( *a != ' ' && *a != '\t' && *a != '\0') a++; |
||
| 312 | } |
||
| 313 | } |
||
| 314 | |||
| 315 | vid->fd = open(vid->dev, O_RDWR);// O_RDONLY ? |
||
| 316 | if(vid->fd < 0){ |
||
| 317 | printf("video device (%s) open failed\n",vid->dev); |
||
| 318 | free( vid ); |
||
| 319 | return 0; |
||
| 320 | } |
||
| 321 | |||
| 322 | if(ioctl(vid->fd,VIDIOCGCAP,&vd) < 0){ |
||
| 323 | printf("ioctl failed\n"); |
||
| 324 | free( vid ); |
||
| 325 | return 0; |
||
| 326 | } |
||
| 327 | |||
| 328 | if( vid->debug ) { |
||
| 329 | printf("=== debug info ===\n"); |
||
| 330 | printf(" vd.name = %s\n",vd.name); |
||
| 331 | printf(" vd.channels = %d\n",vd.channels); |
||
| 332 | printf(" vd.maxwidth = %d\n",vd.maxwidth); |
||
| 333 | printf(" vd.maxheight = %d\n",vd.maxheight); |
||
| 334 | printf(" vd.minwidth = %d\n",vd.minwidth); |
||
| 335 | printf(" vd.minheight = %d\n",vd.minheight); |
||
| 336 | } |
||
| 337 | |||
| 338 | /* adjust capture size if needed */ |
||
| 339 | if (adjust) |
||
| 340 | { |
||
| 341 | if (vid->width >= vd.maxwidth) |
||
| 342 | vid->width = vd.maxwidth; |
||
| 343 | if (vid->height >= vd.maxheight) |
||
| 344 | vid->height = vd.maxheight; |
||
| 345 | if (vid->debug) |
||
| 346 | printf ("arVideoOpen: width/height adjusted to (%d, %d)\n", vid->width, vid->height); |
||
| 347 | } |
||
| 348 | |||
| 349 | /* check capture size */ |
||
| 350 | if(vd.maxwidth < vid->width || vid->width < vd.minwidth || |
||
| 351 | vd.maxheight < vid->height || vid->height < vd.minheight ) { |
||
| 352 | printf("arVideoOpen: width or height oversize \n"); |
||
| 353 | free( vid ); |
||
| 354 | return 0; |
||
| 355 | } |
||
| 356 | |||
| 357 | /* adjust channel if needed */ |
||
| 358 | if (adjust) |
||
| 359 | { |
||
| 360 | if (vid->channel >= vd.channels) |
||
| 361 | vid->channel = 0; |
||
| 362 | if (vid->debug) |
||
| 363 | printf ("arVideoOpen: channel adjusted to 0\n"); |
||
| 364 | } |
||
| 365 | |||
| 366 | /* check channel */ |
||
| 367 | if(vid->channel < 0 || vid->channel >= vd.channels){ |
||
| 368 | printf("arVideoOpen: channel# is not valid. \n"); |
||
| 369 | free( vid ); |
||
| 370 | return 0; |
||
| 371 | } |
||
| 372 | |||
| 373 | if( vid->debug ) { |
||
| 374 | printf("==== capture device channel info ===\n"); |
||
| 375 | } |
||
| 376 | |||
| 377 | for(i = 0;i < vd.channels && i < MAXCHANNEL; i++){ |
||
| 378 | vc[i].channel = i; |
||
| 379 | if(ioctl(vid->fd,VIDIOCGCHAN,&vc[i]) < 0){ |
||
| 380 | printf("error: acquireing channel(%d) info\n",i); |
||
| 381 | free( vid ); |
||
| 382 | return 0; |
||
| 383 | } |
||
| 384 | |||
| 385 | if( vid->debug ) { |
||
| 386 | printf(" channel = %d\n", vc[i].channel); |
||
| 387 | printf(" name = %s\n", vc[i].name); |
||
| 388 | printf(" tuners = %d", vc[i].tuners); |
||
| 389 | |||
| 390 | printf(" flag = 0x%08x",vc[i].flags); |
||
| 391 | if(vc[i].flags & VIDEO_VC_TUNER) |
||
| 392 | printf(" TUNER"); |
||
| 393 | if(vc[i].flags & VIDEO_VC_AUDIO) |
||
| 394 | printf(" AUDIO"); |
||
| 395 | printf("\n"); |
||
| 396 | |||
| 397 | printf(" vc[%d].type = 0x%08x", i, vc[i].type); |
||
| 398 | if(vc[i].type & VIDEO_TYPE_TV) |
||
| 399 | printf(" TV"); |
||
| 400 | if(vc[i].type & VIDEO_TYPE_CAMERA) |
||
| 401 | printf(" CAMERA"); |
||
| 402 | printf("\n"); |
||
| 403 | } |
||
| 404 | } |
||
| 405 | |||
| 406 | /* select channel */ |
||
| 407 | vc[vid->channel].norm = vid->mode; /* 0: PAL 1: NTSC 2:SECAM 3:AUTO */ |
||
| 408 | if(ioctl(vid->fd, VIDIOCSCHAN, &vc[vid->channel]) < 0){ |
||
| 409 | printf("error: selecting channel %d\n", vid->channel); |
||
| 410 | free( vid ); |
||
| 411 | return 0; |
||
| 412 | } |
||
| 413 | |||
| 414 | if(ioctl(vid->fd, VIDIOCGPICT, &vp)) { |
||
| 415 | printf("error: getting palette\n"); |
||
| 416 | free( vid ); |
||
| 417 | return 0; |
||
| 418 | } |
||
| 419 | |||
| 420 | if( vid->debug ) { |
||
| 421 | printf("=== debug info ===\n"); |
||
| 422 | printf(" vp.brightness= %d\n",vp.brightness); |
||
| 423 | printf(" vp.hue = %d\n",vp.hue); |
||
| 424 | printf(" vp.colour = %d\n",vp.colour); |
||
| 425 | printf(" vp.contrast = %d\n",vp.contrast); |
||
| 426 | printf(" vp.whiteness = %d\n",vp.whiteness); |
||
| 427 | printf(" vp.depth = %d\n",vp.depth); |
||
| 428 | printf(" vp.palette = %d\n",vp.palette); |
||
| 429 | } |
||
| 430 | |||
| 431 | /* set video picture */ |
||
| 432 | if ((vid->brightness+1.)>0.001) |
||
| 433 | vp.brightness = 32767 * 2.0 *vid->brightness; |
||
| 434 | if ((vid->contrast+1.)>0.001) |
||
| 435 | vp.contrast = 32767 * 2.0 *vid->contrast; |
||
| 436 | if ((vid->hue+1.)>0.001) |
||
| 437 | vp.hue = 32767 * 2.0 *vid->hue; |
||
| 438 | if ((vid->whiteness+1.)>0.001) |
||
| 439 | vp.whiteness = 32767 * 2.0 *vid->whiteness; |
||
| 440 | if ((vid->saturation+1.)>0.001) |
||
| 441 | vp.colour = 32767 * 2.0 *vid->saturation; |
||
| 442 | vp.depth = 24; |
||
| 443 | vp.palette = vid->palette; |
||
| 444 | |||
| 445 | if(ioctl(vid->fd, VIDIOCSPICT, &vp)) { |
||
| 446 | printf("error: setting configuration !! bad palette mode..\n TIPS:try other palette mode (or with new failure contact ARToolKit Developer)\n"); |
||
| 447 | free( vid ); |
||
| 448 | return 0; |
||
| 449 | } |
||
| 450 | if (vid->palette==VIDEO_PALETTE_YUV420P) |
||
| 451 | arMalloc( vid->videoBuffer, ARUint8, vid->width*vid->height*3 ); |
||
| 452 | |||
| 453 | if( vid->debug ) { |
||
| 454 | if(ioctl(vid->fd, VIDIOCGPICT, &vp)) { |
||
| 455 | printf("error: getting palette\n"); |
||
| 456 | free( vid ); |
||
| 457 | return 0; |
||
| 458 | } |
||
| 459 | printf("=== debug info ===\n"); |
||
| 460 | printf(" vp.brightness= %d\n",vp.brightness); |
||
| 461 | printf(" vp.hue = %d\n",vp.hue); |
||
| 462 | printf(" vp.colour = %d\n",vp.colour); |
||
| 463 | printf(" vp.contrast = %d\n",vp.contrast); |
||
| 464 | printf(" vp.whiteness = %d\n",vp.whiteness); |
||
| 465 | printf(" vp.depth = %d\n",vp.depth); |
||
| 466 | printf(" vp.palette = %d\n",vp.palette); |
||
| 467 | } |
||
| 468 | |||
| 469 | /* get mmap info */ |
||
| 470 | if(ioctl(vid->fd,VIDIOCGMBUF,&vid->vm) < 0){ |
||
| 471 | printf("error: videocgmbuf\n"); |
||
| 472 | free( vid ); |
||
| 473 | return 0; |
||
| 474 | } |
||
| 475 | |||
| 476 | if( vid->debug ) { |
||
| 477 | printf("===== Image Buffer Info =====\n"); |
||
| 478 | printf(" size = %d[bytes]\n", vid->vm.size); |
||
| 479 | printf(" frames = %d\n", vid->vm.frames); |
||
| 480 | } |
||
| 481 | if(vid->vm.frames < 2){ |
||
| 482 | printf("this device can not be supported by libARvideo.\n"); |
||
| 483 | printf("(vm.frames < 2)\n"); |
||
| 484 | free( vid ); |
||
| 485 | return 0; |
||
| 486 | } |
||
| 487 | |||
| 488 | |||
| 489 | /* get memory mapped io */ |
||
| 490 | if((vid->map = (ARUint8 *)mmap(0, vid->vm.size, PROT_READ|PROT_WRITE, MAP_SHARED, vid->fd, 0)) < 0){ |
||
| 491 | printf("error: mmap\n"); |
||
| 492 | free( vid ); |
||
| 493 | return 0; |
||
| 494 | } |
||
| 495 | |||
| 496 | /* setup for vmm */ |
||
| 497 | vid->vmm.frame = 0; |
||
| 498 | vid->vmm.width = vid->width; |
||
| 499 | vid->vmm.height = vid->height; |
||
| 500 | vid->vmm.format= vid->palette; |
||
| 501 | |||
| 502 | vid->video_cont_num = -1; |
||
| 503 | |||
| 504 | #ifdef USE_EYETOY |
||
| 505 | JPEGToRGBInit(vid->width,vid->height); |
||
| 506 | #endif |
||
| 507 | return vid; |
||
| 508 | } |
||
| 509 | |||
| 510 | int ar2VideoClose( AR2VideoParamT *vid ) |
||
| 511 | { |
||
| 512 | if(vid->video_cont_num >= 0){ |
||
| 513 | ar2VideoCapStop( vid ); |
||
| 514 | } |
||
| 515 | close(vid->fd); |
||
| 516 | if(vid->videoBuffer!=NULL) |
||
| 517 | free(vid->videoBuffer); |
||
| 518 | free( vid ); |
||
| 519 | |||
| 520 | return 0; |
||
| 521 | } |
||
| 522 | |||
| 523 | |||
| 524 | int ar2VideoCapStart( AR2VideoParamT *vid ) |
||
| 525 | { |
||
| 526 | if(vid->video_cont_num >= 0){ |
||
| 527 | printf("arVideoCapStart has already been called.\n"); |
||
| 528 | return -1; |
||
| 529 | } |
||
| 530 | |||
| 531 | vid->video_cont_num = 0; |
||
| 532 | vid->vmm.frame = vid->video_cont_num; |
||
| 533 | if(ioctl(vid->fd, VIDIOCMCAPTURE, &vid->vmm) < 0) { |
||
| 534 | return -1; |
||
| 535 | } |
||
| 536 | vid->vmm.frame = 1 - vid->vmm.frame; |
||
| 537 | if( ioctl(vid->fd, VIDIOCMCAPTURE, &vid->vmm) < 0) { |
||
| 538 | return -1; |
||
| 539 | } |
||
| 540 | |||
| 541 | return 0; |
||
| 542 | } |
||
| 543 | |||
| 544 | int ar2VideoCapNext( AR2VideoParamT *vid ) |
||
| 545 | { |
||
| 546 | if(vid->video_cont_num < 0){ |
||
| 547 | printf("arVideoCapStart has never been called.\n"); |
||
| 548 | return -1; |
||
| 549 | } |
||
| 550 | |||
| 551 | vid->vmm.frame = 1 - vid->vmm.frame; |
||
| 552 | ioctl(vid->fd, VIDIOCMCAPTURE, &vid->vmm); |
||
| 553 | |||
| 554 | return 0; |
||
| 555 | } |
||
| 556 | |||
| 557 | int ar2VideoCapStop( AR2VideoParamT *vid ) |
||
| 558 | { |
||
| 559 | if(vid->video_cont_num < 0){ |
||
| 560 | printf("arVideoCapStart has never been called.\n"); |
||
| 561 | return -1; |
||
| 562 | } |
||
| 563 | if(ioctl(vid->fd, VIDIOCSYNC, &vid->video_cont_num) < 0){ |
||
| 564 | printf("error: videosync\n"); |
||
| 565 | return -1; |
||
| 566 | } |
||
| 567 | vid->video_cont_num = -1; |
||
| 568 | |||
| 569 | return 0; |
||
| 570 | } |
||
| 571 | |||
| 572 | |||
| 573 | ARUint8 *ar2VideoGetImage( AR2VideoParamT *vid ) |
||
| 574 | { |
||
| 575 | ARUint8 *buf; |
||
| 576 | |||
| 577 | if(vid->video_cont_num < 0){ |
||
| 578 | printf("arVideoCapStart has never been called.\n"); |
||
| 579 | return NULL; |
||
| 580 | } |
||
| 581 | |||
| 582 | if(ioctl(vid->fd, VIDIOCSYNC, &vid->video_cont_num) < 0){ |
||
| 583 | printf("error: videosync\n"); |
||
| 584 | return NULL; |
||
| 585 | } |
||
| 586 | vid->video_cont_num = 1 - vid->video_cont_num; |
||
| 587 | |||
| 588 | if(vid->video_cont_num == 0) |
||
| 589 | buf=(vid->map + vid->vm.offsets[1]); |
||
| 590 | else |
||
| 591 | buf=(vid->map + vid->vm.offsets[0]); |
||
| 592 | |||
| 593 | if(vid->palette == VIDEO_PALETTE_YUV420P) |
||
| 594 | { |
||
| 595 | |||
| 596 | ccvt_420p_bgr24(vid->width, vid->height, buf, buf+(vid->width*vid->height), |
||
| 597 | buf+(vid->width*vid->height)+(vid->width*vid->height)/4, |
||
| 598 | vid->videoBuffer); |
||
| 599 | return vid->videoBuffer; |
||
| 600 | } |
||
| 601 | #ifdef USE_EYETOY |
||
| 602 | buf=JPEGToRGB(buf,vid->width, vid->height); |
||
| 603 | #endif |
||
| 604 | |||
| 605 | return buf; |
||
| 606 | |||
| 607 | } |
||
| 608 | |||
| 609 | int ar2VideoInqSize(AR2VideoParamT *vid, int *x,int *y) |
||
| 610 | { |
||
| 611 | *x = vid->vmm.width; |
||
| 612 | *y = vid->vmm.height; |
||
| 613 | |||
| 614 | return 0; |
||
| 615 | } |