Skip to content

Commit

Permalink
Add a v4l2 workaround so broken camera handles are disqualified from …
Browse files Browse the repository at this point in the history
…scan
  • Loading branch information
TojikCZ authored and ondratu committed Jun 28, 2024
1 parent 1dd52cc commit 59bcdee
Showing 1 changed file with 76 additions and 72 deletions.
148 changes: 76 additions & 72 deletions prusa/link/cameras/v4l2_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,83 +110,84 @@ def read_capabilities(file_descriptor):

def read_info(filename):
"""Reads device specific info needed for device initialization"""
file_descriptor = fopen(filename)
caps = read_capabilities(file_descriptor)
version_tuple = (
(caps.version & 0xFF0000) >> 16,
(caps.version & 0x00FF00) >> 8,
(caps.version & 0x0000FF),
)
version_str = ".".join(map(str, version_tuple))
device_capabilities = caps.capabilities
with fopen(filename) as file_descriptor:
caps = read_capabilities(file_descriptor)
version_tuple = (
(caps.version & 0xFF0000) >> 16,
(caps.version & 0x00FF00) >> 8,
(caps.version & 0x0000FF),
)
version_str = ".".join(map(str, version_tuple))
device_capabilities = caps.capabilities

formats = []
pixel_formats = set()
formats = []
pixel_formats = set()

fmt = v4l2.v4l2_fmtdesc()
fmt.type = STREAM_TYPE
for index in range(128):
fmt.index = index
try:
fcntl.ioctl(file_descriptor, v4l2.VIDIOC_ENUM_FMT, fmt)
except OSError as error:
if error.errno == errno.EINVAL:
break
raise
try:
pixel_format = fmt.pixelformat
except ValueError:
continue
formats.append(
ImageFormat(
type=STREAM_TYPE,
flags=fmt.flags,
description=fmt.description.decode(),
pixel_format=pixel_format,
),
)
pixel_formats.add(pixel_format)

focus_info = None

focus_auto = v4l2_queryctrl()
focus_auto.id = V4L2_CID_FOCUS_AUTO

focus_absolute = v4l2_queryctrl()
focus_absolute.id = V4L2_CID_FOCUS_ABSOLUTE

fmt = v4l2.v4l2_fmtdesc()
fmt.type = STREAM_TYPE
for index in range(128):
fmt.index = index
try:
fcntl.ioctl(file_descriptor, v4l2.VIDIOC_ENUM_FMT, fmt)
except OSError as error:
if error.errno == errno.EINVAL:
break
raise
try:
pixel_format = fmt.pixelformat
except ValueError:
continue
formats.append(
ImageFormat(
type=STREAM_TYPE,
flags=fmt.flags,
description=fmt.description.decode(),
pixel_format=pixel_format,
),
)
pixel_formats.add(pixel_format)

focus_info = None

focus_auto = v4l2_queryctrl()
focus_auto.id = V4L2_CID_FOCUS_AUTO

focus_absolute = v4l2_queryctrl()
focus_absolute.id = V4L2_CID_FOCUS_ABSOLUTE

try:
if fcntl.ioctl(file_descriptor, VIDIOC_QUERYCTRL, focus_auto) != 0:
raise RuntimeError("Unable to get focus auto")
if fcntl.ioctl(file_descriptor, VIDIOC_QUERYCTRL, focus_absolute) != 0:
raise RuntimeError("Unable to get focus absolute")
except (OSError, RuntimeError):
focus_info = FocusInfo(
available=False,
min=None,
max=None,
step=None,
)
else:
focus_info = FocusInfo(
available=True,
min=focus_absolute.minimum,
max=focus_absolute.maximum,
step=focus_absolute.step,
if fcntl.ioctl(file_descriptor, VIDIOC_QUERYCTRL, focus_auto) != 0:
raise RuntimeError("Unable to get focus auto")
if fcntl.ioctl(
file_descriptor, VIDIOC_QUERYCTRL, focus_absolute) != 0:
raise RuntimeError("Unable to get focus absolute")
except (OSError, RuntimeError):
focus_info = FocusInfo(
available=False,
min=None,
max=None,
step=None,
)
else:
focus_info = FocusInfo(
available=True,
min=focus_absolute.minimum,
max=focus_absolute.maximum,
step=focus_absolute.step,
)

return Info(
driver=caps.driver.decode(),
card=caps.card.decode(),
bus_info=caps.bus_info.decode(),
version=version_str,
physical_capabilities=caps.capabilities,
capabilities=device_capabilities,
formats=formats,
frame_sizes=frame_sizes(file_descriptor, pixel_formats),
focus_info=focus_info,
)

return Info(
driver=caps.driver.decode(),
card=caps.card.decode(),
bus_info=caps.bus_info.decode(),
version=version_str,
physical_capabilities=caps.capabilities,
capabilities=device_capabilities,
formats=formats,
frame_sizes=frame_sizes(file_descriptor, pixel_formats),
focus_info=focus_info,
)


def fopen(path, write=False):
"""Opens a specified video device file"""
Expand Down Expand Up @@ -487,6 +488,9 @@ def _scan():
if IGNORED_BUS_INFO_REGEX.match(device.info.bus_info) is not None:
continue

if not device.info.formats:
continue

media_device_path = get_media_device_path(device)
if media_device_path is None:
continue
Expand Down

0 comments on commit 59bcdee

Please sign in to comment.