Open TheFrog4u opened 10 years ago
Just wanted to note that this topic is still hot for me. Is there a way or even a chance to fix this issue or maybe a reason why select() is not working correctly with v4l2loopback?
it would be great if you could provide a simple test program that exhibits the problem (ideally one that can be run in an automated test-suite)
How can I attach source code? You can basicly use the example above with simple modifications:
static int read_frame(void) { struct v4l2_buffer buf; int err;
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
err = xioctl(fd, VIDIOC_DQBUF, &buf);
if (err == -1) {
if (errno == EAGAIN) {
return ERR_IMAGE_AGAIN;
} else {
perror("VIDIOC_QBUF");
return ERR_IMAGE_ERROR;
}
}
assert(buf.index < n_buffers);
process_image(buffers[buf.index].start, buf.bytesused, buf.index);
err = xioctl(fd, VIDIOC_QBUF, &buf);
if (err == -1) {
perror("VIDIOC_QBUF");
return ERR_IMAGE_ERROR;
}
return OK;
}
static void main_loop(void) { unsigned int count = READ_NUM_IMAGES; int err;
while (count-- > 0) {
for(;;) {
fd_set fds;
struct timeval tv;
FD_ZERO(&fds);
FD_SET(fd, &fds);
/* Timeout. */
tv.tv_sec = 30;
tv.tv_usec = 0;
err = select(fd + 1, &fds, NULL, NULL, &tv);
if (err == -1) {
if (errno == EINTR) {
continue;
}
errno_exit("select");
}
if (err == 0) {
fprintf(stderr, "select timeout\n");
exit(EXIT_FAILURE);
}
err = read_frame();
if (err == OK) {
break;
}else if (err == ERR_IMAGE_AGAIN) {
fprintf(stderr, "Error capture image, retrying...\n");
usleep(10000); // wait 10 ms and try again..
continue;
} else {
errno_exit("ERR_IMAGE_ERROR");
}
}
}
}
I just feed the v4l2loopback device:
gst-launch -q multifilesrc location=image01.png num_buffers=100 caps="image/png,framerate=10/1" ! pngdec ! videorate ! ffmpegcolorspace ! "video/x-raw-gray,format=(fourcc)GRAY" ! v4l2sink device=/dev/video0
and than run the example, I get:
./v4l2example Error capture image, retrying... Error capture image, retrying... Error capture image, retrying... Error capture image, retrying... Error capture image, retrying... Error capture image, retrying... Error capture image, retrying...
With an actual camera I do not get the "Error capture image, retrying..." errors which are triggered because select() always return 1, no matter if an image is actually in the buffer.
Best regards, Jens
Can verify this defect and think I see the issue:
Problem occurs when device is accessed with read() or write() rather than streaming interface. The opener->type field is only set in vidioc_streamon and vidioc_streamoff functions, and if it is not set to either READER or WRITER then v4l2_loopback_poll() always returns 0, indicating no activity on the device. Since the streaming ioctls should not be used by applications that just use read() and write(), this field is never set.
I'm seeing the same behaviour with read/wrte using v4l2py with a loopback device; and stream_on
/stream_off
doesn't make a difference there - but I'm trying to drill down a bit further into the module to see if there's some flag that isn't being set correctly.
I'm fairly sure that v4l2loopback doesn't implement a true poll/wait for V4L2_BUF_TYPE_VIDEO_OUTPUT
. The poll function looks like it always falls through immediately with the POLLOUT
event mask.
Looks to my eye that videoc_qbuf
immediately wakes up any read (event) subscribers, too (regardless of frame rate)... so; I guess the frame rate is entirely controlled by the application.
Coming back to this after spending a lot more time on thing V4L + V4L2loopback; I don't believe this is a bug. Streaming I/O hasn't been negotiated correctly in the code snippet. poll() should (and does) return an error:
When the application did not call VIDIOC_STREAMON the poll() function succeeds, but sets the POLLERR flag in the revents field.
Hi, v4l2loopback works very well for me with one execption: the select() functionality (http://linuxtv.org/downloads/v4l-dvb-apis/func-select.html) which should wait for a buffer to be filled always returns 1. An example how I use it can be found here: http://linuxtv.org/downloads/v4l-dvb-apis/capture-example.html With my "real" camera select() waits for the image, but not with the v4l2loopback device, no matter if I even have a gstreamer v4l2sink coupled or not.