diff --git a/src/video.c b/src/video.c index c06c289..c95cf64 100644 --- a/src/video.c +++ b/src/video.c @@ -75,6 +75,7 @@ static void open_device(VideoCapture *video_capture, const char *name, strlcpy(video_capture->name, name, STR_LEN); video_capture->error = false; video_capture->fd = -1; + video_capture->buf_count = 0; video_capture->fd = open(name, O_RDWR | O_NONBLOCK); if (video_capture->fd == -1) { @@ -214,6 +215,9 @@ static bool request_buffers(VideoCapture *video_capture, log_info("(%s) V4L2 Buffer Count: %d", video_capture->name, reqbuf.count); video_capture->buf_count = reqbuf.count; + for (unsigned int i = 0; i < reqbuf.count; i++) { + video_capture->exp_fd[i] = -1; + } return true; } @@ -265,7 +269,7 @@ static bool open_stream(VideoCapture *video_capture) { return true; } -static void create_image_buffer(const VideoCapture *video_capture, +static bool create_image_buffer(VideoCapture *video_capture, struct v4l2_buffer *buf, unsigned int index) { memset(buf, 0, sizeof(*buf)); @@ -273,15 +277,24 @@ static void create_image_buffer(const VideoCapture *video_capture, buf->memory = V4L2_MEMORY_MMAP; buf->index = index; - ioctl(video_capture->fd, VIDIOC_QBUF, buf); + if (ioctl(video_capture->fd, VIDIOC_QBUF, buf) == -1) { + ioctl_error(video_capture, "VIDIOC_QBUF", "Could not enqueue buffer"); + return false; + } + + return true; } -static void create_image_buffers(VideoCapture *video_capture) { +static bool create_image_buffers(VideoCapture *video_capture) { unsigned int i; for (i = 0; i < video_capture->buf_count; i++) { - create_image_buffer(video_capture, &video_capture->buf[i], i); + if (!create_image_buffer(video_capture, &video_capture->buf[i], i)) { + return false; + } } + + return true; } static void close_stream(const VideoCapture *video_capture) { @@ -317,30 +330,46 @@ void video_init(VideoCapture *video_capture, const char *name, } if (!check_caps(video_capture)) { + video_capture->error = true; + video_free(video_capture); return; } if (!get_available_sizes(video_capture, preferred_height)) { + video_capture->error = true; + video_free(video_capture); return; } if (!set_format(video_capture)) { + video_capture->error = true; + video_free(video_capture); return; } if (!request_buffers(video_capture, buffer_count)) { + video_capture->error = true; + video_free(video_capture); return; } if (!export_buffers(video_capture)) { + video_capture->error = true; + video_free(video_capture); return; } if (!open_stream(video_capture)) { + video_capture->error = true; + video_free(video_capture); return; } - create_image_buffers(video_capture); + if (!create_image_buffers(video_capture)) { + video_capture->error = true; + video_free(video_capture); + return; + } } void *video_background_read(void *args) { @@ -388,13 +417,14 @@ void *video_background_read(void *args) { void video_free(const VideoCapture *video_capture) { unsigned int i; - close_stream(video_capture); - for (i = 0; i < video_capture->buf_count; i++) { - close(video_capture->exp_fd[i]); + if (video_capture->exp_fd[i] != -1) { + close(video_capture->exp_fd[i]); + } } if (video_capture->fd != -1) { + close_stream(video_capture); close(video_capture->fd); } }