Make device to support composite devices (single output, many captures)
This commit is contained in:
		@@ -93,7 +93,7 @@ int camera_set_params(camera_t *camera)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  device_set_fps(camera->camera, camera->options.fps);
 | 
					  device_set_fps(camera->camera, camera->options.fps);
 | 
				
			||||||
  device_set_option_list(camera->camera, camera->options.options);
 | 
					  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, camera->options.h264.options);
 | 
				
			||||||
  device_set_option_list(camera->codec_h264_lowres, 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);
 | 
					  device_set_option_list(camera->codec_jpeg, camera->options.jpeg.options);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -55,10 +55,7 @@ typedef struct camera_s {
 | 
				
			|||||||
    struct {
 | 
					    struct {
 | 
				
			||||||
      device_t *camera;
 | 
					      device_t *camera;
 | 
				
			||||||
      device_t *decoder; // decode JPEG/H264 into YUVU
 | 
					      device_t *decoder; // decode JPEG/H264 into YUVU
 | 
				
			||||||
      device_t *legacy_isp; // convert pRAA/YUVU into YUVU
 | 
					      device_t *isp;
 | 
				
			||||||
      device_t *isp_srgb;
 | 
					 | 
				
			||||||
      device_t *isp_yuuv;
 | 
					 | 
				
			||||||
      device_t *isp_yuuv_lowres;
 | 
					 | 
				
			||||||
      device_t *codec_jpeg; // encode YUVU into JPEG
 | 
					      device_t *codec_jpeg; // encode YUVU into JPEG
 | 
				
			||||||
      device_t *codec_h264; // encode YUVU into H264
 | 
					      device_t *codec_h264; // encode YUVU into H264
 | 
				
			||||||
      device_t *codec_jpeg_lowres; // encode YUVU into JPEG
 | 
					      device_t *codec_jpeg_lowres; // encode YUVU into JPEG
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,16 +15,12 @@ int camera_configure_isp(camera_t *camera, buffer_list_t *camera_capture, float
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  link_t *links = camera->links;
 | 
					  link_t *links = camera->links;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  camera->isp_srgb = device_v4l2_open("ISP", "/dev/video13");
 | 
					  camera->isp = 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->codec_jpeg = device_v4l2_open("JPEG", "/dev/video31");
 | 
					  camera->codec_jpeg = device_v4l2_open("JPEG", "/dev/video31");
 | 
				
			||||||
  camera->codec_h264 = device_v4l2_open("H264", "/dev/video11");
 | 
					  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_output = device_open_buffer_list_output(camera->isp, 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_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 } };
 | 
					  *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;
 | 
					    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_jpeg_lowres = device_v4l2_open("JPEG-LOW", "/dev/video31");
 | 
				
			||||||
  camera->codec_h264_lowres = device_v4l2_open("H264-LOW", "/dev/video11");
 | 
					  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_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);
 | 
					  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);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
					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_jpeg = device_v4l2_open("JPEG", "/dev/video31");
 | 
				
			||||||
  camera->codec_h264 = device_v4l2_open("H264", "/dev/video11");
 | 
					  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_output = device_open_buffer_list_output(camera->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_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_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);
 | 
					  buffer_list_t *jpeg_capture = device_open_buffer_list_capture(camera->codec_jpeg, jpeg_output, 1.0, V4L2_PIX_FMT_JPEG, true);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
					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;
 | 
					  unsigned type;
 | 
				
			||||||
  char name[64];
 | 
					  char name[64];
 | 
				
			||||||
@@ -85,7 +90,7 @@ buffer_list_t *device_open_buffer_list(device_t *dev, bool do_capture, unsigned
 | 
				
			|||||||
    .nbufs = nbufs
 | 
					    .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) {
 | 
					  if (!buf_list) {
 | 
				
			||||||
    goto error;
 | 
					    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)
 | 
					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) {
 | 
					  if (!dev || !output_list) {
 | 
				
			||||||
    return NULL;
 | 
					    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,
 | 
					    output_list->fmt.width / div, output_list->fmt.height / div,
 | 
				
			||||||
    format, 0, output_list->nbufs, do_mmap);
 | 
					    format, 0, output_list->nbufs, do_mmap);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -47,7 +47,6 @@ typedef struct device_s {
 | 
				
			|||||||
    struct device_libcamera_s *libcamera;
 | 
					    struct device_libcamera_s *libcamera;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  device_t *output_device;
 | 
					 | 
				
			||||||
  bool paused;
 | 
					  bool paused;
 | 
				
			||||||
  bool decoder_started;
 | 
					  bool decoder_started;
 | 
				
			||||||
} device_t;
 | 
					} 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);
 | 
					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, 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_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_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_consume_event(device_t *dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int device_set_stream(device_t *dev, bool do_on);
 | 
					int device_set_stream(device_t *dev, bool do_on);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,11 @@ int libcamera_buffer_list_open(buffer_list_t *buf_list)
 | 
				
			|||||||
    return -1;
 | 
					    return -1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (buf_list->index > 0) {
 | 
				
			||||||
 | 
					    LOG_INFO(buf_list, "Only single capture device is supported.");
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!buf_list->do_mmap) {
 | 
					  if (!buf_list->do_mmap) {
 | 
				
			||||||
    LOG_INFO(buf_list, "Only mmap buffers are supported.");
 | 
					    LOG_INFO(buf_list, "Only mmap buffers are supported.");
 | 
				
			||||||
    return -1;
 | 
					    return -1;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -60,10 +60,6 @@ int _build_fds(link_t *all_links, struct pollfd *fds, link_t **links, buffer_lis
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    source->dev->paused = paused;
 | 
					    source->dev->paused = paused;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (source->dev->output_device) {
 | 
					 | 
				
			||||||
      source->dev->output_device->paused = paused;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    int count_enqueued = buffer_list_count_enqueued(source);
 | 
					    int count_enqueued = buffer_list_count_enqueued(source);
 | 
				
			||||||
    bool can_dequeue = count_enqueued > 0;
 | 
					    bool can_dequeue = count_enqueued > 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,6 +15,16 @@ int v4l2_buffer_list_open(buffer_list_t *buf_list)
 | 
				
			|||||||
    return -1;
 | 
					    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;
 | 
					  struct v4l2_capability v4l2_cap;
 | 
				
			||||||
  ERR_IOCTL(dev, buf_list->v4l2->dev_fd, VIDIOC_QUERYCAP, &v4l2_cap, "Can't query device capabilities");
 | 
					  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->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
 | 
				
			||||||
      buf_list->v4l2->do_mplanes = true;
 | 
					      buf_list->v4l2->do_mplanes = true;
 | 
				
			||||||
    } else {
 | 
					    } 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 {
 | 
					  } else {
 | 
				
			||||||
    if (v4l2_cap.capabilities & V4L2_CAP_VIDEO_OUTPUT) {
 | 
					    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->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
 | 
				
			||||||
      buf_list->v4l2->do_mplanes = true;
 | 
					      buf_list->v4l2->do_mplanes = true;
 | 
				
			||||||
    } else {
 | 
					    } 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);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user