Skip to content

Commit 4b535bd

Browse files
steveseguinactions-user
authored andcommitted
fix(rpi): Auto-detect and prefer v4l2 for UVC on GStreamer < 1.20
Address `libcamerasrc` instability with USB/UVC capture devices (e.g., MacroSilicon HDMI dongles) on older GStreamer builds (specifically 1.18.x). - Introduce logic in `publish.py` to check the installed GStreamer version. - If GStreamer is less than 1.20 and `libcamera` is not explicitly requested, automatically scan `/dev/video*` for known UVC devices. - Force the use of `v4l2src` for these specific UVC devices to ensure stable video capture. - This prevents the use of potentially unstable `libcamerasrc` for UVC sources on affected GStreamer versions. - Remove prior generic `usbcam` detection logic, which is superseded by this targeted approach. [auto-enhanced]
1 parent 41b10b8 commit 4b535bd

1 file changed

Lines changed: 24 additions & 6 deletions

File tree

publish.py

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11823,7 +11823,30 @@ async def main():
1182311823
print("")
1182411824

1182511825
elif args.rpi and not args.v4l2 and not args.hdmi and not args.rpicam and not args.z1:
11826-
if check_plugins(['libcamera']):
11826+
gst_ver = Gst.version()
11827+
11828+
# On older GStreamer builds (notably 1.18), libcamerasrc can be unstable with some
11829+
# USB/UVC capture devices (eg MacroSilicon HDMI dongles). Prefer v4l2src in that case.
11830+
if gst_ver.major == 1 and gst_ver.minor < 20 and not args.libcamera:
11831+
for i in range(10):
11832+
candidate = f"/dev/video{i}"
11833+
if not os.path.exists(candidate) or not os.access(candidate, os.R_OK):
11834+
continue
11835+
name = None
11836+
try:
11837+
with open(f"/sys/class/video4linux/video{i}/name", "r", encoding="utf-8") as f:
11838+
name = f.read().strip()
11839+
except Exception:
11840+
pass
11841+
if not name:
11842+
continue
11843+
name_l = name.lower()
11844+
if "uvc" in name_l or "usb vid" in name_l or "macrosilicon" in name_l or "ms2109" in name_l:
11845+
args.v4l2 = candidate
11846+
print(f"Auto-selected video device: {candidate} ({name})")
11847+
break
11848+
11849+
if not args.v4l2 and check_plugins(['libcamera']):
1182711850
args.libcamera = True
1182811851

1182911852
monitor = Gst.DeviceMonitor.new()
@@ -11846,11 +11869,6 @@ async def main():
1184611869
if len(picam):
1184711870
args.rpicam = True
1184811871

11849-
usbcam = [d for d in devices if "USB Vid" in d.get_display_name()]
11850-
11851-
if len(usbcam) and not args.v4l2:
11852-
args.v4l2 = "/dev/video0"
11853-
1185411872
elif not args.v4l2:
1185511873
args.v4l2 = '/dev/video0'
1185611874

0 commit comments

Comments
 (0)