diff --git a/device/buffer_list.c b/device/buffer_list.c index 518d4d1..fc2e286 100644 --- a/device/buffer_list.c +++ b/device/buffer_list.c @@ -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; diff --git a/device/buffer_list.h b/device/buffer_list.h index 3a70d21..6bdabb6 100644 --- a/device/buffer_list.h +++ b/device/buffer_list.h @@ -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; diff --git a/device/camera/camera_input.c b/device/camera/camera_input.c index e7f4662..176431f 100644 --- a/device/camera/camera_input.c +++ b/device/camera/camera_input.c @@ -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; } diff --git a/device/device.c b/device/device.c index df41e15..dd3c55f 100644 --- a/device/device.c +++ b/device/device.c @@ -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) diff --git a/device/device.h b/device/device.h index e2e8112..b52dee9 100644 --- a/device/device.h +++ b/device/device.h @@ -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); diff --git a/device/v4l2/buffer_list.c b/device/v4l2/buffer_list.c index 49fb8ac..521deae 100644 --- a/device/v4l2/buffer_list.c +++ b/device/v4l2/buffer_list.c @@ -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) {