Hacker News new | past | comments | ask | show | jobs | submit login
Driver adventures for a 1999 webcam (benjojo.co.uk)
429 points by tomwas54 on April 28, 2023 | hide | past | favorite | 74 comments



There is a lot you can do to improve the quality of the image. This camera has a very early CMOS sensor, which suffered from huge pixel-to-pixel variation. By characterizing each pixel (which you can do by taking dark field and flat field images), you can correct for this variation, and get an image that looks much less noisy. There are also various algorithms to undo the Bayer filtering, with tradeoffs between sharpness, color accuracy and performance.


That's a very neat trick. In two decades of messing around with webcams we never clued in to that, and I'm pretty sure that this may well be one of the reasons why we had noise issues when using our very early bluescreen implementation.


The mentioned qc-usb driver seems to do some filtering.

IIRC when I played with that 15-20 years ago qc-usb produced distinctly blurry images with slightly washed out colors, while the original windows driver produced images that are sharp, very noisy and with somewhat unnaturaly vivid colors.


Maybe it's subjective, but the screencap from XP seems to show a much higher quality image. It seems there's still room for improvement. Awesome work regardless!


He did say that the webcam had its gain and white balance controlled by the driver so I'm guessing he didn't go the extra mile to reverse engineer that part of the software for what is a pretty lousy camera.


Yeah, looks like the author took a random debayering filter and then called it a day.


That was my immediate thought too. The XP image definitely looked a lot better.


That's being kind.


https://en.wikipedia.org/wiki/Flat-field_correction

Of note is that FFC --- and frequent too --- is basically mandatory for thermal imaging sensors, since their pixels drift a lot.


Does pixel-to-pixel variation change based on temperature or some other ambient factor, or would characterization be a one-shot deal?


