From 8dd470cb4970fd8b1789a9fe1d7926095ee7b749 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Mon, 11 Apr 2022 22:02:22 +0200 Subject: [PATCH] Make device to support composite devices (single output, many captures) --- device/camera/camera.c | 2 +- device/camera/camera.h | 5 +---- device/camera/camera_isp.c | 16 ++++------------ device/camera/camera_legacy_isp.c | 6 +++--- device/device.c | 14 ++++++++++++-- device/device.h | 3 ++- device/libcamera/buffer_list.cc | 5 +++++ device/links.c | 4 ---- device/v4l2/buffer_list.c | 14 ++++++++++++-- 9 files changed, 40 insertions(+), 29 deletions(-) diff --git a/device/camera/camera.c b/device/camera/camera.c index 0d9042b..4545a6d 100644 --- a/device/camera/camera.c +++ b/device/camera/camera.c @@ -93,7 +93,7 @@ int camera_set_params(camera_t *camera) device_set_fps(camera->camera, camera->options.fps); device_set_option_list(camera->camera, camera->options.options); - device_set_option_list(camera->isp_srgb, camera->options.isp.options); + device_set_option_list(camera->isp, camera->options.isp.options); device_set_option_list(camera->codec_h264, camera->options.h264.options); device_set_option_list(camera->codec_h264_lowres, camera->options.h264.options); device_set_option_list(camera->codec_jpeg, camera->options.jpeg.options); diff --git a/device/camera/camera.h b/device/camera/camera.h index f43aed5..93750ab 100644 --- a/device/camera/camera.h +++ b/device/camera/camera.h @@ -55,10 +55,7 @@ typedef struct camera_s { struct { device_t *camera; device_t *decoder; // decode JPEG/H264 into YUVU - device_t *legacy_isp; // convert pRAA/YUVU into YUVU - device_t *isp_srgb; - device_t *isp_yuuv; - device_t *isp_yuuv_lowres; + device_t *isp; device_t *codec_jpeg; // encode YUVU into JPEG device_t *codec_h264; // encode YUVU into H264 device_t *codec_jpeg_lowres; // encode YUVU into JPEG diff --git a/device/camera/camera_isp.c b/device/camera/camera_isp.c index a056c77..5a8b9d3 100644 --- a/device/camera/camera_isp.c +++ b/device/camera/camera_isp.c @@ -15,16 +15,12 @@ int camera_configure_isp(camera_t *camera, buffer_list_t *camera_capture, float { link_t *links = camera->links; - camera->isp_srgb = device_v4l2_open("ISP", "/dev/video13"); - camera->isp_yuuv = device_v4l2_open("ISP-YUUV", "/dev/video14"); - if (camera->isp_yuuv) { - camera->isp_yuuv->output_device = camera->isp_srgb; - } + camera->isp = device_v4l2_open("ISP", "/dev/video13"); camera->codec_jpeg = device_v4l2_open("JPEG", "/dev/video31"); camera->codec_h264 = device_v4l2_open("H264", "/dev/video11"); - buffer_list_t *isp_output = device_open_buffer_list_output(camera->isp_srgb, camera_capture); - buffer_list_t *isp_capture = device_open_buffer_list_capture(camera->isp_yuuv, isp_output, high_div, V4L2_PIX_FMT_YUYV, true); + buffer_list_t *isp_output = device_open_buffer_list_output(camera->isp, camera_capture); + buffer_list_t *isp_capture = device_open_buffer_list_capture2(camera->isp, "/dev/video14", isp_output, high_div, V4L2_PIX_FMT_YUYV, true); *links++ = (link_t){ camera_capture, { isp_output } }; @@ -47,14 +43,10 @@ int camera_configure_isp(camera_t *camera, buffer_list_t *camera_capture, float return 0; } - camera->isp_yuuv_lowres = device_v4l2_open("ISP-YUUV-LOW", "/dev/video15"); - if (camera->isp_yuuv_lowres) { - camera->isp_yuuv_lowres->output_device = camera->isp_srgb; - } camera->codec_jpeg_lowres = device_v4l2_open("JPEG-LOW", "/dev/video31"); camera->codec_h264_lowres = device_v4l2_open("H264-LOW", "/dev/video11"); - buffer_list_t *isp_lowres_capture = device_open_buffer_list_capture(camera->isp_yuuv_lowres, isp_output, low_div, V4L2_PIX_FMT_YUYV, true); + buffer_list_t *isp_lowres_capture = device_open_buffer_list_capture2(camera->isp, "/dev/video15", isp_output, low_div, V4L2_PIX_FMT_YUYV, true); buffer_list_t *jpeg_lowres_output = device_open_buffer_list_output(camera->codec_jpeg_lowres, isp_lowres_capture); buffer_list_t *jpeg_lowres_capture = device_open_buffer_list_capture(camera->codec_jpeg_lowres, jpeg_lowres_output, 1.0, V4L2_PIX_FMT_JPEG, true); diff --git a/device/camera/camera_legacy_isp.c b/device/camera/camera_legacy_isp.c index f9ab7ec..d7bdcc1 100644 --- a/device/camera/camera_legacy_isp.c +++ b/device/camera/camera_legacy_isp.c @@ -23,12 +23,12 @@ void write_yuvu(buffer_t *buffer) int camera_configure_legacy_isp(camera_t *camera, buffer_list_t *camera_capture, float div) { - camera->legacy_isp = device_v4l2_open("ISP", "/dev/video12"); + camera->isp = device_v4l2_open("ISP", "/dev/video12"); camera->codec_jpeg = device_v4l2_open("JPEG", "/dev/video31"); camera->codec_h264 = device_v4l2_open("H264", "/dev/video11"); - buffer_list_t *isp_output = device_open_buffer_list_output(camera->legacy_isp, camera_capture); - buffer_list_t *isp_capture = device_open_buffer_list_capture(camera->legacy_isp, isp_output, div, V4L2_PIX_FMT_YUYV, true); + buffer_list_t *isp_output = device_open_buffer_list_output(camera->isp, camera_capture); + buffer_list_t *isp_capture = device_open_buffer_list_capture(camera->isp, isp_output, div, V4L2_PIX_FMT_YUYV, true); buffer_list_t *jpeg_output = device_open_buffer_list_output(camera->codec_jpeg, isp_capture); buffer_list_t *jpeg_capture = device_open_buffer_list_capture(camera->codec_jpeg, jpeg_output, 1.0, V4L2_PIX_FMT_JPEG, true); diff --git a/device/device.c b/device/device.c index e8071d3..feb0640 100644 --- a/device/device.c +++ b/device/device.c @@ -48,6 +48,11 @@ 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) +{ + return device_open_buffer_list2(dev, NULL, do_capture, width, height, format, bytesperline, nbufs, 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) { unsigned type; char name[64]; @@ -85,7 +90,7 @@ buffer_list_t *device_open_buffer_list(device_t *dev, bool do_capture, unsigned .nbufs = nbufs }; - buf_list = buffer_list_open(name, index, dev, NULL, fmt, do_capture, do_mmap); + buf_list = buffer_list_open(name, index, dev, path, fmt, do_capture, do_mmap); if (!buf_list) { goto error; } @@ -118,12 +123,17 @@ buffer_list_t *device_open_buffer_list_output(device_t *dev, buffer_list_t *capt } buffer_list_t *device_open_buffer_list_capture(device_t *dev, buffer_list_t *output_list, float div, unsigned format, bool do_mmap) +{ + return device_open_buffer_list_capture2(dev, NULL, output_list, div, format, do_mmap); +} + +buffer_list_t *device_open_buffer_list_capture2(device_t *dev, const char *path, buffer_list_t *output_list, float div, unsigned format, bool do_mmap) { if (!dev || !output_list) { return NULL; } - return device_open_buffer_list(dev, true, + return device_open_buffer_list2(dev, path, true, output_list->fmt.width / div, output_list->fmt.height / div, format, 0, output_list->nbufs, do_mmap); } diff --git a/device/device.h b/device/device.h index 271ec1d..50655c0 100644 --- a/device/device.h +++ b/device/device.h @@ -47,7 +47,6 @@ typedef struct device_s { struct device_libcamera_s *libcamera; }; - device_t *output_device; bool paused; bool decoder_started; } device_t; @@ -56,8 +55,10 @@ 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_output(device_t *dev, buffer_list_t *capture_list); buffer_list_t *device_open_buffer_list_capture(device_t *dev, buffer_list_t *output_list, float div, unsigned format, bool do_mmap); +buffer_list_t *device_open_buffer_list_capture2(device_t *dev, const char *path, buffer_list_t *output_list, float div, unsigned format, bool do_mmap); int device_consume_event(device_t *dev); int device_set_stream(device_t *dev, bool do_on); diff --git a/device/libcamera/buffer_list.cc b/device/libcamera/buffer_list.cc index 6b81576..d5ecffb 100644 --- a/device/libcamera/buffer_list.cc +++ b/device/libcamera/buffer_list.cc @@ -8,6 +8,11 @@ int libcamera_buffer_list_open(buffer_list_t *buf_list) return -1; } + if (buf_list->index > 0) { + LOG_INFO(buf_list, "Only single capture device is supported."); + return -1; + } + if (!buf_list->do_mmap) { LOG_INFO(buf_list, "Only mmap buffers are supported."); return -1; diff --git a/device/links.c b/device/links.c index a6effaf..5cb870a 100644 --- a/device/links.c +++ b/device/links.c @@ -60,10 +60,6 @@ int _build_fds(link_t *all_links, struct pollfd *fds, link_t **links, buffer_lis source->dev->paused = paused; - if (source->dev->output_device) { - source->dev->output_device->paused = paused; - } - int count_enqueued = buffer_list_count_enqueued(source); bool can_dequeue = count_enqueued > 0; diff --git a/device/v4l2/buffer_list.c b/device/v4l2/buffer_list.c index fc98593..15694da 100644 --- a/device/v4l2/buffer_list.c +++ b/device/v4l2/buffer_list.c @@ -15,6 +15,16 @@ int v4l2_buffer_list_open(buffer_list_t *buf_list) return -1; } + if (buf_list->path) { + buf_list->v4l2->dev_fd = open(buf_list->path, O_RDWR|O_NONBLOCK); + if (buf_list->v4l2->dev_fd < 0) { + LOG_ERROR(buf_list, "Can't open device: %s", buf_list->path); + return -1; + } + + LOG_INFO(buf_list, "Device path=%s fd=%d opened", buf_list->path, buf_list->v4l2->dev_fd); + } + struct v4l2_capability v4l2_cap; ERR_IOCTL(dev, buf_list->v4l2->dev_fd, VIDIOC_QUERYCAP, &v4l2_cap, "Can't query device capabilities"); @@ -25,7 +35,7 @@ int v4l2_buffer_list_open(buffer_list_t *buf_list) buf_list->v4l2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; buf_list->v4l2->do_mplanes = true; } else { - LOG_ERROR(dev, "Video capture is not supported by device: %08x", v4l2_cap.capabilities); + LOG_ERROR(buf_list, "Video capture is not supported by device: %08x", v4l2_cap.capabilities); } } else { if (v4l2_cap.capabilities & V4L2_CAP_VIDEO_OUTPUT) { @@ -34,7 +44,7 @@ int v4l2_buffer_list_open(buffer_list_t *buf_list) buf_list->v4l2->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; buf_list->v4l2->do_mplanes = true; } else { - LOG_ERROR(dev, "Video output is not supported by device: %08x", v4l2_cap.capabilities); + LOG_ERROR(buf_list, "Video output is not supported by device: %08x", v4l2_cap.capabilities); } }