linux-old/Documentation/video4linux/CQcam.txt
<<
>>
Prefs
   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
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.