From ca07c62f2584c5c98ff40cb8817f38f5ca9f4679 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Sun, 10 Apr 2022 10:44:31 +0200 Subject: [PATCH] Simplify `v4l2_cap` support --- device/camera.c | 2 +- device/hw/buffer_list.c | 64 +++++++++++++++++++++++------------------ device/hw/buffer_list.h | 2 +- device/hw/device.c | 29 ++++++------------- device/hw/device.h | 2 +- 5 files changed, 47 insertions(+), 52 deletions(-) diff --git a/device/camera.c b/device/camera.c index 940e28c..130dfd7 100644 --- a/device/camera.c +++ b/device/camera.c @@ -46,7 +46,7 @@ camera_t *camera_open(camera_options_t *options) camera->camera->allow_dma = camera->options.allow_dma; - if (strstr(camera->camera->v4l2_cap.bus_info, "usb")) { + if (strstr(camera->camera->bus_info, "usb")) { E_LOG_INFO(camera, "Disabling DMA since device uses USB (which is likely not working properly)."); camera->camera->allow_dma = false; } diff --git a/device/hw/buffer_list.c b/device/hw/buffer_list.c index 6e961d7..030adcf 100644 --- a/device/hw/buffer_list.c +++ b/device/hw/buffer_list.c @@ -3,42 +3,50 @@ #include "device/hw/device.h" #include "device/hw/v4l2.h" -buffer_list_t *buffer_list_open(const char *name, struct device_s *dev, unsigned type, bool do_mmap) +buffer_list_t *buffer_list_open(const char *name, struct device_s *dev, bool do_capture, bool do_mmap) { buffer_list_t *buf_list = calloc(1, sizeof(buffer_list_t)); buf_list->device = dev; buf_list->name = strdup(name); - buf_list->v4l2.type = type; + buf_list->do_capture = do_capture; - switch(type) { - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - buf_list->do_mmap = do_mmap; - buf_list->do_dma = do_mmap; - break; + struct v4l2_capability v4l2_cap; + E_XIOCTL(dev, dev->fd, VIDIOC_QUERYCAP, &v4l2_cap, "Can't query device capabilities"); - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - buf_list->do_mmap = do_mmap; - buf_list->do_dma = do_mmap; - buf_list->v4l2.do_mplanes = true; - break; + if (do_capture) { + if (v4l2_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) { + buf_list->v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf_list->do_dma = do_mmap; + buf_list->do_mmap = do_mmap; + } else if (v4l2_cap.capabilities & (V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE)) { + buf_list->v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + buf_list->v4l2.do_mplanes = true; + buf_list->do_dma = do_mmap; + buf_list->do_mmap = do_mmap; + } else { + E_LOG_ERROR(dev, "Video capture is not supported by device: %08x", v4l2_cap.capabilities); + } + } else { + if (v4l2_cap.capabilities & V4L2_CAP_VIDEO_OUTPUT) { + buf_list->v4l2.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + buf_list->do_mmap = do_mmap; + buf_list->do_dma = do_mmap; + } else if (v4l2_cap.capabilities & (V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE)) { + buf_list->v4l2.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + buf_list->v4l2.do_mplanes = true; + buf_list->do_mmap = do_mmap; + buf_list->do_dma = do_mmap; + } else { + E_LOG_ERROR(dev, "Video output is not supported by device: %08x", v4l2_cap.capabilities); + } + } - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - buf_list->do_dma = do_mmap; - buf_list->do_mmap = do_mmap; - buf_list->do_capture = true; - break; - - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - buf_list->do_dma = do_mmap; - buf_list->do_mmap = do_mmap; - buf_list->v4l2.do_mplanes = true; - buf_list->do_capture = true; - break; - - default: - E_LOG_PERROR(buf_list, "Unknown type=%d", type); - goto error; + // Add suffix for debug purposes + if (v4l2_cap.capabilities & (V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE)) { +#define MPLANE_SUFFIX ":mplane" + buf_list->name = realloc(buf_list->name, strlen(buf_list->name) + strlen(MPLANE_SUFFIX) + 1); + strcat(buf_list->name, MPLANE_SUFFIX); } return buf_list; diff --git a/device/hw/buffer_list.h b/device/hw/buffer_list.h index 8d0541e..cb1379f 100644 --- a/device/hw/buffer_list.h +++ b/device/hw/buffer_list.h @@ -30,7 +30,7 @@ typedef struct buffer_list_s { int frames; } buffer_list_t; -buffer_list_t *buffer_list_open(const char *name, struct device_s *dev, unsigned type, bool do_mmap); +buffer_list_t *buffer_list_open(const char *name, struct device_s *dev, bool do_capture, bool do_mmap); void buffer_list_close(buffer_list_t *buf_list); int buffer_list_set_stream(buffer_list_t *buf_list, bool do_on); diff --git a/device/hw/device.c b/device/hw/device.c index c67b8ed..ace09de 100644 --- a/device/hw/device.c +++ b/device/hw/device.c @@ -16,12 +16,15 @@ device_t *device_open(const char *name, const char *path, device_hw_t *hw) { } E_LOG_DEBUG(dev, "Querying device capabilities ..."); - E_XIOCTL(dev, dev->fd, VIDIOC_QUERYCAP, &dev->v4l2_cap, "Can't query device capabilities");\ + struct v4l2_capability v4l2_cap; + E_XIOCTL(dev, dev->fd, VIDIOC_QUERYCAP, &v4l2_cap, "Can't query device capabilities"); - if (!(dev->v4l2_cap.capabilities & V4L2_CAP_STREAMING)) { + if (!(v4l2_cap.capabilities & V4L2_CAP_STREAMING)) { E_LOG_ERROR(dev, "Device doesn't support streaming IO"); } + strcpy(dev->bus_info, v4l2_cap.bus_info); + E_LOG_INFO(dev, "Device path=%s fd=%d opened", dev->path, dev->fd); dev->subdev_fd = device_open_v4l2_subdev(dev, 0); @@ -81,15 +84,7 @@ int device_open_buffer_list(device_t *dev, bool do_capture, unsigned width, unsi E_LOG_ERROR(dev, "The capture_list is already created."); } - if (dev->v4l2_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) { - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - sprintf(name, "%s:capture", dev->name); - } else if (dev->v4l2_cap.capabilities & (V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE)) { - type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - sprintf(name, "%s:capture:mplane", dev->name); - } else { - E_LOG_ERROR(dev, "Video capture is not supported by device: %08x", dev->v4l2_cap.capabilities); - } + sprintf(name, "%s:capture", dev->name); } else { buf_list = &dev->output_list; @@ -97,18 +92,10 @@ int device_open_buffer_list(device_t *dev, bool do_capture, unsigned width, unsi E_LOG_ERROR(dev, "The output_list is already created."); } - if (dev->v4l2_cap.capabilities & V4L2_CAP_VIDEO_OUTPUT) { - type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - sprintf(name, "%s:output", dev->name); - } else if (dev->v4l2_cap.capabilities & (V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE)) { - type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - sprintf(name, "%s:output:mplane", dev->name); - } else { - E_LOG_ERROR(dev, "Video output is not supported by device: %08x", dev->v4l2_cap.capabilities); - } + sprintf(name, "%s:output", dev->name); } - *buf_list = buffer_list_open(name, dev, type, do_mmap); + *buf_list = buffer_list_open(name, dev, do_capture, do_mmap); if (!*buf_list) { goto error; } diff --git a/device/hw/device.h b/device/hw/device.h index 1e4cc63..9b971a4 100644 --- a/device/hw/device.h +++ b/device/hw/device.h @@ -13,9 +13,9 @@ typedef struct device_hw_s { typedef struct device_s { char *name; char *path; + char bus_info[64]; int fd; int subdev_fd; - struct v4l2_capability v4l2_cap; bool allow_dma; device_hw_t *hw;