fix: free video capture on early init error

This commit is contained in:
2026-05-16 18:15:40 +02:00
parent 6a7c9b3aab
commit aab770ba3d
+38 -8
View File
@@ -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);
}
}