Skip to content

kittennbfive/kittenUVCcam

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

kittenUVCcam

A tool for getting video data and still images out of UVC compatible devices under Linux.

What is this?

This tool can be used for getting video data and still images from an UVC compatible device under Linux, like a webcam or microscope camera.

UVC (universal video class) is part of the USB standard (you can download all the details as pdf from the official USB website for free) and supported by Linux out of the box, but only for video. Still images (that might have much higher resolutions) are not supported, but i really needed them for using my new microscope camera (more story-telling at the end of this file). That's why i made this tool based on libusb and the UVC 1.1 specifications (UVC 1.5 is current but all devices i tested report UVC 1.0 for which i was unable to find the specifications online (anybody?)).

Licence and Disclaimer

The content of this repository is Copyright (c) 2026 by kittennbfive.

Licence: AGPLv3+

EVERYTHING IS PROVIDED WITHOUT ANY WARRANTY! THIS IS EXPERIMENTAL STUFF!

It was a huge pain writing/debugging this code. USB (even version 2.0) is a big and horribly complex thing and the UVC specifications, although only like 140 pages long, are not easy to understand (like always with specifications...). Expect bugs.

Why not improving the Linux V4L2 driver?

Linux drivers are really complex animals and i have almost no knowledge about how all this internal stuff works. A bad driver can make the computer freeze/crash or worse. Also i would have to recompile (and maybe modify) my code at every Kernel update. Even i where able (spoiler: i am not) to make a really good patch (read: code quality) that would go upstream into Linux it would take some (a lot of) time to get to Debian stable which i use. All this is not great as i needed a solution fast.

There is at least one modified driver with still image support on github, but it is very old and probably no longer compatible with recent Kernel versions.

The code

My tool is written in C and Linux only. Maybe there is a way to make it run on Windows but i can't and won't provide any support for this.

Dependencies

For compiling you need libusb. On Debian and derived try sudo apt install libusb-1.0-0-dev.
To run the tool you need ffplay as this is used to display the video stream. If not already installed try sudo apt install ffmpeg (ffplay is part of this).

Code structure

There are two parts:

  • descriptors.{c,h} for parsing the USB descriptors (really fun stuff!) and extracting all needed informations about the device (like resolutions, ...).
  • main.c for the actual tool.

Compiling

Use gcc -Wall -Wextra -Werror -O3 -o kuvccam main.c descriptors.c -lusb-1.0.

Adjustments

There are some #define at the beginning of main.c, 2 of them might need tweaking:

  • NB_USB_ISO_PACKETS is the number of packets inside a single USB isochronous transfer. 32 seems to work fine and is used by ffplay and/or VLC (and the proprietary tool that came with my camera, see below).
  • NB_PARALLEL_ISO_TRANSFERS is the number of parallel USB isochronous transfers (with NB_USB_ISO_PACKETS packets inside each transfer). This seems to be needed to get smooth video for some devices (especially an old webcam i used for testing).

Usage

This tool as 2 modes:

  • interactive mode that let you choose the device and resolutions for video and still images.
  • automatic mode that will auto-select the highest resolutions for both modes.

Interactive mode

Just run the tool without arguments and select what you want.

Automatic mode

Run the tool with the VID and PID of your device as a single argument ("vvvv:pppp" in hex without leading "0x").

General usage

If supported by your device you can press the 's' key to save a still image in the folder where the executable is. Note that the key press must go to the tool (the terminal window inside which the tool runs), not to the ffplay window (nothing will happen).
To stop press the 'q' key while any of both window (tool or ffplay) has focus. If ffplay had focus when you press 'q' the tool will tell you about a "broken pipe", this is normal.

Limitations

Kernel and library versions

At some point the code uses a "simplified method" for libusb event-handling that will only work with:

Linux v2.6.27 or newer, compiled with timerfd support
glibc v2.9 or newer
libusb v1.0.5 or newer

(from https://libusb.sourceforge.io/api-1.0/group__libusb__poll.html)

Still image mode

To be able to get still images your device must support what is called "mode 2" in the UVC specifications. If your device does not support this mode (or still images at all) the tool will still run but is somewhat "useless", just use ffplay via V4L2 (/dev/videoX) or whatever media player you want (like VLC) directly. I could have made this a fatal error in my code but making still image support optional allows to test the code with more devices (as said in a comment somewhere in the code).

Image format

Only MJPEG and uncompressed YUY2 are supported. Uncompressed NV12 is not supported because i don't have a device that can output this for testing.

"access denied"-trouble

If you can't access your device you may need to add an udev rule for it. Something like

#/etc/udev/rules.d/some_file_name.rules
ATTR{idVendor}=="vvvv", ATTR{idProduct}=="pppp", MODE="660", GROUP="plugdev"

will work, assuming you are in the plugdev group. Adjust file name as needed and replace vvvv/pppp with VID/PID of your device.
For single-shot testing you can also use lsusb to see where the device is connected and try something like sudo chown root:plugdev /dev/bus/usb/$BUS/$DEVICE (replace $BUS and $DEVICE with numbers you got from lsusb or similar - these are not VID and PID).

Some background story

(You can skip this part.)
I have a microscope for delicate electronics work and bought a new, cheap camera (from Aliexpress) with higher resolution and an USB connector to be able to get pictures into the PC more easely than using a HDMI to USB converter. The camera works and can be powered directly from USB (which is good as i really don't trust the very light PSU), although the image quality is not great (you get what you pay for i guess...). This is why i won't provide the exact name of the device, at least for now. The camera does work out of the box with VLC and ffplay on Linux (using V4L2), but as i said there is no way to take still images with (much) higher resolution than the video stream. There is some software provided with the camera (on a CD...), but it is Windows only and closed source. The software can do more than display the video stream and take still images (like making measurements on the video stream), but i don't need all that.
I installed the software on Windows inside a VM and sniffed the USB packets using Wireshark (really a great tool). I discovered quite quickly that the camera follows the UVC standard, but then - big disappointment - i also discovered that Linux (V4L2) does not support still images. So i began experimenting. A lot of time (and pulled hair) later i had about 1200 LOC (currently)...

How to report a bug

If you try this tool with a device and it does not work please include the output of lsusb -v -d vvvv:pppp in your issue (as an attachment if it is really long). Also compile the code with DEBUG_VERBOSE_MODE defined in both files (main.c and descriptors.c) and include the output too. You can also do the same thing with DEBUG_VERBOSE_CB_TRANSFER but you will need to cut down the result, it can be really long.

About

A tool for getting video data and still images out of UVC compatible devices under Linux.

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages