ssize_t v4l1_read(int fd, void *buffer, size_t n) { int index = v4l1_get_index(fd); ssize_t result; if (index == -1) return SYS_READ(fd, buffer, n); pthread_mutex_lock(&devices[index].stream_lock); result = v4l2_read(fd, buffer, n); pthread_mutex_unlock(&devices[index].stream_lock); return result; }
static int v4l2_read_and_convert(int index, unsigned char *dest, int dest_size) { const int max_tries = 10; int result, buf_size, tries = max_tries; buf_size = devices[index].dest_fmt.fmt.pix.sizeimage; if (devices[index].readbuf_size < buf_size) { unsigned char *new_buf; new_buf = realloc(devices[index].readbuf, buf_size); if (!new_buf) return -1; devices[index].readbuf = new_buf; devices[index].readbuf_size = buf_size; } do { result = SYS_READ(devices[index].fd, devices[index].readbuf, buf_size); if (result <= 0) { if (result && errno != EAGAIN) { int saved_err = errno; V4L2_LOG_ERR("reading: %s\n", strerror(errno)); errno = saved_err; } return result; } result = v4lconvert_convert(devices[index].convert, &devices[index].src_fmt, &devices[index].dest_fmt, devices[index].readbuf, result, dest, dest_size); if (devices[index].first_frame) { /* Always treat convert errors as EAGAIN during the first few frames, as some cams produce bad frames at the start of the stream (hsync and vsync still syncing ??). */ if (result < 0) errno = EAGAIN; devices[index].first_frame--; } if (result < 0) { int saved_err = errno; if (errno == EAGAIN) V4L2_LOG("warning error while converting frame data: %s", v4lconvert_get_error_message(devices[index].convert)); else V4L2_LOG_ERR("converting / decoding frame data: %s", v4lconvert_get_error_message(devices[index].convert)); errno = saved_err; } tries--; } while (result < 0 && errno == EAGAIN && tries); if (result < 0 && errno == EAGAIN) { V4L2_LOG_ERR("got %d consecutive frame decode errors, last error: %s", max_tries, v4lconvert_get_error_message(devices[index].convert)); } return result; }