Intermittent Snow Instead of Picture

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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;
}



[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux