Как ждать кадр и сигнал тревоги

У меня проблема с веб-камерой. Это может быть аппаратный, но я уверен, что это не так. Со всеми приложениями я вижу поток, но вдруг он зависает. Из-за следующего вывода из используемого приложения, когда возникает проблема:

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

Я проверил код и интересную часть:

/* 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);
}

Из чего я заключаю, что SYNC_TIMEOUT может быть проблемой. Значение составляет 3 секунды, что, кажется, вполне достаточно.

Моя просьба помочь мне, чтобы код chage не блокировал бесконечно ожидающие кадры:

Если в течение 100 мс не поступает ни одного кадра, то время ожидания и дает возможность графическому интерфейсу обновить себя. Не все устройства могут освободить колесо, поэтому приложение должно поддерживать такие устройства без блокировки графического интерфейса.

Как я могу сделать секундное ожидание?

Устройства v4l2 работают очень хорошо с этим:

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

но у меня есть устройство v4l1.

1 ответ

Какую (usb) веб-камеру и версию ядра вы используете?

  1. Обновите свой драйвер / ядро
  2. Если это USB-камера, попробуйте подключиться без USB-концентратора

VIDIOCSYNC ioctl на vidin->fd приостанавливает выполнение до тех пор, пока vidin->buf не будет заполнено. Вы можете подождать, пока заполненный буфер станет доступным, с помощью выбора или опроса

Другие вопросы по тегам