It is mostly the dark current (which is reflected in the values you would get if no light is hitting the CMOS sensor) which is affected by temperature. However, its effect scales with the exposure time. Since night time astrophotography requires long exposure times, this would require recalibration (see also @bdigiifh's post). However, for typical daytime use the effect is much less significant.

Some CMOS sensors or the surrounding electronics components on the PCB can heat up significantly while the sensor is in use.

If the sensor has a configurable gain (which is the hardware amplification applied before digitizing the voltage measured for each pixel), then you probably want to characterize the pixel-to-pixel variation for each gain level.


In professional astronomy (where sensors are kept in dewars to reduce dark current) this process (flat field, dark field) is carried out at least once a night.


Oh, the 'I took it home already' feeling. I had a really bad case of this last week, bought a 17 KW solar inverter for a relatively small amount of money and lugged it home, all 50 Kg of it. It worked when it was taken off the wall according to the seller, but on plugging it in on my end it didn't work, though the display lit up and it seemed to work it wasn't making any power. Normally you'd return it as defective and that would be that but this thing is heavy and it was far away.

Long story short: the seller was a trustworthy fellow and definitely did not try to pull a fast one on me. What happened is that during assembly in the factory or a later repair someone smashed the lid into the main circuit board, almost but not quite tearing off one of those IDC headers for flat cable. Bits of it were rattling around in the case which already had me suspicious upon unloading it. That must have been quite the impact, those things don't normally break. The vibration of the transport across 200 km in a car with a stiff suspension did the rest and dislodged the cable completely. Plug the cable back in and it still worked, so I guess I got really lucky. It's been on the wall and has been making power for the last 3 days without any errors.


  $ cat /usr/src/linux-headers-`uname -r`/include/uapi/asm-generic/errno.h | grep 90
  #define        EMSGSIZE        90        /* Message too long */
Nooo! errno from moreutils:

https://man.archlinux.org/man/errno.1

  $ errno 90
  EMSGSIZE 90 Message too long
or:

  $ errno -s "too long"
  E2BIG 7 Argument list too long
  ENAMETOOLONG 36 File name too long
  EMSGSIZE 90 Message too long


Microsoft have an Err.exe for Windows error codes too: https://learn.microsoft.com/en-us/windows/win32/debug/system...


A friend of mine used a cheap (pac207) webcam. He complained to me that the camera image was too dark. I looked in the kernel for its driver... found the line which controlled its brightness... sent a patch to maintainer to increase. The maintainer accepted just a bit lower than what I suggest; he said that if the exposure was too long some protocol (probably USB) could break.

Update the driver on my friends' computer (of course, without waiting a new kernel release) and boom, much better image from the camera! He was happy. He thanked me for how I fixed it, I thanked him for giving me opportunity for such a small and useful hack.

Got back to visit him a few days later. Noticed he wasn't using the webcam anymore. I asked "where's your webcam?", he said: "Damn webcam only works correctly under linux!"


This is pretty cool and impressive work! In a pleasant turn of events, "USB video device class" or UVC would have its initial release just 4 years later in 2003. Webcams implementing UVC, which most do since the early 2000s, communicate using a standard protocol which means almost any OS can access almost any webcam without any special drivers or software.

I have an 2012 Logitech webcam connected to an OpenBSD box. A cron job instructs ffmpeg to read from /dev/video0 every 10 minutes, which in turn writes a .jpg into a folder for creating a timelapse. Not bad for a random old webcam I had laying around.

https://en.wikipedia.org/wiki/USB_video_device_class


Even better, this device class also covers things like cheap digital "microscopes" and external USB video capture devices. It really simplifies working with those kind of tools.


Reminds me when I had to read barcodes from a USB-connected barcode scanner on a Mac. The manufacturer supplied a closed-source library which only supported PPC code and they told me that they lost the source code, so I couldn't easily add intel support.

In the end I sniffed the USB protocol of the windows driver and was delighted to see how they abused the control endpoint rather than setting up proper data endpoints.

I was so happy when my Mac application was able to talk to the scanner and, compared to windows, completely without any driver installation thanks to user-space IOKit on macOS.

Writing software to make hardware beep is even more fun than writing software that doesn't involve hardware making noise.


Core memory unlocked. Somewhere deep in the bellows of my electronics pile, I have an ancient HP barcode reader box that plugged inline with an AT keyboard. Into this box plugged a reader pen that you dragged across a barcode.

Once read, it would send the barcode number as keyboard commands. It was a very tactile experience.


Meanwhile, USB barcode scanners nowadays work by basically being a keyboard, so I guess we've come full circle.


I think keyboard emulation was always the way most barcode readers operated.


> In the end I sniffed the USB protocol of the windows driver and was delighted to see how they abused the control endpoint rather than setting up proper data endpoints.

Is there a better way to implement this? They seem to use it for any non-standard feature. My laptop's keyboard uses the control endpoint to control the LEDs.


you're supposed to use the control endpoint to negotiate which data endpoints to set up in what way for communication and then communicate over those.

In the case of this barcode scanner all communication was done over the control endpoint though.


That sounds pretty fun (once you're finished with it, I'm sure)! How does sniffing the USB work? Do you do that via some software/kernel extension, via special hardware, or something simpler? Do you find there are some USB devices where the manufacturer would rather you didn't sniff their traffic and make it more painful to piece together?


Wireshark via usbmon under Linux can be used to capture USB traffic. This is especially useful when the device has windows drivers, as usbmon can be used to capture the traffic off a windows VM.

For black box devices, you can build/buy a bus snoop cable and hook that up to usbmon/Wireshark (eg sniff the Xbox Kinect protocol).

Percurnious devices will encrypt/sign their packets to make reverse engineering more difficult, if not impossible, but those are few and far between. You're already buying the hardware and that's the expensive bit, so as long as you've bought the hardware, DRM-style weirdness over USB is rare. Still exists, but most hardware I see these days just uses a generic driver like HID for input, or UVC for video, reducing the amount of snooping needed to make the basics work. Getting extra functionality (like special LEDs) working still requires snooping of the working Windows driver+program though.


> Now you might ask, why does the webcam have an endpoint with a 0 byte MaxPacketSize on its first interface? Who knows!

This one has a simple answer:

USB is a shared bus and limited in bandwidth. Isochronous endpoints transmit continously and thus require a fixed part of that bandwidth.

The OS has to allocate the available bus bandwidth to all plugged in devices.

If no more bandwidth is available, it will refuse to configure the device that you just plugged in!

Thus the alternate setting with the isochronous packet size set to 0 serves multiple purposes:

1) It lets the OS configure the device and let the driver discover it even when not enough free bandwith is available on the bus

