Pass sizeimage to ensure that allocated buffers are of a correct size
				
					
				
			This commit is contained in:
		| @@ -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; | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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; | ||||
|   } | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Kamil Trzcinski
					Kamil Trzcinski