diff --git a/device.c b/device.c index 5d7b218..a61d7cf 100644 --- a/device.c +++ b/device.c @@ -7,6 +7,7 @@ device_t *device_open(const char *name, const char *path) { dev->name = strdup(name); dev->path = strdup(path); dev->fd = open(path, O_RDWR|O_NONBLOCK); + dev->allow_dma = true; if(dev->fd < 0) { E_LOG_ERROR(dev, "Can't open device"); } @@ -48,7 +49,7 @@ void device_close(device_t *dev) { free(dev); } -int device_open_buffer_list(device_t *dev, bool do_capture, unsigned width, unsigned height, unsigned format, int nbufs, bool allow_dma) +int device_open_buffer_list(device_t *dev, bool do_capture, unsigned width, unsigned height, unsigned format, int nbufs) { unsigned type; char name[64]; @@ -59,6 +60,10 @@ int device_open_buffer_list(device_t *dev, bool do_capture, unsigned width, unsi buf_list = &dev->capture_list; do_mmap = true; + if (dev->capture_list) { + 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); @@ -70,7 +75,11 @@ int device_open_buffer_list(device_t *dev, bool do_capture, unsigned width, unsi } } else { buf_list = &dev->output_list; - do_mmap = !allow_dma; + do_mmap = !dev->allow_dma; + + if (dev->output_list) { + 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; diff --git a/device.h b/device.h index 9d80b1c..c000582 100644 --- a/device.h +++ b/device.h @@ -7,15 +7,18 @@ typedef struct device_s { char *path; int fd; struct v4l2_capability v4l2_cap; + bool allow_dma; struct buffer_list_s *capture_list; struct buffer_list_s *output_list; + + struct device_s *upstream_device; } device_t; device_t *device_open(const char *name, const char *path); void device_close(device_t *device); -int device_open_buffer_list(device_t *dev, bool do_capture, unsigned width, unsigned height, unsigned format, int nbufs, bool allow_dma); +int device_open_buffer_list(device_t *dev, bool do_capture, unsigned width, unsigned height, unsigned format, int nbufs); int device_consume_event(device_t *device); int device_stream(device_t *dev, bool do_on); diff --git a/links.c b/links.c index 1e9be4e..4431830 100644 --- a/links.c +++ b/links.c @@ -100,6 +100,22 @@ error: return -1; } +int links_open_buffer_list_from(device_t *dev, bool do_capture, buffer_list_t *parent_buffer, unsigned format) +{ + if (!parent_buffer) { + return -1; + } + + return device_open_buffer_list( + dev, + do_capture, + parent_buffer->fmt_width, + parent_buffer->fmt_height, + format ? format : parent_buffer->fmt_format, + parent_buffer->nbufs + ); +} + int links_init(link_t *all_links) { // create all outputs (sinks) @@ -109,6 +125,20 @@ int links_init(link_t *all_links) if (!link->capture) { E_LOG_ERROR(NULL, "Missing link capture."); } + + if (link->capture_format) { + int ret = links_open_buffer_list_from( + link->capture, + true, + link->capture->upstream_device ? link->capture->upstream_device->output_list : link->capture->output_list, + link->capture_format + ); + + if (ret < 0) { + E_LOG_ERROR(link->capture, "Failed to create capture_list."); + } + } + if (!link->capture->capture_list) { E_LOG_ERROR(link->capture, "Missing capture device."); } @@ -116,20 +146,9 @@ int links_init(link_t *all_links) for (int j = 0; link->outputs[j]; j++) { device_t *output = link->outputs[j]; - if (output->output_list) { - E_LOG_ERROR(output, "Device already has output created. Duplicate?"); - } - - int ret = device_open_buffer_list(output, false, - link->capture->capture_list->fmt_width, - link->capture->capture_list->fmt_height, - link->capture->capture_list->fmt_format, - link->capture->capture_list->nbufs, - true - ); - + int ret = links_open_buffer_list_from(output, false, link->capture->capture_list, 0); if (ret < 0) { - E_LOG_ERROR(output, "Failed to create capture."); + E_LOG_ERROR(output, "Failed to create output_list."); } } } @@ -150,9 +169,11 @@ int links_loop(link_t *all_links, bool *running) while(*running) { if (links_step(all_links, 1000) < 0) { + links_stream(all_links, false); return -1; } } + links_stream(all_links, false); return 0; } \ No newline at end of file diff --git a/links.h b/links.h index a3ad92c..aaa8961 100644 --- a/links.h +++ b/links.h @@ -6,6 +6,8 @@ typedef struct link_s { struct device_s *capture; // capture_list struct device_s *outputs[10]; void (*on_buffer)(struct buffer_s *buf); + + unsigned capture_format; } link_t; int links_init(link_t *all_links); diff --git a/main.c b/main.c index 2077e4a..a08f4fd 100644 --- a/main.c +++ b/main.c @@ -16,20 +16,11 @@ device_t *isp_yuuv = NULL; device_t *isp_yuuv_low = NULL; device_t *codec_jpeg = NULL; -int open_camera(const char *path) -{ - if (device_open_buffer_list(camera, true, camera_width, camera_height, camera_format, camera_nbufs, true) < 0) { - return -1; - } - - return 0; -} - int open_isp(buffer_list_t *src, const char *srgb_path, const char *yuuv_path, const char *yuuv_low_path) { - if (device_open_buffer_list(isp_srgb, false, src->fmt_width, src->fmt_height, src->fmt_format, camera_nbufs, true) < 0 || - device_open_buffer_list(isp_yuuv, true, src->fmt_width, src->fmt_height, V4L2_PIX_FMT_YUYV, camera_nbufs, true) < 0 || - device_open_buffer_list(isp_yuuv_low, true, src->fmt_width / 2, src->fmt_height / 2, V4L2_PIX_FMT_YUYV, camera_nbufs, true) < 0) { + if (device_open_buffer_list(isp_srgb, false, src->fmt_width, src->fmt_height, src->fmt_format, camera_nbufs) < 0 || + device_open_buffer_list(isp_yuuv, true, src->fmt_width, src->fmt_height, V4L2_PIX_FMT_YUYV, camera_nbufs) < 0 || + device_open_buffer_list(isp_yuuv_low, true, src->fmt_width / 2, src->fmt_height / 2, V4L2_PIX_FMT_YUYV, camera_nbufs) < 0) { return -1; } @@ -38,8 +29,8 @@ int open_isp(buffer_list_t *src, const char *srgb_path, const char *yuuv_path, c int open_jpeg(buffer_list_t *src, const char *tmp) { - if (device_open_buffer_list(codec_jpeg, false, src->fmt_width, src->fmt_height, src->fmt_format, camera_nbufs, false) < 0 || - device_open_buffer_list(codec_jpeg, true, src->fmt_width, src->fmt_height, V4L2_PIX_FMT_JPEG, camera_nbufs, false) < 0) { + if (device_open_buffer_list(codec_jpeg, false, src->fmt_width, src->fmt_height, src->fmt_format, camera_nbufs) < 0 || + device_open_buffer_list(codec_jpeg, true, src->fmt_width, src->fmt_height, V4L2_PIX_FMT_JPEG, camera_nbufs) < 0) { return -1; } @@ -60,18 +51,20 @@ void write_jpeg(buffer_t *buf) int main(int argc, char *argv[]) { camera = device_open("CAMERA", "/dev/video0"); - isp_srgb = device_open("ISP-SRGB", "/dev/video13"); - isp_yuuv = device_open("ISP-YUUV", "/dev/video14"); - isp_yuuv_low = device_open("ISP-YUUV-LOW", "/dev/video15"); - codec_jpeg = device_open("JPEG", "/dev/video31"); - if (device_open_buffer_list(camera, true, camera_width, camera_height, camera_format, camera_nbufs, true) < 0) { + if (device_open_buffer_list(camera, true, camera_width, camera_height, camera_format, camera_nbufs) < 0) { return -1; } - if (open_camera("/dev/video0") < 0) { - goto error; - } + isp_srgb = device_open("ISP-SRGB", "/dev/video13"); + isp_srgb->allow_dma = false; + isp_yuuv = device_open("ISP-YUUV", "/dev/video14"); + isp_yuuv->upstream_device = isp_srgb; + isp_yuuv_low = device_open("ISP-YUUV-LOW", "/dev/video15"); + isp_yuuv_low->upstream_device = isp_srgb; + codec_jpeg = device_open("JPEG", "/dev/video31"); + codec_jpeg->allow_dma = false; + if (open_isp(camera->capture_list, "/dev/video13", "/dev/video14", "/dev/video15") < 0) { goto error; } @@ -82,30 +75,33 @@ int main(int argc, char *argv[]) link_t links[] = { { camera, - {isp_srgb}, + { isp_srgb }, NULL }, { isp_yuuv, { camera_use_low ? NULL : codec_jpeg }, - NULL + NULL, + V4L2_PIX_FMT_YUYV }, { isp_yuuv_low, { camera_use_low ? codec_jpeg : NULL }, - NULL + NULL, + V4L2_PIX_FMT_YUYV }, { codec_jpeg, - {}, - write_jpeg + { }, + write_jpeg, + V4L2_PIX_FMT_JPEG }, { NULL } }; - if (links_init(links) < 0) { - return -1; - } + // if (links_init(links) < 0) { + // return -1; + // } bool running = false; links_loop(links, &running);