Как ждать кадр и сигнал тревоги
У меня проблема с веб-камерой. Это может быть аппаратный, но я уверен, что это не так. Со всеми приложениями я вижу поток, но вдруг он зависает. Из-за следующего вывода из используемого приложения, когда возникает проблема:
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) веб-камеру и версию ядра вы используете?
- Обновите свой драйвер / ядро
- Если это USB-камера, попробуйте подключиться без USB-концентратора
VIDIOCSYNC ioctl на vidin->fd приостанавливает выполнение до тех пор, пока vidin->buf не будет заполнено. Вы можете подождать, пока заполненный буфер станет доступным, с помощью выбора или опроса