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( LOG_INFO(
buf_list, buf_list,
"Using: %ux%u/%s, bytesperline=%d", "Using: %ux%u/%s, bytesperline=%d, sizeimage=%.1fMiB",
buf_list->fmt.width, buf_list->fmt.width,
buf_list->fmt.height, buf_list->fmt.height,
fourcc_to_string(buf_list->fmt.format).buf, 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*)); 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; 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; return buf_list;

View File

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

View File

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

View File

@ -47,12 +47,12 @@ void device_close(device_t *dev) {
free(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]; char name[64];
int index = 0; 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); 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); buf_list = buffer_list_open(name, index, dev, path, fmt, do_capture, do_mmap);
if (!buf_list) { if (!buf_list) {
goto error; goto error;
@ -114,11 +106,23 @@ buffer_list_t *device_open_buffer_list_output(device_t *dev, buffer_list_t *capt
return NULL; 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, return device_open_buffer_list(dev, false,
capture_list->fmt.width, capture_list->fmt.height, fmt,
capture_list->fmt.format, capture_list->fmt.bytesperline, do_mmap);
capture_list->nbufs,
capture_list->dev->opts.allow_dma ? !capture_list->do_mmap : true);
} }
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) 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 NULL;
} }
return device_open_buffer_list2(dev, path, true, buffer_format_t fmt = output_list->fmt;
width ? width : output_list->fmt.width, height ? height : output_list->fmt.height,
format, 0, output_list->nbufs, do_mmap); 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) 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_s buffer_t;
typedef struct buffer_list_s buffer_list_t; typedef struct buffer_list_s buffer_list_t;
typedef struct buffer_format_s buffer_format_t;
typedef struct device_s device_t; typedef struct device_s device_t;
struct pollfd; struct pollfd;
@ -57,8 +58,8 @@ typedef struct device_s {
device_t *device_open(const char *name, const char *path, device_hw_t *hw); device_t *device_open(const char *name, const char *path, device_hw_t *hw);
void device_close(device_t *dev); 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_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, 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);
buffer_list_t *device_open_buffer_list_output(device_t *dev, buffer_list_t *capture_list); 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); 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); 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.field = V4L2_FIELD_ANY;
v4l2_fmt.fmt.pix_mp.num_planes = 1; 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].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 { } else {
v4l2_fmt.fmt.pix.colorspace = V4L2_COLORSPACE_RAW; v4l2_fmt.fmt.pix.colorspace = V4L2_COLORSPACE_RAW;
if (fmt.width) if (fmt.width)
@ -106,7 +106,7 @@ retry_resolution_set:
v4l2_fmt.fmt.pix.pixelformat = fmt.format; v4l2_fmt.fmt.pix.pixelformat = fmt.format;
v4l2_fmt.fmt.pix.field = V4L2_FIELD_ANY; v4l2_fmt.fmt.pix.field = V4L2_FIELD_ANY;
v4l2_fmt.fmt.pix.bytesperline = fmt.bytesperline; 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); 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.height = v4l2_fmt.fmt.pix_mp.height;
buf_list->fmt.format = v4l2_fmt.fmt.pix_mp.pixelformat; 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.bytesperline = v4l2_fmt.fmt.pix_mp.plane_fmt[0].bytesperline;
buf_list->fmt.sizeimage = v4l2_fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
} else { } else {
buf_list->fmt.width = v4l2_fmt.fmt.pix.width; buf_list->fmt.width = v4l2_fmt.fmt.pix.width;
buf_list->fmt.height = v4l2_fmt.fmt.pix.height; buf_list->fmt.height = v4l2_fmt.fmt.pix.height;
buf_list->fmt.format = v4l2_fmt.fmt.pix.pixelformat; buf_list->fmt.format = v4l2_fmt.fmt.pix.pixelformat;
buf_list->fmt.bytesperline = v4l2_fmt.fmt.pix.bytesperline; 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) { if (buf_list->fmt.width != fmt.width || buf_list->fmt.height != fmt.height) {