How to wait for frame and alarm signal

298 views Asked by At

I have problem with a webcam. It can be a hardware one but i'm convinced it is no. With all apps I can see the stream but suddenly it freezes. Because of the following output from used app when the problem occurs:

v4l: timeout (got SIGALRM), hardware/driver problems?

I have checked out the code and the interesting part:

/* How many seconds to wait before deciding it's a driver problem. */
#define SYNC_TIMEOUT 3

int alarms;

void sigalarm(int signal)
{
    alarms++;
}

.................................................................................

void wait_for_frame_v4l1( input_t *vidin, int frameid )
{
    alarms = 0;
    alarm(SYNC_TIMEOUT);
    if (ioctl(vidin->fd, VIDIOCSYNC, vidin->buf + frameid) < 0 )
        fprintf(stderr, "input: Can't wait for frame %d: %s\n", frameid, strerror(errno));
    if (alarms)
        fprintf(stderr, "v4l: timeout (got SIGALRM), hardware/driver problems?");
    alarm(0);
}

From which I conclude that SYNC_TIMEOUT could be problem. The value is 3 secondes which seems to be quite enough.

My request is to help me chage code to don't block indefinitely waiting for frames:

If no frame arrives within 100 ms, then timeout and give the GUI the chance to update itself. Not all devices can free wheel, so app should support such devices without blocking the GUI.

How can I do sub-second waiting?

v4l2 devices work very well with this:

/* How many milliseconds to wait before deciding it's a driver problem. */
#define SYNC_TIMEOUT_MSECS 100

int wait_for_frame_v4l2(input_t * vidin)
{
        struct timeval timeout;
        fd_set rdset;
        int n;

        FD_ZERO(&rdset);
        FD_SET(vidin->fd, &rdset);

        timeout.tv_sec = 0;
        timeout.tv_usec = SYNC_TIMEOUT_MSECS * 1000;

        n = select(vidin->fd + 1, &rdset, 0, 0, &timeout);
        if(n == -1) {
            fprintf(stderr, "input: Can't wait for frame: %s\n", strerror(errno));
        } else if(n == 0) {
            sigalarm(0);
            return 1;
        }
        return 0;
}

but I have v4l1 device.

1

There are 1 answers

0
gj13 On

What (usb) webcam and kernel version are you using?

  1. Update your driver/kernel
  2. If it's an USB-Cam, try connecting without an USB-hub

The VIDIOCSYNC ioctl on vidin->fd suspends execution until vidin->buf has been filled. You can wait for a filled buffer to become available via select or poll