Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a v4l2 workaround so broken camera handles are disqualified from … #978

Merged
merged 3 commits into from
Jun 28, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
TojikCZ marked this conversation as resolved.
Show resolved Hide resolved
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
Loading