1c-qcam - Connectix Color QuickCam video4linux kernel driver 2 3Copyright (C) 1999 Dave Forrest <drf5n@virginia.edu> 4 released under GNU GPL. 5 61999-12-08 Dave Forrest, written with kernel version 2.2.12 in mind 7 8 9Table of Contents 10 111.0 Introduction 122.0 Compilation, Installation, and Configuration 133.0 Troubleshooting 144.0 Future Work / current work arounds 159.0 Sample Program, v4lgrab 1610.0 Other Information 17 18 191.0 Introduction 20 21 The file ../drivers/char/c-qcam.c is a device driver for the 22Logitech (nee Connectix) parallel port interface color CCD camera. 23This is a fairly inexpensive device for capturing images. Logitech 24does not currently provide information for developers, but many people 25have engineered several solutions for non-Microsoft use of the Color 26Quickcam. 27 281.1 Motivation 29 30 I spent a number of hours trying to get my camera to work, and I 31hope this document saves you some time. My camera will not work with 32the 2.2.13 kernel as distributed, but with a few patches to the 33module, I was able to grab some frames. See 4.0, Future Work. 34 35 36 372.0 Compilation, Installation, and Configuration 38 39 The c-qcam depends on parallel port support, video4linux, and the 40Color Quickcam. It is also nice to have the parallel port readback 41support enabled. I enabled these as modules during the kernel 42configuration. The appropriate flags are: 43 44 CONFIG_PRINTER M for lp.o, parport.o parport_pc.o modules 45 CONFIG_PNP_PARPORT M for autoprobe.o IEEE1284 readback module 46 CONFIG_PRINTER_READBACK M for parport_probe.o IEEE1284 readback module 47 CONFIG_VIDEO_DEV M for videodev.o video4linux module 48 CONFIG_VIDEO_CQCAM M for c-qcam.o Color Quickcam module 49 50 With these flags, the kernel should compile and install the modules. 51To record and monitor the compilation, I use: 52 53 (make dep; \ 54 make zlilo ; \ 55 make modules; \ 56 make modules_install ; 57 depmod -a ) &>log & 58 less log # then a capital 'F' to watch the progress 59 60But that is my personal preference. 61 622.2 Configuration 63 64 The configuration requires module configuration and device 65configuration. I like kmod or kerneld process with the 66/etc/modules.conf file so the modules can automatically load/unload as 67they are used. The video devices could already exist, be generated 68using MAKEDEV, or need to be created. The following sections detail 69these procedures. 70 71 722.1 Module Configuration 73 74 Using modules requires a bit of work to install and pass the 75parameters. Do read ../modules.txt, and understand that entries 76in /etc/modules.conf of: 77 78 alias parport_lowlevel parport_pc 79 options parport_pc io=0x378 irq=none 80 alias char-major-81 videodev 81 alias char-major-81-0 c-qcam 82 83will cause the kmod/kerneld/modprobe to do certain things. If you are 84using kmod or kerneld, then a request for a 'char-major-81-0' will cause 85the 'c-qcam' module to load. If you have other video sources with 86modules, you might want to assign the different minor numbers to 87different modules. 88 892.2 Device Configuration 90 91 At this point, we need to ensure that the device files exist. 92Video4linux used the /dev/video* files, and we want to attach the 93Quickcam to one of these. 94 95 ls -lad /dev/video* # should produce a list of the video devices 96 97If the video devices do not exist, you can create them with: 98 99 su 100 cd /dev 101 for ii in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do 102 mknod video$ii c 81 $ii # char-major-81-[0-16] 103 chown root.root video$ii # owned by root 104 chmod 600 video$ii # read/writable by root only 105 done 106 107 Lots of people connect video0 to video and bttv, but you might want 108your c-qcam to mean something more: 109 110 ln -s video0 c-qcam # make /dev/c-qcam a working file 111 ln -s c-qcam video # make /dev/c-qcam your default video source 112 113 But these are conveniences. The important part is to make the proper 114special character files with the right major and minor numbers. All 115of the special device files are listed in ../devices.txt. If you 116would like the c-qcam readable by non-root users, you will need to 117change the permissions. 118 1193.0 Troubleshooting 120 121 If the sample program below, v4lgrab, gives you output then 122everything is working. 123 124 v4lgrab | wc # should give you a count of characters 125 126 Otherwise, you have some problem. 127 128 The c-qcam is IEEE1284 compatible, so if you are using the proc file 129system (CONFIG_PROC_FS), the parallel printer support 130(CONFIG_PRINTER), the IEEE 1284 system,(CONFIG_PRINTER_READBACK), you 131should be able to read some identification from your quickcam with 132 133 modprobe -v parport 134 modprobe -v parport_probe 135 cat /proc/parport/PORTNUMBER/autoprobe 136Returns: 137 CLASS:MEDIA; 138 MODEL:Color QuickCam 2.0; 139 MANUFACTURER:Connectix; 140 141 A good response to this indicates that your color quickcam is alive 142and well. A common problem is that the current driver does not 143reliably detect a c-qcam, even though one is attached. In this case, 144 145 modprobe -v c-qcam 146or 147 insmod -v c-qcam 148 149 Returns a message saying "Device or resource busy" Development is 150currently underway, but a workaround is to patch the module to skip 151the detection code and attach to a defined port. Check the 152video4linux mailing list and archive for more current information. 153 1543.1 Checklist: 155 156 Can you get an image? 157 v4lgrab >qcam.ppm ; wc qcam.ppm ; xv qcam.ppm 158 159 Is a working c-qcam connected to the port? 160 grep ^ /proc/parport/?/autoprobe 161 162 Do the /dev/video* files exist? 163 ls -lad /dev/video 164 165 Is the c-qcam module loaded? 166 modprobe -v c-qcam ; lsmod 167 168 Does the camera work with alternate programs? cqcam, etc? 169 170 171 172 1734.0 Future Work / current workarounds 174 175 It is hoped that this section will soon become obsolete, but if it 176isn't, you might try patching the c-qcam module to add a parport=xxx 177option as in the bw-qcam module so you can specify the parallel port: 178 179 insmod -v c-qcam parport=0 180 181And bypass the detection code, see ../../drivers/char/c-qcam.c and 182look for the 'qc_detect' code and call. 183 184 Note that there is work in progress to change the video4linux API, 185this work is documented at the video4linux2 site listed below. 186 187 1889.0 --- A sample program using v4lgrabber, 189 190This program is a simple image grabber that will copy a frame from the 191first video device, /dev/video0 to standard output in portable pixmap 192format (.ppm) Using this like: 'v4lgrab | convert - c-qcam.jpg' 193produced this picture of me at 194 http://mug.sys.virginia.edu/~drf5n/extras/c-qcam.jpg 195 196-------------------- 8< ---------------- 8< ----------------------------- 197 198/* Simple Video4Linux image grabber. */ 199/* 200 * Video4Linux Driver Test/Example Framegrabbing Program 201 * 202 * Compile with: 203 * gcc -s -Wall -Wstrict-prototypes v4lgrab.c -o v4lgrab 204 * Use as: 205 * v4lgrab >image.ppm 206 * 207 * Copyright (C) 1998-05-03, Phil Blundell <philb@gnu.org> 208 * Copied from http://www.tazenda.demon.co.uk/phil/vgrabber.c 209 * with minor modifications (Dave Forrest, drf5n@virginia.edu). 210 * 211 */ 212 213#include <unistd.h> 214#include <sys/types.h> 215#include <sys/stat.h> 216#include <fcntl.h> 217#include <stdio.h> 218#include <sys/ioctl.h> 219#include <stdlib.h> 220 221#include <linux/types.h> 222#include <linux/videodev.h> 223 224#define FILE "/dev/video0" 225 226/* Stole this from tvset.c */ 227 228#define READ_VIDEO_PIXEL(buf, format, depth, r, g, b) \ 229{ \ 230 switch (format) \ 231 { \ 232 case VIDEO_PALETTE_GREY: \ 233 switch (depth) \ 234 { \ 235 case 4: \ 236 case 6: \ 237 case 8: \ 238 (r) = (g) = (b) = (*buf++ << 8);\ 239 break; \ 240 \ 241 case 16: \ 242 (r) = (g) = (b) = \ 243 *((unsigned short *) buf); \ 244 buf += 2; \ 245 break; \ 246 } \ 247 break; \ 248 \ 249 \ 250 case VIDEO_PALETTE_RGB565: \ 251 { \ 252 unsigned short tmp = *(unsigned short *)buf; \ 253 (r) = tmp&0xF800; \ 254 (g) = (tmp<<5)&0xFC00; \ 255 (b) = (tmp<<11)&0xF800; \ 256 buf += 2; \ 257 } \ 258 break; \ 259 \ 260 case VIDEO_PALETTE_RGB555: \ 261 (r) = (buf[0]&0xF8)<<8; \ 262 (g) = ((buf[0] << 5 | buf[1] >> 3)&0xF8)<<8; \ 263 (b) = ((buf[1] << 2 ) & 0xF8)<<8; \ 264 buf += 2; \ 265 break; \ 266 \ 267 case VIDEO_PALETTE_RGB24: \ 268 (r) = buf[0] << 8; (g) = buf[1] << 8; \ 269 (b) = buf[2] << 8; \ 270 buf += 3; \ 271 break; \ 272 \ 273 default: \ 274 fprintf(stderr, \ 275 "Format %d not yet supported\n", \ 276 format); \ 277 } \ 278} 279 280int get_brightness_adj(unsigned char *image, long size, int *brightness) { 281 long i, tot = 0; 282 for (i=0;i<size*3;i++) 283 tot += image[i]; 284 *brightness = (128 - tot/(size*3))/3; 285 return !((tot/(size*3)) >= 126 && (tot/(size*3)) <= 130); 286} 287 288int main(int argc, char ** argv) 289{ 290 int fd = open(FILE, O_RDONLY), f; 291 struct video_capability cap; 292 struct video_window win; 293 struct video_picture vpic; 294 295 unsigned char *buffer, *src; 296 int bpp = 24, r, g, b; 297 unsigned int i, src_depth; 298 299 if (fd < 0) { 300 perror(FILE); 301 exit(1); 302 } 303 304 if (ioctl(fd, VIDIOCGCAP, &cap) < 0) { 305 perror("VIDIOGCAP"); 306 fprintf(stderr, "(" FILE " not a video4linux device?)\n"); 307 close(fd); 308 exit(1); 309 } 310 311 if (ioctl(fd, VIDIOCGWIN, &win) < 0) { 312 perror("VIDIOCGWIN"); 313 close(fd); 314 exit(1); 315 } 316 317 if (ioctl(fd, VIDIOCGPICT, &vpic) < 0) { 318 perror("VIDIOCGPICT"); 319 close(fd); 320 exit(1); 321 } 322 323 if (cap.type & VID_TYPE_MONOCHROME) { 324 vpic.depth=8; 325 vpic.palette=VIDEO_PALETTE_GREY; /* 8bit grey */ 326 if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { 327 vpic.depth=6; 328 if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { 329 vpic.depth=4; 330 if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { 331 fprintf(stderr, "Unable to find a supported capture format.\n"); 332 close(fd); 333 exit(1); 334 } 335 } 336 } 337 } else { 338 vpic.depth=24; 339 vpic.palette=VIDEO_PALETTE_RGB24; 340 341 if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { 342 vpic.palette=VIDEO_PALETTE_RGB565; 343 vpic.depth=16; 344 345 if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) { 346 vpic.palette=VIDEO_PALETTE_RGB555; 347 vpic.depth=15; 348 349 if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) { 350 fprintf(stderr, "Unable to find a supported capture format.\n"); 351 return -1; 352 } 353 } 354 } 355 } 356 357 buffer = malloc(win.width * win.height * bpp); 358 if (!buffer) { 359 fprintf(stderr, "Out of memory.\n"); 360 exit(1); 361 } 362 363 do { 364 int newbright; 365 read(fd, buffer, win.width * win.height * bpp); 366 f = get_brightness_adj(buffer, win.width * win.height, &newbright); 367 if (f) { 368 vpic.brightness += (newbright << 8); 369 if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) { 370 perror("VIDIOSPICT"); 371 break; 372 } 373 } 374 } while (f); 375 376 fprintf(stdout, "P6\n%d %d 255\n", win.width, win.height); 377 378 src = buffer; 379 380 for (i = 0; i < win.width * win.height; i++) { 381 READ_VIDEO_PIXEL(src, vpic.palette, src_depth, r, g, b); 382 fputc(r>>8, stdout); 383 fputc(g>>8, stdout); 384 fputc(b>>8, stdout); 385 } 386 387 close(fd); 388 return 0; 389} 390-------------------- 8< ---------------- 8< ----------------------------- 391 392 39310.0 --- Other Information 394 395Use the ../../Maintainers file, particularly the VIDEO FOR LINUX and PARALLEL 396PORT SUPPORT sections 397 398The video4linux page: 399 http://roadrunner.swansea.linux.org.uk/v4l.shtml 400 401The video4linux2 page: 402 http://millennium.diads.com/bdirks/v4l2.htm 403 404Some web pages about the quickcams: 405 http://www.dkfz-heidelberg.de/Macromol/wedemann/mini-HOWTO-cqcam.html 406 407 http://www.crynwr.com/qcpc/ QuickCam Third-Party Drivers 408 http://www.crynwr.com/qcpc/re.html Some Reverse Engineering 409 http://cse.unl.edu/~cluening/gqcam/ v4l client 410 http://phobos.illtel.denver.co.us/pub/qcread/ doesn't use v4l 411 ftp://ftp.cs.unm.edu/pub/chris/quickcam/ Has lots of drivers 412 http://www.cs.duke.edu/~reynolds/quickcam/ Has lots of information 413 414 415