otaku42 / v4l2py

V4L2 python library
GNU General Public License v3.0
0 stars 0 forks source link

iter_read_controls() skips many control types #1

Closed otaku42 closed 1 year ago

otaku42 commented 1 year ago

According to v4l2-ctl, my Microsoft LifeCam Studio HD has more controls than those that v4l2py makes available in Device.controls.

v4l2-ctl -d /dev/video4 -L :

User Controls

                     brightness 0x00980900 (int)    : min=30 max=255 step=1 default=133 value=45
                       contrast 0x00980901 (int)    : min=0 max=10 step=1 default=5 value=3
                     saturation 0x00980902 (int)    : min=0 max=200 step=1 default=103 value=0
        white_balance_automatic 0x0098090c (bool)   : default=1 value=1
           power_line_frequency 0x00980918 (menu)   : min=0 max=2 default=2 value=2
                                0: Disabled
                                1: 50 Hz
                                2: 60 Hz
      white_balance_temperature 0x0098091a (int)    : min=2500 max=10000 step=1 default=4500 value=4500 flags=inactive
                      sharpness 0x0098091b (int)    : min=0 max=50 step=1 default=25 value=25
         backlight_compensation 0x0098091c (int)    : min=0 max=10 step=1 default=0 value=0

Camera Controls

                  auto_exposure 0x009a0901 (menu)   : min=0 max=3 default=3 value=3
                                1: Manual Mode
                                3: Aperture Priority Mode
         exposure_time_absolute 0x009a0902 (int)    : min=1 max=10000 step=1 default=156 value=156 flags=inactive
                   pan_absolute 0x009a0908 (int)    : min=-529200 max=529200 step=3600 default=0 value=0
                  tilt_absolute 0x009a0909 (int)    : min=-432000 max=432000 step=3600 default=0 value=0
                 focus_absolute 0x009a090a (int)    : min=0 max=40 step=1 default=0 value=0 flags=inactive
     focus_automatic_continuous 0x009a090c (bool)   : default=1 value=1
                  zoom_absolute 0x009a090d (int)    : min=0 max=317 step=1 default=0 value=0

whereas ...

import v4l2py

cam = v4l2py.Device("/dev/video4", True)
cam.open()
for c in cam.controls.values():
    print("0x%08x:" % c.id, c)
cam.close()

... just gives:

0x00980900: <Control name=Brightness, type=INTEGER, min=30, max=255, step=1>
0x00980901: <Control name=Contrast, type=INTEGER, min=0, max=10, step=1>
0x00980902: <Control name=Saturation, type=INTEGER, min=0, max=200, step=1>
0x0098091a: <Control name=White Balance Temperature, type=INTEGER, min=2500, max=10000, step=1>
0x0098091b: <Control name=Sharpness, type=INTEGER, min=0, max=50, step=1>
0x0098091c: <Control name=Backlight Compensation, type=INTEGER, min=0, max=10, step=1>
0x009a0902: <Control name=Exposure Time, Absolute, type=INTEGER, min=1, max=10000, step=1>
0x009a0908: <Control name=Pan, Absolute, type=INTEGER, min=-529200, max=529200, step=3600>
0x009a0909: <Control name=Tilt, Absolute, type=INTEGER, min=-432000, max=432000, step=3600>
0x009a090a: <Control name=Focus, Absolute, type=INTEGER, min=0, max=40, step=1>
0x009a090d: <Control name=Zoom, Absolute, type=INTEGER, min=0, max=317, step=1>

Note the missing controls of type bool and menu.

otaku42 commented 1 year ago

Debugging this issue took me by far longer than the short timespan between issue and this comment may suggest... :-)

This problem is caused by using V4L2_CTRL_TYPE_CTRL_CLASS in a bitmasking operation, although it's an integer (enum). As a result, iter_read_controls() skips all control classes except V4L2_CTRL_TYPE_INTEGER, V4L2_CTRL_TYPE_BITMASK and V4L2_CTRL_TYPE_INTEGER_MENU .