Hi Tomasz, I like the direction in which you are going with the userspace handling. This is almost exactly as I envisioned it. I have one comment though:
On Thu, Jan 26, 2012 at 01:48, Tomasz Stanislawski t.stanislaws@samsung.com wrote:
[snip]
/* setup polling */ struct pollfd fds[2] = { { .fd = f_in, .events = POLLIN }, { .fd = f_out, .events = POLLOUT }, };
while ((ret = poll(fds, 2, 5000)) > 0) { struct v4l2_buffer buf; struct v4l2_plane plane;
memset(&buf, 0, sizeof buf); memset(&plane, 0, sizeof plane); buf.m.planes = &plane; buf.length = 1;
if (fds[0].revents & POLLIN) { /* dequeue buffer */ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; buf.memory = V4L2_MEMORY_MMAP; ret = ioctl(f_in, VIDIOC_DQBUF, &buf); BYE_ON(ret, "VIDIOC_DQBUF failed: %s\n", ERRSTR);
/* enqueue buffer */ buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; buf.memory = V4L2_MEMORY_DMABUF; plane.m.fd = fd[buf.index]; ret = ioctl(f_out, VIDIOC_QBUF, &buf); BYE_ON(ret, "VIDIOC_QBUF failed: %s\n", ERRSTR); }
This passes fd, so the OUTPUT driver will get the correct buffer from dmabuf.
if (fds[1].revents & POLLOUT) { /* dequeue buffer */ buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; buf.memory = V4L2_MEMORY_DMABUF; ret = ioctl(f_out, VIDIOC_DQBUF, &buf); BYE_ON(ret, "VIDIOC_DQBUF failed: %s\n", ERRSTR);
/* enqueue buffer */ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; buf.memory = V4L2_MEMORY_MMAP; ret = ioctl(f_in, VIDIOC_QBUF, &buf); BYE_ON(ret, "VIDIOC_QBUF failed: %s\n", ERRSTR); }
This, however, relies on the indexes to be equal for the same buffers/planes in both drivers. I don't see why we should restrict ourselves to that. In fact, we must not. You should have a reverse mapping of fd->index for the INPUT device and use the fd returned in buf by DQBUF from OUTPUT device to look-up the correct index to be passed to the INPUT device.
}
BYE_ON(ret == 0, "polling timeout\n"); BYE_ON(1, "polling stopped: %s\n", ERRSTR);
return 0; }