Score:1

Logitech c930e focus reverts to default settings even with custom udev rules

cn flag

OS: Ubuntu 20.04 (Focal Fossa)

I recently bought a Logitech c930e camera for use in online proctored exams where the invigilator may ask for a government-issued ID to be shown. The camera has an autofocus functionality which can initially focus on close objects (if one is placed in front of the camera as it is started), but once it shifts its focus to distant objects, it cannot re-detect and refocus on close objects subsequently placed in front of the camera. This causes the text on government-issued IDs placed in front of the camera to become illegible.

After some initial research, it turns out I can install v4l-utils and obtain a list of parameters I can tune on the camera as follows (assuming the associated device node is /dev/video1):

$ v4l2-ctl -d /dev/video1 --list-ctrls

Filtering the output to only include focus-related options gives:

$ v4l2-ctl -d /dev/video1 --list-ctrls | grep focus
                 focus_absolute 0x009a090a (int)    : min=0 max=255 step=5 default=0 value=0 flags=inactive
                     focus_auto 0x009a090c (bool)   : default=1 value=1

So focus_auto is set to 1 and focus_absolute to 0 by default, which can also be seen by running the following commands:

$ v4l2-ctl -d /dev/video1 --get-ctrl focus_auto
focus_auto: 1
$ v4l2-ctl -d /dev/video1 --get-ctrl focus_absolute
focus_absolute: 0

After some manual experimentation, it seems that focus_auto: 0 and focus_absolute: 75 gives a good balance of making close-up text clear enough while not blurring distant objects too much:

$ v4l2-ctl -d /dev/video1 --set-ctrl focus_auto=0
$ v4l2-ctl -d /dev/video1 --set-ctrl focus_absolute=75

So I write a udev rules file /etc/udev/rules.d/90-logitech-c930e.rules for applying these settings:

KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="0843", RUN+="/usr/bin/v4l2-ctl -d $devnode --set-ctrl focus_auto=0", RUN+="/usr/bin/v4l2-ctl -d $devnode --set-ctrl focus_absolute=75"

This file can also be found on GitHub

The idVendor: 046d and idProduct: 0843 I obtained with lsusb:

$ lsusb | grep Logitech
Bus 001 Device 002: ID 046d:0843 Logitech, Inc. Webcam C930e

Then I restart systemd-udevd.service:

$ sudo systemctl restart systemd-udevd.service

Unplug the camera, and plug it back in. For the first few seconds, focus_auto is set to 0 and focus_absolute to 75 as expected:

$ v4l2-ctl -d /dev/video1 --get-ctrl focus_auto
focus_auto: 0
$ v4l2-ctl -d /dev/video1 --get-ctrl focus_absolute
focus_absolute: 75

But after a few dozen seconds at most, the settings are reverted to their defaults:

$ v4l2-ctl -d /dev/video1 --get-ctrl focus_auto
focus_auto: 1
$ v4l2-ctl -d /dev/video1 --get-ctrl focus_absolute
focus_absolute: 0

Why might that be? Is it possible to disable this behavior? If so, how?

Score:1
cn flag

After some extra research, it seems that automatically restoring default settings is A Feature, Not A Bug (TM): https://www.reddit.com/r/obs/comments/fflg5g/logitech_cam_keeps_resetting_video_settings_back/

So I came up with an idea: what if I could set the focus every few seconds or so, to prevent the settings from drifting back to defaults? It turns out this is possible, though not directly with udev since it's a long-running process and udev rules are blocking. Instead, I used a combination of udev rules, systemd device units and service units.

The high-level idea is as follows:

  • Create a udev rules file that tags systemd so that the associated device unit is created, and set SYSTEMD_WANTS to point to a service template unit file, passing the minor device number to the template
  • The service template unit runs a script, passing its argument (the minor device number) to the script
  • The script uses the minor device number to refer to the correct camera and set the focus parameters repeatedly on that camera, on an interval of 5 seconds

The detailed solution can be found in this gist.

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.