libusb / hidapi

A Simple cross-platform library for communicating with HID devices
https://libusb.info/hidapi/
Other
1.6k stars 391 forks source link

Device read hangs while streaming with V4L2 #177

Closed fgervais closed 4 years ago

fgervais commented 4 years ago

I'm reading from an hid device using hidapi in python through a libusb backend while also streaming images from a webcam

Only reading from the hid device by itself is fine but if I do so while streaming from the webcam, the hid.read(64) hangs.

Here my reproduction code:

import cv2
import time
import hid

_hid = hid.device()
_hid.open(0x04D8, 0x00DD)

video_capture = cv2.VideoCapture(0)
video_capture.set(cv2.CAP_PROP_BUFFERSIZE, 1)
video_capture.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
video_capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)

while True:
    report = b"\x10"
    _hid.write(b"\0" + report + b"\0" * (64 - len(report)))
    print("HID"*10)
    print(_hid.read(64))

    print("READ"*10)
    success, frame = video_capture.read()
    print(success)
    time.sleep(1)

and here the strace output with some added "\n" to make it somewhat nicer to read:

You can see the I can read properly from the hid device, then I do the video_capture.read() and on the second loop I cannot read from the device anymore. I hangs there forever.

openat(AT_FDCWD, "/dev/video0", O_RDWR|O_NONBLOCK) = 10
ioctl(10, VIDIOC_QUERYCAP, {driver="uvcvideo", card="USB 2.0 Camera: HD USB Camera", bus_info="usb-0000:01:00.0-1.1", version=4.19.118, capabilities=V4L2_CAP_VIDEO_CAPTURE|V4L2_CAP_STREAMING|V4L2_CAP_DEVICE_CAPS|V4L2_CAP_EXT_PIX_FORMAT|V4L2_CAP_META_CAPTURE, device_caps=V4L2_CAP_VIDEO_CAPTURE|V4L2_CAP_STREAMING|V4L2_CAP_EXT_PIX_FORMAT}) = 0
ioctl(10, VIDIOC_G_FMT, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, fmt.pix={width=320, height=240, pixelformat=v4l2_fourcc('Y', 'U', 'Y', 'V') /* V4L2_PIX_FMT_YUYV */, field=V4L2_FIELD_NONE, bytesperline=640, sizeimage=153600, colorspace=V4L2_COLORSPACE_SRGB}}) = 0
ioctl(10, VIDIOC_S_FMT, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, fmt.pix={width=640, height=480, pixelformat=v4l2_fourcc('B', 'G', 'R', '3') /* V4L2_PIX_FMT_BGR24 */, field=V4L2_FIELD_ANY, bytesperline=0, sizeimage=0, colorspace=0 /* V4L2_COLORSPACE_??? */} => fmt.pix={width=640, height=480, pixelformat=v4l2_fourcc('Y', 'U', 'Y', 'V') /* V4L2_PIX_FMT_YUYV */, field=V4L2_FIELD_NONE, bytesperline=1280, sizeimage=614400, colorspace=V4L2_COLORSPACE_SRGB}}) = 0
ioctl(10, VIDIOC_S_FMT, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, fmt.pix={width=640, height=480, pixelformat=v4l2_fourcc('R', 'G', 'B', '3') /* V4L2_PIX_FMT_RGB24 */, field=V4L2_FIELD_ANY, bytesperline=0, sizeimage=0, colorspace=0 /* V4L2_COLORSPACE_??? */} => fmt.pix={width=640, height=480, pixelformat=v4l2_fourcc('Y', 'U', 'Y', 'V') /* V4L2_PIX_FMT_YUYV */, field=V4L2_FIELD_NONE, bytesperline=1280, sizeimage=614400, colorspace=V4L2_COLORSPACE_SRGB}}) = 0
ioctl(10, VIDIOC_S_FMT, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, fmt.pix={width=640, height=480, pixelformat=v4l2_fourcc('Y', 'V', '1', '2') /* V4L2_PIX_FMT_YVU420 */, field=V4L2_FIELD_ANY, bytesperline=0, sizeimage=0, colorspace=0 /* V4L2_COLORSPACE_??? */} => fmt.pix={width=640, height=480, pixelformat=v4l2_fourcc('Y', 'U', 'Y', 'V') /* V4L2_PIX_FMT_YUYV */, field=V4L2_FIELD_NONE, bytesperline=1280, sizeimage=614400, colorspace=V4L2_COLORSPACE_SRGB}}) = 0
ioctl(10, VIDIOC_S_FMT, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, fmt.pix={width=640, height=480, pixelformat=v4l2_fourcc('Y', 'U', '1', '2') /* V4L2_PIX_FMT_YUV420 */, field=V4L2_FIELD_ANY, bytesperline=0, sizeimage=0, colorspace=0 /* V4L2_COLORSPACE_??? */} => fmt.pix={width=640, height=480, pixelformat=v4l2_fourcc('Y', 'U', 'Y', 'V') /* V4L2_PIX_FMT_YUYV */, field=V4L2_FIELD_NONE, bytesperline=1280, sizeimage=614400, colorspace=V4L2_COLORSPACE_SRGB}}) = 0
ioctl(10, VIDIOC_S_FMT, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, fmt.pix={width=640, height=480, pixelformat=v4l2_fourcc('4', '1', '1', 'P') /* V4L2_PIX_FMT_YUV411P */, field=V4L2_FIELD_ANY, bytesperline=0, sizeimage=0, colorspace=0 /* V4L2_COLORSPACE_??? */} => fmt.pix={width=640, height=480, pixelformat=v4l2_fourcc('Y', 'U', 'Y', 'V') /* V4L2_PIX_FMT_YUYV */, field=V4L2_FIELD_NONE, bytesperline=1280, sizeimage=614400, colorspace=V4L2_COLORSPACE_SRGB}}) = 0
ioctl(10, VIDIOC_S_FMT, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, fmt.pix={width=640, height=480, pixelformat=v4l2_fourcc('Y', 'U', 'Y', 'V') /* V4L2_PIX_FMT_YUYV */, field=V4L2_FIELD_ANY, bytesperline=0, sizeimage=0, colorspace=0 /* V4L2_COLORSPACE_??? */} => fmt.pix={width=640, height=480, pixelformat=v4l2_fourcc('Y', 'U', 'Y', 'V') /* V4L2_PIX_FMT_YUYV */, field=V4L2_FIELD_NONE, bytesperline=1280, sizeimage=614400, colorspace=V4L2_COLORSPACE_SRGB}}) = 0
ioctl(10, VIDIOC_S_PARM, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, parm.capture={capability=0, capturemode=0, timeperframe=1/30, extendedmode=0, readbuffers=0} => parm.capture={capability=0, capturemode=0, timeperframe=1/30, extendedmode=0, readbuffers=0}}) = 0
ioctl(10, VIDIOC_G_PARM, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, parm.capture={capability=V4L2_CAP_TIMEPERFRAME, capturemode=0, timeperframe=1/30, extendedmode=0, readbuffers=0}}) = 0
ioctl(10, VIDIOC_REQBUFS, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, memory=V4L2_MEMORY_MMAP, count=4 => 4}) = 0
ioctl(10, VIDIOC_QUERYBUF, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, index=0, memory=V4L2_MEMORY_MMAP, m.offset=0, length=614400, bytesused=0, flags=V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC|V4L2_BUF_FLAG_TSTAMP_SRC_SOE, ...}) = 0
mmap2(NULL, 614400, PROT_READ, MAP_SHARED, 10, 0) = 0xad039000
ioctl(10, VIDIOC_QUERYBUF, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, index=1, memory=V4L2_MEMORY_MMAP, m.offset=0x96000, length=614400, bytesused=0, flags=V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC|V4L2_BUF_FLAG_TSTAMP_SRC_SOE, ...}) = 0
mmap2(NULL, 614400, PROT_READ, MAP_SHARED, 10, 0x96000) = 0xace6a000
ioctl(10, VIDIOC_QUERYBUF, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, index=2, memory=V4L2_MEMORY_MMAP, m.offset=0x12c000, length=614400, bytesused=0, flags=V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC|V4L2_BUF_FLAG_TSTAMP_SRC_SOE, ...}) = 0
mmap2(NULL, 614400, PROT_READ, MAP_SHARED, 10, 0x12c000) = 0xacdd4000
ioctl(10, VIDIOC_QUERYBUF, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, index=3, memory=V4L2_MEMORY_MMAP, m.offset=0x1c2000, length=614400, bytesused=0, flags=V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC|V4L2_BUF_FLAG_TSTAMP_SRC_SOE, ...}) = 0
mmap2(NULL, 614400, PROT_READ, MAP_SHARED, 10, 0x1c2000) = 0xacd3e000
mmap2(NULL, 618496, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xacca7000
mmap2(NULL, 925696, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xacbc5000
munmap(0xacbc5000, 925696)              = 0
munmap(0xacca7000, 618496)              = 0
munmap(0xad039000, 614400)              = 0
munmap(0xace6a000, 614400)              = 0
munmap(0xacdd4000, 614400)              = 0
munmap(0xacd3e000, 614400)              = 0
ioctl(10, VIDIOC_REQBUFS, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, memory=V4L2_MEMORY_MMAP, count=0 => 0}) = 0
ioctl(10, VIDIOC_QUERYCAP, {driver="uvcvideo", card="USB 2.0 Camera: HD USB Camera", bus_info="usb-0000:01:00.0-1.1", version=4.19.118, capabilities=V4L2_CAP_VIDEO_CAPTURE|V4L2_CAP_STREAMING|V4L2_CAP_DEVICE_CAPS|V4L2_CAP_EXT_PIX_FORMAT|V4L2_CAP_META_CAPTURE, device_caps=V4L2_CAP_VIDEO_CAPTURE|V4L2_CAP_STREAMING|V4L2_CAP_EXT_PIX_FORMAT}) = 0
ioctl(10, VIDIOC_G_FMT, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, fmt.pix={width=640, height=480, pixelformat=v4l2_fourcc('Y', 'U', 'Y', 'V') /* V4L2_PIX_FMT_YUYV */, field=V4L2_FIELD_NONE, bytesperline=1280, sizeimage=614400, colorspace=V4L2_COLORSPACE_SRGB}}) = 0
ioctl(10, VIDIOC_S_FMT, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, fmt.pix={width=640, height=480, pixelformat=v4l2_fourcc('Y', 'U', 'Y', 'V') /* V4L2_PIX_FMT_YUYV */, field=V4L2_FIELD_ANY, bytesperline=0, sizeimage=0, colorspace=0 /* V4L2_COLORSPACE_??? */} => fmt.pix={width=640, height=480, pixelformat=v4l2_fourcc('Y', 'U', 'Y', 'V') /* V4L2_PIX_FMT_YUYV */, field=V4L2_FIELD_NONE, bytesperline=1280, sizeimage=614400, colorspace=V4L2_COLORSPACE_SRGB}}) = 0
ioctl(10, VIDIOC_S_PARM, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, parm.capture={capability=0, capturemode=0, timeperframe=1/30, extendedmode=0, readbuffers=0} => parm.capture={capability=0, capturemode=0, timeperframe=1/30, extendedmode=0, readbuffers=0}}) = 0
ioctl(10, VIDIOC_G_PARM, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, parm.capture={capability=V4L2_CAP_TIMEPERFRAME, capturemode=0, timeperframe=1/30, extendedmode=0, readbuffers=0}}) = 0
ioctl(10, VIDIOC_REQBUFS, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, memory=V4L2_MEMORY_MMAP, count=1 => 1}) = 0
ioctl(10, VIDIOC_QUERYBUF, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, index=0, memory=V4L2_MEMORY_MMAP, m.offset=0, length=614400, bytesused=0, flags=V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC|V4L2_BUF_FLAG_TSTAMP_SRC_SOE, ...}) = 0
mmap2(NULL, 614400, PROT_READ, MAP_SHARED, 10, 0) = 0xad039000
mmap2(NULL, 618496, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xace69000
mmap2(NULL, 925696, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xacd87000
munmap(0xacd87000, 925696)              = 0
munmap(0xace69000, 618496)              = 0
munmap(0xad039000, 614400)              = 0
ioctl(10, VIDIOC_REQBUFS, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, memory=V4L2_MEMORY_MMAP, count=0 => 0}) = 0
ioctl(10, VIDIOC_QUERYCAP, {driver="uvcvideo", card="USB 2.0 Camera: HD USB Camera", bus_info="usb-0000:01:00.0-1.1", version=4.19.118, capabilities=V4L2_CAP_VIDEO_CAPTURE|V4L2_CAP_STREAMING|V4L2_CAP_DEVICE_CAPS|V4L2_CAP_EXT_PIX_FORMAT|V4L2_CAP_META_CAPTURE, device_caps=V4L2_CAP_VIDEO_CAPTURE|V4L2_CAP_STREAMING|V4L2_CAP_EXT_PIX_FORMAT}) = 0
ioctl(10, VIDIOC_G_FMT, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, fmt.pix={width=640, height=480, pixelformat=v4l2_fourcc('Y', 'U', 'Y', 'V') /* V4L2_PIX_FMT_YUYV */, field=V4L2_FIELD_NONE, bytesperline=1280, sizeimage=614400, colorspace=V4L2_COLORSPACE_SRGB}}) = 0
ioctl(10, VIDIOC_S_FMT, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, fmt.pix={width=320, height=240, pixelformat=v4l2_fourcc('Y', 'U', 'Y', 'V') /* V4L2_PIX_FMT_YUYV */, field=V4L2_FIELD_ANY, bytesperline=0, sizeimage=0, colorspace=0 /* V4L2_COLORSPACE_??? */} => fmt.pix={width=320, height=240, pixelformat=v4l2_fourcc('Y', 'U', 'Y', 'V') /* V4L2_PIX_FMT_YUYV */, field=V4L2_FIELD_NONE, bytesperline=640, sizeimage=153600, colorspace=V4L2_COLORSPACE_SRGB}}) = 0
ioctl(10, VIDIOC_S_PARM, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, parm.capture={capability=0, capturemode=0, timeperframe=1/30, extendedmode=0, readbuffers=0} => parm.capture={capability=0, capturemode=0, timeperframe=1/30, extendedmode=0, readbuffers=0}}) = 0
ioctl(10, VIDIOC_G_PARM, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, parm.capture={capability=V4L2_CAP_TIMEPERFRAME, capturemode=0, timeperframe=1/30, extendedmode=0, readbuffers=0}}) = 0
ioctl(10, VIDIOC_REQBUFS, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, memory=V4L2_MEMORY_MMAP, count=1 => 1}) = 0
ioctl(10, VIDIOC_QUERYBUF, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, index=0, memory=V4L2_MEMORY_MMAP, m.offset=0, length=153600, bytesused=0, flags=V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC|V4L2_BUF_FLAG_TSTAMP_SRC_SOE, ...}) = 0
mmap2(NULL, 153600, PROT_READ, MAP_SHARED, 10, 0) = 0xad0a9000
mmap2(NULL, 233472, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xad070000
clock_gettime(CLOCK_MONOTONIC, {tv_sec=92256, tv_nsec=773634839}) = 0
timerfd_settime(8, TFD_TIMER_ABSTIME, {it_interval={tv_sec=0, tv_nsec=0}, it_value={tv_sec=92257, tv_nsec=773634000}}, NULL) = 0

ioctl(9, USBDEVFS_SUBMITURB, 0x22db8e0) = 0
clock_gettime(CLOCK_REALTIME, {tv_sec=1594160917, tv_nsec=120827536}) = 0
futex(0x22ecf50, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 0, {tv_sec=1594160977, tv_nsec=120827536}, FUTEX_BITSET_MATCH_ANY) = 0
futex(0x22ecf10, FUTEX_WAKE_PRIVATE, 1) = 0
write(1, "HIDHIDHIDHIDHIDHIDHIDHIDHIDHID", 30HIDHIDHIDHIDHIDHIDHIDHIDHIDHID) = 30
write(1, "\n", 1
)                       = 1
write(1, "[16, 0, 0, 0, 0, 0, 0, 0, 0, 0, "..., 223[16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 241, 117, 240, 0, 0, 0, 48, 48, 11, 48, 7, 35, 55, 212, 7, 0, 0, 38, 144, 20, 65, 54, 49, 50, 255, 3, 0, 0, 254, 3, 253, 2, 192, 1, 0, 0, 0, 0]) = 223
write(1, "\n", 1
)                       = 1
write(1, "READREADREADREADREADREADREADREAD"..., 40READREADREADREADREADREADREADREADREADREAD) = 40
write(1, "\n", 1
)                       = 1
ioctl(10, VIDIOC_QBUF, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, index=0, memory=V4L2_MEMORY_MMAP, m.offset=0, length=153600, bytesused=0, flags=V4L2_BUF_FLAG_MAPPED|V4L2_BUF_FLAG_QUEUED|V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC|V4L2_BUF_FLAG_TSTAMP_SRC_SOE, ...}) = 0
ioctl(10, VIDIOC_STREAMON, [V4L2_BUF_TYPE_VIDEO_CAPTURE]) = 0
ioctl(10, VIDIOC_DQBUF, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE}) = -1 EAGAIN (Resource temporarily unavailable)
_newselect(11, [10], NULL, NULL, {tv_sec=10, tv_usec=0}) = 1 (in [10], left {tv_sec=9, tv_usec=904183})
ioctl(10, VIDIOC_DQBUF, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, index=0, memory=V4L2_MEMORY_MMAP, m.offset=0, length=153600, bytesused=153600, flags=V4L2_BUF_FLAG_MAPPED|V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC|V4L2_BUF_FLAG_TSTAMP_SRC_SOE, timestamp = {tv_sec=92256, tv_usec=865418}, ...}) = 0
ioctl(10, VIDIOC_QBUF, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, index=0, memory=V4L2_MEMORY_MMAP, m.offset=0, length=153600, bytesused=0, flags=V4L2_BUF_FLAG_MAPPED|V4L2_BUF_FLAG_QUEUED|V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC|V4L2_BUF_FLAG_TSTAMP_SRC_SOE, ...}) = 0
ioctl(10, VIDIOC_DQBUF, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE}) = -1 EAGAIN (Resource temporarily unavailable)
_newselect(11, [10], NULL, NULL, {tv_sec=10, tv_usec=0}) = 1 (in [10], left {tv_sec=9, tv_usec=938565})
ioctl(10, VIDIOC_DQBUF, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, index=0, memory=V4L2_MEMORY_MMAP, m.offset=0, length=153600, bytesused=153600, flags=V4L2_BUF_FLAG_MAPPED|V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC|V4L2_BUF_FLAG_TSTAMP_SRC_SOE, timestamp = {tv_sec=92256, tv_usec=989475}, ...}) = 0
gettimeofday({tv_sec=1594160917, tv_usec=369371}, NULL) = 0
openat(AT_FDCWD, "/sys/devices/system/cpu/online", O_RDONLY|O_CLOEXEC) = 11
read(11, "0-3\n", 8192)                 = 4
close(11)                               = 0
openat(AT_FDCWD, "/sys/fs/cgroup/cpuset/cpuset.cpus", O_RDONLY|O_LARGEFILE) = 11
read(11, "0-3\n", 8191)                 = 4
read(11, "", 8191)                      = 0
close(11)                               = 0
openat(AT_FDCWD, "/sys/fs/cgroup/cpu/cpu.cfs_quota_us", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/sys/devices/system/cpu/online", O_RDONLY|O_LARGEFILE) = 11
read(11, "0-3\n", 8191)                 = 4
read(11, "", 8191)                      = 0
close(11)                               = 0
sched_getaffinity(0, 128, [0, 1, 2, 3]) = 4
gettimeofday({tv_sec=1594160917, tv_usec=372711}, NULL) = 0
mmap2(NULL, 8392704, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0xac6ff000
mprotect(0xac700000, 8388608, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
clone(child_stack=0xacefef98, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0xaceff4c8, tls=0xaceff920, child_tidptr=0xaceff4c8) = 161
mmap2(NULL, 8392704, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0xabcff000
mprotect(0xabd00000, 8388608, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
clone(child_stack=0xac4fef98, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0xac4ff4c8, tls=0xac4ff920, child_tidptr=0xac4ff4c8) = 162
mmap2(NULL, 8392704, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0xab4fe000
mprotect(0xab4ff000, 8388608, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
clone(child_stack=0xabcfdf98, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0xabcfe4c8, tls=0xabcfe920, child_tidptr=0xabcfe4c8) = 163
futex(0x22d7da8, FUTEX_WAKE_PRIVATE, 2147483647) = 1
sched_yield()                           = 0
ioctl(10, VIDIOC_QBUF, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, index=0, memory=V4L2_MEMORY_MMAP, m.offset=0, length=153600, bytesused=0, flags=V4L2_BUF_FLAG_MAPPED|V4L2_BUF_FLAG_QUEUED|V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC|V4L2_BUF_FLAG_TSTAMP_SRC_SOE, ...}) = 0
mmap2(NULL, 233472, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xad037000
write(1, "True", 4True)                     = 4
write(1, "\n", 1
)                       = 1
clock_gettime(CLOCK_MONOTONIC, {tv_sec=92257, tv_nsec=47158582}) = 0
_newselect(0, NULL, NULL, NULL, {tv_sec=1, tv_usec=0}) = 0 (Timeout)
clock_gettime(CLOCK_MONOTONIC, {tv_sec=92258, tv_nsec=49396093}) = 0
timerfd_settime(8, TFD_TIMER_ABSTIME, {it_interval={tv_sec=0, tv_nsec=0}, it_value={tv_sec=92259, tv_nsec=49396000}}, NULL) = 0

ioctl(9, USBDEVFS_SUBMITURB, 0x22e5798) = 0
clock_gettime(CLOCK_REALTIME, {tv_sec=1594160918, tv_nsec=397311851}) = 0
futex(0x22ecf54, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 0, {tv_sec=1594160978, tv_nsec=397311851}, FUTEX_BITSET_MATCH_ANY) = 0
futex(0x22ecf10, FUTEX_WAKE_PRIVATE, 1) = 0
write(1, "HIDHIDHIDHIDHIDHIDHIDHIDHIDHID", 30HIDHIDHIDHIDHIDHIDHIDHIDHIDHID) = 30
write(1, "\n", 1
)                       = 1
futex(0x22db8a8, FUTEX_WAIT_PRIVATE, 0, NULL
fgervais commented 4 years ago

I though it could be a kernel issue so I tried on a newer version but I still get the same result.

My original post was using a kernel 4.19 version and now I tried on 5.4 but it still freezes at FUTEX_WAKE_PRIVATE.

The exact version I'm on right now is:

Linux ubuntu 5.4.0-1008-raspi #8-Ubuntu SMP Wed Apr 8 11:17:03 UTC 2020 armv7l armv7l armv7l GNU/Linux
Youw commented 4 years ago

1) I assume that you have a composite device, that has an UVC interface and HID interface, and you're trying to open both devices of the same physical device. Am I correct? 2) Is it your own or a well known device/interfaces?

fgervais commented 4 years ago

It's 2 different physical devices.

One is an aliexpress camera module (https://www.aliexpress.com/item/32263338732.html?spm=a2g0s.9042311.0.0.27424c4dXUOYdf)

The other is an mcp2221a (https://www.adafruit.com/product/4471)

fgervais@ubuntu:~$ lsusb -t
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 3: Dev 9, If 0, Class=Communications, Driver=cdc_acm, 12M
        |__ Port 3: Dev 9, If 1, Class=CDC Data, Driver=cdc_acm, 12M
        |__ Port 3: Dev 9, If 2, Class=Human Interface Device, Driver=usbhid, 12M
        |__ Port 4: Dev 4, If 1, Class=Video, Driver=uvcvideo, 480M
        |__ Port 4: Dev 4, If 0, Class=Video, Driver=uvcvideo, 480M
Youw commented 4 years ago

Then why do you think this is a hidapi library issue?

fgervais commented 4 years ago

Well I though that it was the case because it was the layer that I saw blocking at the time. To be fair though, I don't think it's the case anymore. I left the issue open thinking someone might provide some help while we actively debug this issue on our side.

Do you know how I could get more info on what this blocking futex() call is about? Any way I can know what it's waiting for exactly?

Youw commented 4 years ago

I might try to help you understand the hidapi implementation itself only. In case of libusb backend, only down to calling libusb functions.

Please note, that this is an issue tracker, not a support forum. We, maintainers, trying to keep the library maintained in terms of fixing bugs found by us or by a community. This work is being done purely on our enthusiasm, and I hope you can understand why I'm asking you to search for help on Stackoverflow or other forums.