Pass sizeimage to ensure that allocated buffers are of a correct size

This commit is contained in:
Kamil Trzcinski 2022-11-05 13:53:55 +01:00
parent ca08adb62f
commit 0c244a61c8
6 changed files with 58 additions and 38 deletions

View File

@ -25,11 +25,12 @@ buffer_list_t *buffer_list_open(const char *name, int index, struct device_s *de
LOG_INFO(
buf_list,
"Using: %ux%u/%s, bytesperline=%d",
"Using: %ux%u/%s, bytesperline=%d, sizeimage=%.1fMiB",
buf_list->fmt.width,
buf_list->fmt.height,
fourcc_to_string(buf_list->fmt.format).buf,
buf_list->fmt.bytesperline
buf_list->fmt.bytesperline,
buf_list->fmt.sizeimage / 1024.0f / 1024.0f
);
buf_list->bufs = calloc(got_bufs, sizeof(buffer_t*));
@ -54,7 +55,7 @@ buffer_list_t *buffer_list_open(const char *name, int index, struct device_s *de
buf_list->bufs[i] = buf;
}
LOG_VERBOSE(buf_list, "Opened %u buffers. Memory used: %.1f MiB", buf_list->nbufs, mem_used / 1024.0f / 1024.0f);
LOG_INFO(buf_list, "Opened %u buffers. Memory used: %.1f MiB", buf_list->nbufs, mem_used / 1024.0f / 1024.0f);
return buf_list;

View File

@ -8,7 +8,7 @@ typedef struct device_s device_t;
struct pollfd;
typedef struct buffer_format_s {
unsigned width, height, format, bytesperline;
unsigned width, height, format, bytesperline, sizeimage;
unsigned nbufs;
unsigned interval_us;
} buffer_format_t;

View File

@ -32,8 +32,14 @@ static int camera_configure_input_v4l2(camera_t *camera)
camera->camera->opts.allow_dma = false;
}
buffer_list_t *camera_capture = device_open_buffer_list(camera->camera, true,
camera->options.width, camera->options.height, camera->options.format, 0, camera->options.nbufs, true);
buffer_format_t fmt = {
.width = camera->options.width,
.height = camera->options.height,
.format = camera->options.format,
.nbufs = camera->options.nbufs
};
buffer_list_t *camera_capture = device_open_buffer_list(camera->camera, true, fmt, true);
if (!camera_capture) {
return -1;
}
@ -52,16 +58,14 @@ static int camera_configure_input_libcamera(camera_t *camera)
camera->camera->opts.allow_dma = camera->options.allow_dma;
buffer_list_t *camera_capture = device_open_buffer_list(
camera->camera,
true,
camera->options.width,
camera->options.height,
camera->options.format,
0,
camera->options.nbufs,
true
);
buffer_format_t fmt = {
.width = camera->options.width,
.height = camera->options.height,
.format = camera->options.format,
.nbufs = camera->options.nbufs
};
buffer_list_t *camera_capture = device_open_buffer_list(camera->camera, true, fmt, true);
if (!camera_capture) {
return -1;
}

View File

@ -47,12 +47,12 @@ void device_close(device_t *dev) {
free(dev);
}
buffer_list_t *device_open_buffer_list(device_t *dev, bool do_capture, unsigned width, unsigned height, unsigned format, unsigned bytesperline, int nbufs, bool do_mmap)
buffer_list_t *device_open_buffer_list(device_t *dev, bool do_capture, buffer_format_t fmt, bool do_mmap)
{
return device_open_buffer_list2(dev, NULL, do_capture, width, height, format, bytesperline, nbufs, do_mmap);
return device_open_buffer_list2(dev, NULL, do_capture, fmt, do_mmap);
}
buffer_list_t *device_open_buffer_list2(device_t *dev, const char *path, bool do_capture, unsigned width, unsigned height, unsigned format, unsigned bytesperline, int nbufs, bool do_mmap)
buffer_list_t *device_open_buffer_list2(device_t *dev, const char *path, bool do_capture, buffer_format_t fmt, bool do_mmap)
{
char name[64];
int index = 0;
@ -81,14 +81,6 @@ buffer_list_t *device_open_buffer_list2(device_t *dev, const char *path, bool do
sprintf(name, "%s:output", dev->name);
}
buffer_format_t fmt = {
.width = width,
.height = height,
.format = format,
.bytesperline = bytesperline,
.nbufs = nbufs
};
buf_list = buffer_list_open(name, index, dev, path, fmt, do_capture, do_mmap);
if (!buf_list) {
goto error;
@ -114,11 +106,23 @@ buffer_list_t *device_open_buffer_list_output(device_t *dev, buffer_list_t *capt
return NULL;
}
buffer_format_t fmt = capture_list->fmt;
bool do_mmap = capture_list->dev->opts.allow_dma ? !capture_list->do_mmap : true;
// If manually allocating buffers, ensure that `sizeimage` is at least `buf->length`
if (do_mmap) {
for (int i = 0; i < capture_list->nbufs; i++) {
buffer_t *buf = capture_list->bufs[i];
if (fmt.sizeimage < buf->length)
fmt.sizeimage = buf->length;
}
} else {
fmt.sizeimage = 0;
}
return device_open_buffer_list(dev, false,
capture_list->fmt.width, capture_list->fmt.height,
capture_list->fmt.format, capture_list->fmt.bytesperline,
capture_list->nbufs,
capture_list->dev->opts.allow_dma ? !capture_list->do_mmap : true);
fmt,
do_mmap);
}
buffer_list_t *device_open_buffer_list_capture(device_t *dev, const char *path, buffer_list_t *output_list, unsigned width, unsigned height, unsigned format, bool do_mmap)
@ -127,9 +131,17 @@ buffer_list_t *device_open_buffer_list_capture(device_t *dev, const char *path,
return NULL;
}
return device_open_buffer_list2(dev, path, true,
width ? width : output_list->fmt.width, height ? height : output_list->fmt.height,
format, 0, output_list->nbufs, do_mmap);
buffer_format_t fmt = output_list->fmt;
if (width)
fmt.width = width;
if (height)
fmt.height = height;
fmt.format = format;
fmt.bytesperline = 0;
fmt.sizeimage = 0;
return device_open_buffer_list2(dev, path, true, fmt, do_mmap);
}
int device_set_stream(device_t *dev, bool do_on)

