Author: D. Korovkin Notes and corrections: N. Korovkina, B. Butler USB Cameras support in the Linux kernel. 1. History and present At the beginning of the UNIX era there were two types of devices -- character and block. But we, programmers, are really lazy guys, we don't want to write the same code several times, so it's better to develop a good library functions and reuse them, so we need to write only a very specific part of the code which is either a hardware or application specific. In this way networking, SCSI, USB, etc. driver subclasses appeared. Let's talk today about USB web cameras and their support in the Linux kernel. On one hand these devices are USB devices, so they use USB library functions for USB messages sending and receiving, but on the other hand these devices are Video4Linux devices, so they have to provide Video4Linux interface functions to the upper level. These functions are: - open; - close; - read; - mmap; - ioctls: - VIDIOCGCAP - get device capability; - VIDIOCGCHAN - get channel (useful for TV tuners); - VIDIOCSCHAN - set channel; - VIDIOCGPICT - get brightness, contrast, etc; - VIDIOCSPICT - set brightness, contrast, etc; - VIDIOCMCAPTURE - start image capture; - VIDIOCSYNC - wait for image capture finish; - and others (see drivers/media/video/usbvideo/usbvideo.c for details). 2. Problem But there are some functions that are very specific and common for USB web cameras. Let's see how a typical USB web camera works: 1. Probe the USB device that it's really that camera it has to support; 2. Initialize USB web camera and set up the proper parameters; 3. Set up the picture parameters; 4. Start the video acquisition process by initializing isochronous USB data transmission; 5. Wait for a packet; 6. When the packet comes, convert it's contents to the part of the image and copy this part of the image to the image buffer; 7. Do brightness and white balance corrections; 8. Stop the isochronous USB data transmission; 9. Stop the device and put it to sleep if possible. So, we see, that tasks 1, 2, 3, 7, 9 are more-less hardware specific, 4, 5, 8 are more-less hardware independent. And the task 6 may be splitted to two sub-tasks: get data from the buffer and convert them to the part of the image. While the first one is hardware independent, the second one is ... hardware specific. No, really. Each camera produces an image in one of several standard formats: - RGB555; - RGB565; - RGB24; - RGB32; - greyscale; - YUV422; - YUYV; - and more (see include/linux/videodev.h for details). But there are a finite number of formats that cameras support. So we may build a library of these methods and choose the proper function depending on the camera type and application request. 3. Current solutions There is a module drivers/media/video/usbvideo/usbvideo.c in the Linux kernel that does hardware independent tasks for USB web cameras, but there is no image conversion module in the Linux kernel. Currently usbvideo based camera drivers support only one type of image (which is one that web camera hardware supports). 4. spca50x project spca50x project (http://spca50x.sourceforge.net) is a project of a Linux device driver for Sunplus chips based USB web cameras. It started in 2001. But this driver had to support a lot of cameras. So there was an idea to create a web camera framework that allowed a developer to write a very small module that implements only hardware dependent features. But that was just an idea ;-(. It was not implemented. Currently there is another project derived from it -- gspca (http://mxhaard.free.fr/) which is actually a port of the spca50x to 2.6.xx Linux kernel. It also adds the image conversion library, which is almost exactly what we needed! 5. The short-term perspective of the USB web camera drivers So, currently we have reached the situation that if we need a driver for the camera we have to implement only a module that provides hardware dependent functionality. Let's assume that we have a web camera, made by Megabucks. Surely, it has only a Windoze driver and when you e-mail or phone tech support, you hear: "You use Linux? Sorry, we don't support it. You need hardware specs to write a Linux device driver, right? Sorry it's an intellectual property of Megabucks Company". What to do? Give up and complain? No! Let's set up an experimental environment: - Windoze with drivers; - Megabucks webcam; - USB sniffer (like this one. http://sourceforge.net/projects/usbsnoop/) Then we know, that an average driver sends some control messages in order to set up the camera parameters, then it starts isochronous data transfer and receives camera data. So, let's try to take a look at the log and find them. Then, let's try to experiment and grab an image. The other possible suggestion -- disassemble the camera itself an take a look at chips. May be Megabucks uses a very well known chip, so all you need -- add your camera support into the existing driver. 6. The long-term perspective of the USB web camera drivers USB Implementers Forum is working on a standard for USB Video Class (UVC) devices. So all web cameras will have to provide a standard hardware interface. It can be expected that in the near future most webcams will be UVC compatible as this is a logo requirement for Windows Vista. So, may be all we shall need is a Linux UVC driver (http://linux-uvc.berlios.de/), who knows? That's it. Questions?