Luigi Rizzo -- USB Camera (webcam) Drivers for FreeBSD

So far FreeBSD has had limited support for USB cameras, but there is some chance to improve things. I have started to glue together some good work from other people -- mostly ports for kernel and userland drivers for webcams -- to build a unified camera driver for FreeBSD.

Latest version is pwcbsd-luigi-20070117.tgz, see here for the install instructions, and here for the status of supported/unsupported cameras.
In brief, at the moment it works at 20fps in CIF (352x288) resolution with two USB 1.1 cameras (Trust WB-1200p and Creative VF0010) and work is ongoing to support other cameras.

Work Description

The focus of this project is implementing support for USB Webcam (and in general, video acquisition devices, e.g. DVB receivers). Such support basically requires one or more kernel modules that can talk to the USB interface on one side, and makes the camera accessible using the Video for Linux (v4l) API, which is widely used by application programs.

Background

Supporting usb peripherals other than mice and mass storage devices is challenging. Until recently (late 2006) these devices normally have undocumented protocols above the USB level. So the commands to set up a data transfer, operate the camera (or video grabber) controls, select format, compression and encoding are often derived by reverse engineering the behaviour of application, using hardware or software USB sniffers (see e.g. usbsnoop) on a platform where a device driver exists.

The Linux community has done some amount of work in this direction, coming up with several kernel drivers for various cameras and DVB devices. See e.g. http://mxhaard.free.fr/spca5xx.html and http://www.linuxtv.org/ for some references.

On FreeBSD and *BSD in general, a few people have ported some of the linux work mentioned above. Unfortunately, with a single but important exception, these ports are userland application that access the USB interface via the "ugen" device, e.g.:

This 'userland' approach has two major drawbacks:
  1. very low frame rates, and many dropped or corrupt frames; this happens partly because of the high data rates involved, and partly because some of the required actions (like retriggering a data transfer after an error or at the end of a frame, and the like) cannot happen quickly enough with userland processes that are scheduled at random times).
  2. no Video4Linux compatibility, which makes the camera essentially useless other than for the specific program that knows how to talk to it.
I mentioned that there is an important exception, which is the pwcbsd driver, available in ports/multimedia/pwcbsd (by the way, from the same person who has written the first DVB driver for FreeBSD that i know of).

pwcbsd is a kernel driver which is a kernel driver, in turn derived from the 'pwc' linux driver, which has none of the performance limitations mentioned above, and and implements the Video4Linux API which is used by many applications. The only practical limitation of 'pwcbsd' is the small number of supported webcams (in particular, none of the cameras i had access to!).

I have started looking at how to merge the kernel driver with the userland code, in order to extend the set of supported hardware.

This project

This project, without a name yet, aims at merging pwcbsd with other camera drivers (among those mentioned above, i started with spca) into a unified camera driver for FreeBSD. In the process, i want also to clean up the existing spca code which in many parts is a huge copy&paste programming exercise.

As a first step, i just wrote enough glue to let pwc.ko (the kernel module) link and load with most of the 'spca' code. That involved writing macros or stub functions to implement all the missing linux calls, a few wrappers for the functions that i actually needed, and #ifdef out blocks of code that i did not need (e.g. the module glue, and the device API which was already implemented in pwc). No additional functionality has been added in this phase.

The next step was to start calling spca functions from the pwc driver, beginning with the spcaDetectCamera() (essentially the probe routine) and then the actual data manipulation code. In order to do that i had to merge the pwc_softc and spca_softc descriptor, removing a bit of the duplication, etc. etc.

At this point i started with reengineering some parts of the code, basically the data-movement code in spca, and the hooks from the generic usb driver and the camera-specific routines in pwc.

Install Instructions

  1. Extract the above archive
  2. make && make install
    This creates and installs a pwc.ko that you can kldload.
  3. kldload pwc
  4. install pwcview. pwcview sources are available in this tarball, but you can also install it directly from ports/multimedia/pwcbsd
  5. pwcview -s cif (see the pwcview manpage for details) to see the image and possibly change contrast/brightness.
  6. control-C to block the program!
  7. The camera is also accessible with the Video4Linux API so programs supporting that API might be able to make use of the camera (but this is often untested or disabled in the FreeBSD ports of several programs).

Status (most recent on top)

See below for a list of supported cameras.

Tested cameras

I have a small number of cameras that i am trying with various success, all others being untested. A few notes are worth here:
WORKING 0x093a 0x2468 - Trust WB-1200p (Mini Webcam)
Based on the PAC207 bridge and sensor, CIF 352x288, works well with 20fps in CIF resolution. The camera is not very sensitive. On the other hand, it is easily available on the market for 13-15 euros and works on USB 1.1.
WORKING 0x041e 0x403b - Creative Vista VF0010
This is a USB1 device with CIF resolution, working at 20fps
PARTLY WORKING 0x046d 0x0870Labtec/Dexxa Webcam
This is a 352x288 camera supported by the spca driver. I can read frames but cannot sync/decode the images very well yet.
NOT WORKING 0xeb1a 0x2820 Silvercrest 1.3Mpix
This is a VGA camera using the EMpia 2820 bridge (also used in several DVB receivers) and a sensor presumably from Pixart as well. Not working yet, it uses USB2-high speed so you cannot use with the EHCI driver (which does not support isochronous mode).
Under windows it seems very sensitive even in low light conditions.
NOT WORKING YET 0x05a9 0xa511 - Creative Webcam CT6840 (Part no. 1168403000) A very old model from Creative, apparently supported by the 'vid' program though it does not seem to work for me. Unknown resolution but i suspect it is CIF or less.
NOT WORKING 0x0c45 0x624f - Trust WB-5500T 1.3 Mpixels This is a USB2 device which claims a 1.3Mpixel sensor. Not supported yet. No documentation available.