I've a HDMI to USB capture card with VID:PID 534d:2109. There is no other identifiable information. Captures work via mpv or ffplay. Captures also intermittently work when I use the v4l2 API directly. If I use rust and libv4l-rs to do my captures they typically succeed unless I fail to stop streaming. With C the capture seems to go to fuzz even after I unplug/plug the capture card. Is there a list of errata for devices anywhere? Is there anything I should be doing? I've attached the code I am using, as stated sometimes I get real data. The data typically plays in ffplay/mpv but is colorful snow. =================================== ```c++ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <sys/select.h> #include <sys/epoll.h> #include <linux/videodev2.h> #include <libv4l2.h> int main(int argc, char *argv[]) { int fd = open("/dev/video0", O_RDWR); // TODO: Status check. struct v4l2_capability caps = { 0 }; if (ioctl(fd, VIDIOC_QUERYCAP, &caps)) { perror("VIDIOC_QUERYCAP"); exit(-1); } struct v4l2_format fmt = { 0 }; fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; fmt.fmt.pix.width = 1920; fmt.fmt.pix.width = 1080; if (ioctl(fd, VIDIOC_S_FMT, &fmt)) { perror("VIDIOC_S_FMT"); exit(-1); } struct v4l2_requestbuffers req = { 0 }; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; req.count = 1; if (ioctl(fd, VIDIOC_REQBUFS, &req)) { perror("VIDIOC_REQBUFS"); exit(-1); } struct v4l2_buffer buf = { 0 }; buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = 0; if (ioctl(fd, VIDIOC_QUERYBUF, &buf)) { perror("VIDIOC_QUERYBUF"); exit(-1); } uint8_t *buffer = (uint8_t *)mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset); if (MAP_FAILED == buffer) { perror("mmap"); exit(-1); } if (ioctl(fd, VIDIOC_STREAMON, &buf.type)) { perror("VIDIOC_STREAMON"); exit(-1); } puts("await capture"); fd_set fds; FD_ZERO(&fds); FD_SET(fd, &fds); struct timeval tv = { 0 }; int outfd = open("output.mjpg", O_CREAT | O_WRONLY); if (outfd < 0) { perror("open"); exit(-1); } printf("%d %d %d\n", buf.m.offset, buf.length, buf.bytesused); for (int i = 0; i < 600; i++) { if (ioctl(fd, VIDIOC_QBUF, &buf)) { perror("VIDIOC_QBUF"); exit(-1); } int rc = select(fd+1, &fds, NULL, NULL, &tv); if (ioctl(fd, VIDIOC_DQBUF, &buf)) { perror("VIDIOC_DQBUF"); exit(-1); } write(outfd, &buffer[buf.m.offset], buf.bytesused); fsync(outfd); printf("%d %d %d\n", buf.m.offset, buf.length, buf.bytesused); } if (-1 == ioctl(fd, VIDIOC_STREAMOFF, &buf.type)) { puts("VIDIOC_STREAMOFF"); } close(fd); return 0; }