Lots of us have to use webcams more than we used to. There have been some
recent changes in OpenBSD support for webcams that some might find useful.
Most of the hard work was done by Marcus Glocker, with input from Ingo
Feinerer, sc.dying, and myself.

The first change is that MJPEG in cameras now works reliably. In essence,
most webcams can deliver uncompressed video at a low frame rate or
compressed (MJPEG) at a high frame rate. The latter tickled a limitation in
the USB stack, which led to the picture breaking up -- and which is now
fixed! If you want to know what your camera is capable of, my suggestion is
to install ffmpeg and then run:

  $ ffplay -f v4l2 -list_formats all -i /dev/video0

which will output lots of stuff, but at the end has the important bits:

  [video4linux2,v4l2 @ 0x914fbbb6000] Raw       :     yuyv422 :                 
YUYV : 640x480 160x90 160x120 176x144 320x180 320x240 352x288 432x240 640x360 
800x448 800x600 864x480 960x720 1024x576 1280x720 1600x896 1920x1080 2304x1296 
2304x1536
  [video4linux2,v4l2 @ 0x914fbbb6000] Compressed:       mjpeg :                
MJPEG : 640x480 160x90 160x120 176x144 320x180 320x240 352x288 432x240 640x360 
800x448 800x600 864x480 960x720 1024x576 1280x720 1600x896 1920x1080

This shows that my C920s webcam has a maximum MJPEG resolution of 1920x1080.
The "raw" options (yuyv422) might look tempting as they have a max
resolution of 2304x1536, but "video -q" shows they can only achieve low
frame rates:

  $ video -q
  video device /dev/video:
    encodings: yuy2
    frame sizes (width x height, in pixels) and rates (in frames per second):
        160x90: 30, 24, 20, 15, 10, 7, 5
        160x120: 30, 24, 20, 15, 10, 7, 5
        176x144: 30, 24, 20, 15, 10, 7, 5
        320x180: 30, 24, 20, 15, 10, 7, 5
        320x240: 30, 24, 20, 15, 10, 7, 5
        352x288: 30, 24, 20, 15, 10, 7, 5
        432x240: 30, 24, 20, 15, 10, 7, 5
        640x360: 30, 24, 20, 15, 10, 7, 5
        640x480: 30, 24, 20, 15, 10, 7, 5
        800x448: 30, 24, 20, 15, 10, 7, 5
        800x600: 24, 20, 15, 10, 7, 5
        864x480: 24, 20, 15, 10, 7, 5
        960x720: 15, 10, 7, 5
        1024x576: 15, 10, 7, 5
        1280x720: 10, 7, 5
        1600x896: 7, 5
        1920x1080: 5
        2304x1296: 2
        2304x1536: 2
    controls: brightness, contrast, saturation, gain, sharpness, 
white_balance_temperature

As that suggests, video(1) only easily supports YUY2/YUYV422. The easiest
way to see higher frame rates I know of is to use ffmpeg. Most cameras can
sustain 30fps (or sometimes 60fps) at high resolutions as can be seen with:

  $ ffplay -f v4l2 -input_format mjpeg -video_size 1920x1080 -i /dev/video0

If you use video chat in a browser, you should find that it can now reliably
support higher resolutions without problems.

video(1) has also been extended to allow altering webcam controls from the
command-line. In order to do this, nothing else can be using the webcam;
however, the settings are "sticky" so they effect subsequent programs which
use the webcam. I can see the current settings with:

  $ video -c
  brightness=128
  contrast=128
  saturation=128
  gain=0
  sharpness=128
  white_balance_temperature=auto

and I can reset things back to a known state with:

  $ video -d

I can change e.g. brightness with:

  $ video brightness=200
  brightness: 128 -> 200

Some, though not all, controls have automatic adjustment. If your webcam has
the white_balance_temperature control, it probably defaults to "auto",
meaning that it tries to adjust based on how yellow/white it thinks the
light is. In my experience, the automatic adjustment ends up making
everything look like a Smurfs homage (i.e. too blue). video(1) allows us to
override the automatic setting and specify a temperature manually (in
Kelvin). During the day I might use:

  $ video white_balance_temperature=5000
  white_balance_temperature: auto -> 5000

If you really want, you can use "auto" as a value for such controls instead
of a numeric value. Note further that if you're used to other operating
systems webcam support, you might expect there to be two white balance
temperature controls (one for the manual temperature and a separate auto
boolean): video(1) unifies them.

You can specify multiple controls at once e.g.:

  $ video brightness=50 white_balance_temperature=3000
  brightness: 128 -> 50
  white_balance_temperature: auto -> 3000

Be aware that uvideo doesn't yet support the "camera terminal control
requests" part of the UVC spec so some controls (e.g. zoom, pan, and
exposure) cannot be altered. If and when uvideo gains such support, the
necessary changes to video(1) will be trivial.

Overall, I think this makes webcams much more usable under OpenBSD, and
thanks again to Marcus, because none of this would have happened without
him!


Laurie

Reply via email to