2) The driver can release the unused bandwith while the device is not in use

3) Not sending iso packets while the device is not actively used also means less power draw


"This was especially annoying since I had already taken this thing home."

There's no going back now- we've come too far. I can relate to this, though. I have it, so now I must solve it- pointlessness be damned.


this was actually a pretty serious nostalgic moment as it happened to also be the same model as my first webcam

...and that "eyeball on a stand" form-factor also became the de-facto one for a webcam (just image search "webcam icon"), so it is also historically significant from that perspective.

This is almost like the inverse of some efforts in the retrocomputing community, which involve writing drivers to allow new hardware to work with old OSs, among them Windows XP and the 9x series.

But I think the most frustrating reason to have to get rid of something is that drivers stop being made for devices.

...and they have a similar mindset: if there are no drivers, then let's write some.

On the topic of this particular camera, a little bit of searching shows some more information from a 23-year-old page:

http://www.geocities.ws/qcexpress/quickcam.html

...through which we get a hint that you can download the datasheet for the PB-0100 sensor from Photobit's site; although it is long gone, archive.org has saved some pieces:

https://web.archive.org/web/20001018065459/http://www.photob...

Sadly, the datasheets themselves weren't saved. I could find some for their later, larger sensors, but unfortunately not this one (although it may be out there, the increasing uselessness of search engines is a huge impediment --- and I do think that such destruction of access to historical information may in fact be deliberate.)


Kudos!

I cracked open (both out of curiosity and for recycling) my own 1999 Logitech QuickCam Express just a few days ago, then tossed away the parts. It was a decent webcam for the time, which was when Windows 98 was all the rage.

My desktop admittedly being a Windows system, I dabbled for a while trying to get the old drivers and software to work on Windows 11, alas, not a chance.

I liked the quirky thing especially for the physical visor that assured me nobody is watching me when the camera SHOULD be off, and saved me the masking tape (except for a single strip permanently glued to the inside of the visor, because for some odd reason, the thing was semi-translucent!)

I went out and bought a Trust webcam with Windows 11 support which astonishingly cost me less than three Euros (!!) new, at the bargain store. The Logitech, once upon a time, was more than ten times as much, not adjusted for inflation. Alas, the Logitech QuickCam had lower resolution, but still a better picture.

This was a very intreresting read, as I naively assumed that USB cameras had to follow some HID-like standard also for polling images off of it, like a scanner's TWAIN driver model back in the days. It was enlightening to read that they indeed seem to have had a unique encoding not shared with other cameras.


I believe they now most do follow the UVC standard; however OP's Logitech camera was manufactured before that was established.


If I recall correctly there was also a parallel port version of this webcam, for people using computers without usb support


There definitely was a Mac mini-Din-8 serial port version as well. I believe it was the original, before there even was a version for PC/Windows: https://wiki.preterhuman.net/Connectix_QuickCam


Connectix cameras were all CCD, BW ones used Texas Instruments TC255 http://wastelands-observatory.factspot.com/equipment/. This fabulously ungooglable DMS provider claims to have designed and manufactured it for Connectix https://www.odi.net/portfolio.html


“installing Windows XP on reasonably fast modern systems is very amusing, the setup wizard will say that it has 30 minutes remaining and then proceed to blow through the entire installation in less than 15 seconds”


I did something very similar quite recently with an old Mustek DV3000 camera that had webcam functionality. I was shocked to find out that Linux actually supports it out of the box. The quality is trash so it's not really usable, but fun messing around with it nonetheless.


Linux support for old hardware is absolutely amazing. No matter how arcane or weird your gizmo is chances are someone wrote a driver for it that is still in support. This is one of those ways in which the open source world is way ahead of closed source, where you're sore out of luck even for relatively modern stuff (for instance: Firewire cards).


I have the cam in the article, and it worked off-the-shelf with my Linux box. I temporarily had it set up with a Raspberry Pi as a security cam.