View File

@ -6,6 +6,7 @@
typedef struct buffer_s buffer_t;
typedef struct buffer_list_s buffer_list_t;
typedef struct buffer_format_s buffer_format_t;
typedef struct device_s device_t;
struct pollfd;
@ -57,8 +58,8 @@ typedef struct device_s {
device_t *device_open(const char *name, const char *path, device_hw_t *hw);
void device_close(device_t *dev);
buffer_list_t *device_open_buffer_list(device_t *dev, bool do_capture, unsigned width, unsigned height, unsigned format, unsigned bytesperline, int nbufs, bool do_mmap);
buffer_list_t *device_open_buffer_list2(device_t *dev, const char *path, bool do_capture, unsigned width, unsigned height, unsigned format, unsigned bytesperline, int nbufs, bool do_mmap);
buffer_list_t *device_open_buffer_list(device_t *dev, bool do_capture, buffer_format_t fmt, bool do_mmap);
buffer_list_t *device_open_buffer_list2(device_t *dev, const char *path, bool do_capture, buffer_format_t fmt, bool do_mmap);
buffer_list_t *device_open_buffer_list_output(device_t *dev, buffer_list_t *capture_list);
buffer_list_t *device_open_buffer_list_capture(device_t *dev, const char *path, buffer_list_t *output_list, unsigned width, unsigned height, unsigned format, bool do_mmap);
int device_consume_event(device_t *dev);

View File

@ -95,7 +95,7 @@ retry_resolution_set:
v4l2_fmt.fmt.pix_mp.field = V4L2_FIELD_ANY;
v4l2_fmt.fmt.pix_mp.num_planes = 1;
v4l2_fmt.fmt.pix_mp.plane_fmt[0].bytesperline = fmt.bytesperline;
//v4l2_fmt.fmt.pix_mp.plane_fmt[0].sizeimage = bytesperline * orig_height;
v4l2_fmt.fmt.pix_mp.plane_fmt[0].sizeimage = fmt.sizeimage;
} else {
v4l2_fmt.fmt.pix.colorspace = V4L2_COLORSPACE_RAW;
if (fmt.width)
@ -106,7 +106,7 @@ retry_resolution_set:
v4l2_fmt.fmt.pix.pixelformat = fmt.format;
v4l2_fmt.fmt.pix.field = V4L2_FIELD_ANY;
v4l2_fmt.fmt.pix.bytesperline = fmt.bytesperline;
//v4l2_fmt.fmt.pix.sizeimage = bytesperline * orig_height;
v4l2_fmt.fmt.pix.sizeimage = fmt.sizeimage;
}
LOG_DEBUG(buf_list, "Configuring format (%s)...", fourcc_to_string(fmt.format).buf);
@ -117,11 +117,13 @@ retry_resolution_set:
buf_list->fmt.height = v4l2_fmt.fmt.pix_mp.height;
buf_list->fmt.format = v4l2_fmt.fmt.pix_mp.pixelformat;
buf_list->fmt.bytesperline = v4l2_fmt.fmt.pix_mp.plane_fmt[0].bytesperline;
buf_list->fmt.sizeimage = v4l2_fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
} else {
buf_list->fmt.width = v4l2_fmt.fmt.pix.width;
buf_list->fmt.height = v4l2_fmt.fmt.pix.height;
buf_list->fmt.format = v4l2_fmt.fmt.pix.pixelformat;
buf_list->fmt.bytesperline = v4l2_fmt.fmt.pix.bytesperline;
buf_list->fmt.sizeimage = v4l2_fmt.fmt.pix.sizeimage;
}
if (buf_list->fmt.width != fmt.width || buf_list->fmt.height != fmt.height) {