The driver support makes it a lot easier to build Franken-PCs with obscure graphics cards and accessories too. You wouldn't traditionally associate Linux with just working, but in the case of older hardware it is an amazing selling point.



"Writes drivers to allow 235 webcams to work" is not the same thing as "writes 235 webcam drivers".


While Linux support for old hardware tends to be great, lately various kinds of Linux support are suffering in some ways, as higher percentages of software techies are now using Macs and MS Windows.

Add to this many people now going to pains to do open source for closed (and sometimes abusive) platforms, which has network effects, bringing and cementing more techies to closed, and leaving them oblivious to why and how we have the open things we still do.

This also has network effects in removing some hard-earned pressure on hardware developers to cooperate with open platform efforts.

There's an expression about wealth, which I'll rephrase something like: "The first generation earns it, the second generation preserves it, the third generation fritters it away."

There's also an expression: "The tree of liberty must be refreshed from time to time with the blood of patriots and tyrants."

We could avoid a lot of needless abuse in the next several years (and questionable tree-watering), by more of us actively trying to preserve and even improve libre/open platforms now.


>While Linux support for old hardware tends to be great, lately various kinds of Linux support are suffering in some ways, as higher percentages of software techies are now using Macs and MS Windows.

Any examples or evidence of this? Seems easier than me than ever to use Linux with all kinds of hardware


Here you go.

https://bugs.ghostscript.com/show_bug.cgi?id=706455

There is a workaround by manually editing a script to call gs in a different way, but the original way doesn't work and they won't fix it, and the script itself is from a package maintained by nobody.


Cool read, but was a wee bit disappointing not to have it fully figured out by the end! That's just the reality of life though :)


I have so many strange devices since my adventures in computers began. This has inspired me to dig them out of the plastic containers i have relegated them to and get some running again. Thank you for the write up!!!!


Should custom USB drivers like this be contributed to the kernel? I wanted to send mine upstream but reading the source code I got the impression user space drivers are preferred. Would appreciate some guidance.


I wonder if you could run it through Stable Diffusion as a next project idea? Train a model on your images using Dreambooth and then clean the video to get HD results?


Ugh I wish v4l2loopback was in the upstream kernel...


Well... actually for this use case we need something significantly improved. v4l2loopback has several flaws relevant to user-space camera drivers (which are also relevant to modern MIPI cameras).

The most important one is that it is cumbersome for the application that feeds the virtual camera to know whether its output is used at all - e.g. for power-saving. The correct solution is V4L2_EVENT_PRI_CLIENT_USAGE, but there is no way to use it e.g. from within a GStreamer pipeline or from a call to ffmpeg. You need something like v4l2-relayd, which is a separate application, that starts and stops the GStreamer pipeline based on such events.

Also, there is no way to implement controls (gain, resolution, color temperature, etc.) on the virtual camera that could be passed through to the app that feeds the camera.

There is also akvcam, but it implements image processing in the kernel, which is gross.


Lovely!

I recently picked up a Creative Labs webcam with an LPT and PS/2 connector (probably used for power). I wanted to try it out on a W98 machine, but this inspires me to even try and write a driver for it.

A computer with LPT I have, now i just need to find the time :)


Holy shit!

LPT isn't a problem (besides the real memory access and something tells me it does) but PS/2... vood luck?

you wouldn't believe it but it's actually Shooting Stars playing RN


I suspect PS/2 is only used to get 5V, so not really used by the driver


“Do you pine for the days when men were men and wrote their own device drivers?” https://en.m.wikiquote.org/wiki/Linus_Torvalds

This was such a great read and took me back to the days when you had to figure out the right pin configuration on your modems and write device drivers for anything that was a bit fancy on Slackware.

Thanks for the nostalgia.


I’ve been curious for a while - would it make sense for some USB drivers to be adapted / recompiled to WASM and used via web pages? (Chrome can allow JS code to access USB devices)

Like in this case, would it have made sense to recreate the driver in this way so that other owners of the same camera could have immediately tried it out in their browsers regardless of their operating system?

How OS-specific are most USB devices?


Don't know about webcams - usually (unlike in OP's case) those already have good OS-level support, but I did port gphoto2 to Wasm+WebUSB for access to DSLRs & mirrorless cameras: https://github.com/GoogleChromeLabs/web-gphoto2


Amazing, thanks for sharing

And really great write up too!

https://web.dev/porting-libusb-to-webusb/


Thanks, be sure to check out the part 2 as well :)


On a tangentant note, I've considered if it would be possible to gut the driver related parts (usb / Bluetooth subsystem ect) of linux and package it up to run as a userspace application in windows.

Then we could all use ps3 dualshock controllers wireless again on windows. It seems all the links to third party programs to make it work are virus infected.


At first I thought the article was going to be a story of a young driver embarking upon an adventure to retrieve a webcam from 1999.


Yeah, me too. Had my brain in knots for half a minute.


1999 pffft. I have an original parallel port mono quickcam that i would like to use for partner meetings


Hah I knew it was that one. I had the same. Back in those days there were only a few models on the market. The quality was bad though and it was even black and white. This one is color so it must be a slightly later version.


I have an old industrial thermal camera that takes pretty good pictures. But I don't have the xp software for it, and without a "known good capture" it's hard to reverse engineer and make it work on Linux.


I have an ElGato capture device that doesn’t work with Linux - it’s the one right before the model that does work but is significantly more expensive. Maybe this can help me write a driver for it …


"Mission Success." - I kinda expected they would get a somewhat legible image and then pat themselves on the back. Oh well, at least there was a great interesting tidbits.


I wonder if you could have gotten the webcam to work on Windows 10 by installing the XP driver under compatibility mode.


>I wonder if you could have gotten the webcam to work on Windows 10 by installing the XP driver under compatibility mode.

There are a number of possibilities that might need to be attempted.

In the lab I've got a 20-year old USB HP Laserjet printer plugged into an XP PC which is on my local LAN. Not a network printer but shared with other PCs over the LAN. This was a business printer and the newest drivers were for Windows 7 until the fairly recent Universal Print Driver packages from HP, where the UPD driver supports it with Windows 10/11 when you plug the printer into the USB socket of the W11 PC.

But with the printer plugged directly into the XP PC, then a W11 workstation on the same LAN (with all the permissions right and everything) could still find the printer but not the drivers. You could manually install the printer using the UPD drivers which appeared successful, but it would not print whether you selectied it as default or not.

It was necessary to log in to W11 as an administrator, unzip the old XP drivers, then in File Explorer point to the exact INF file for the exact printer, and right-click for the context menu to Install the INF manually in the background.

No compatibility mode needed, W11 just finds & uses the XP drivers when it connects to the printer after that.

Old Intel USB webcams from 1998 still just plug right in since they were Intel and it's still Windows.

When XP came out it was interesting because a W9x Intel webcam no longer needed drivers and even without any cam app the cam appeared as a device in File Explorer. When you clicked on it in the left-hand panel, the live video appeared in the right-hand panel. Now you need an app but IIRC the built-in modern Windows app may not work. Might have to use Amcap.exe or something more legacy-capable.

Old USB joysticks which were supported in W9x are configured using the same interface as their analog predecessors, and conveniently some modern joysticks can still be configured using the legacy interface (with greatly reduced features) without using the specific hardware driver.


Linux has V4l-utils in order to set up some settings on any supported webcam (and TV tuner).

v4l2-ctl might help you a lot.


>This means that all attempts to get data from it using the first USB interface would fail. Now you might ask, why does the webcam have an endpoint with a 0 byte MaxPacketSize on its first interface? Who knows!

Paper cuts like this is why the Linux Desktop isn't mainstream.


Is..is it not the webcam that's reporting the endpoint? Not Linux?


Correct. This is inherent to the camera's USB descriptor; it's entirely independent of the OS being used to interact with the device.


I am not sure I fully understand what you mean by your remark, but I am positive that this is not a situation most “mainstream desktop users” are ever going to encounter.


Yeah, I mean there are a lot of reasons why linux desktop isn't going mainstream anytime soon, but this is certainly not one of them.


I'm pretty sure this is a quirk of the hardware that the Linux kernel has little control over.

Plus, at the end of the day this hardware actually worked. This process would have been far more involved if the author was on Windows or Mac.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: