From ac9831bd1ae3fc97e9653ba2ef48667cf0ca81a3 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Mon, 4 Apr 2022 14:55:16 +0200 Subject: [PATCH] WIP --- buffer.c | 48 ++++++++++++++++------------- buffer.h | 9 ++++-- buffer_list.c | 35 ++++++++++++--------- buffer_list.h | 10 +++--- buffer_queue.c | 81 +++++++++++++++++++++++++++++++++++++++++-------- camera_stream | Bin 22608 -> 22792 bytes device.c | 15 +++++---- main.c | 79 ++++++++++++++++++++++++++++++++++++++--------- 8 files changed, 202 insertions(+), 75 deletions(-) diff --git a/buffer.c b/buffer.c index 0174013..3250f9d 100644 --- a/buffer.c +++ b/buffer.c @@ -11,30 +11,33 @@ buffer_t *buffer_open(const char *name, buffer_list_t *buf_list, int index) { buf->buf_list = buf_list; buf->dma_fd = -1; - if (buf_list->do_mmap) { - buf->v4l2_buffer.type = buf_list->type; - buf->v4l2_buffer.memory = V4L2_MEMORY_MMAP; - buf->v4l2_buffer.index = index; + if (!buf_list->do_mmap) { + // nothing to do here + return buf; + } - if (buf_list->do_mplanes) { - buf->v4l2_buffer.length = 1; - buf->v4l2_buffer.m.planes = &buf->v4l2_plane; - } + buf->v4l2_buffer.type = buf_list->type; + buf->v4l2_buffer.memory = V4L2_MEMORY_MMAP; + buf->v4l2_buffer.index = index; - E_XIOCTL(buf_list, dev->fd, VIDIOC_QUERYBUF, &buf->v4l2_buffer, "Cannot query buffer %d", index); + if (buf_list->do_mplanes) { + buf->v4l2_buffer.length = 1; + buf->v4l2_buffer.m.planes = &buf->v4l2_plane; + } - if (buf_list->do_mplanes) { - buf->offset = buf->v4l2_plane.m.mem_offset; - buf->length = buf->v4l2_plane.length; - } else { - buf->offset = buf->v4l2_buffer.m.offset; - buf->length = buf->v4l2_buffer.length; - } + E_XIOCTL(buf_list, dev->fd, VIDIOC_QUERYBUF, &buf->v4l2_buffer, "Cannot query buffer %d", index); - buf->start = mmap(NULL, buf->length, PROT_READ | PROT_WRITE, MAP_SHARED, dev->fd, buf->offset); - if (buf->start == MAP_FAILED) { - goto error; - } + if (buf_list->do_mplanes) { + buf->offset = buf->v4l2_plane.m.mem_offset; + buf->length = buf->v4l2_plane.length; + } else { + buf->offset = buf->v4l2_buffer.m.offset; + buf->length = buf->v4l2_buffer.length; + } + + buf->start = mmap(NULL, buf->length, PROT_READ | PROT_WRITE, MAP_SHARED, dev->fd, buf->offset); + if (buf->start == MAP_FAILED) { + goto error; } if (buf_list->do_dma) { @@ -46,7 +49,10 @@ buffer_t *buffer_open(const char *name, buffer_list_t *buf_list, int index) { buf->dma_fd = v4l2_exp.fd; } - buffer_capture_enqueue(buf); + // enqueue buffer + buf->used = 0; + buf->mmap_reflinks = 1; + buffer_consumed(buf); return buf; diff --git a/buffer.h b/buffer.h index 649d1e0..182f9c7 100644 --- a/buffer.h +++ b/buffer.h @@ -8,14 +8,17 @@ typedef struct buffer_s { int index; void *start; size_t offset; + size_t used; size_t length; struct v4l2_buffer v4l2_buffer; struct v4l2_plane v4l2_plane; int dma_fd; - bool enqueued; + + int mmap_reflinks; + struct buffer_s *mmap_source; } buffer_t; buffer_t *buffer_open(const char *name, struct buffer_list_s *buf_list, int buffer); void buffer_close(buffer_t *buf); -bool buffer_output_dequeue(buffer_t *buf); -bool buffer_capture_enqueue(buffer_t *buf); + +bool buffer_consumed(buffer_t *buf); diff --git a/buffer_list.c b/buffer_list.c index 546c20d..8a77e37 100644 --- a/buffer_list.c +++ b/buffer_list.c @@ -2,7 +2,7 @@ #include "buffer_list.h" #include "device.h" -buffer_list_t *buffer_list_open(const char *name, struct device_s *dev, unsigned type) +buffer_list_t *buffer_list_open(const char *name, struct device_s *dev, unsigned type, bool do_mmap) { buffer_list_t *buf_list = calloc(1, sizeof(buffer_list_t)); @@ -12,21 +12,23 @@ buffer_list_t *buffer_list_open(const char *name, struct device_s *dev, unsigned switch(type) { case V4L2_BUF_TYPE_VIDEO_OUTPUT: + buf_list->do_mmap = do_mmap; break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + buf_list->do_mmap = do_mmap; buf_list->do_mplanes = true; break; case V4L2_BUF_TYPE_VIDEO_CAPTURE: - buf_list->do_dma = true; - buf_list->do_mmap = true; + 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 = true; - buf_list->do_mmap = true; + buf_list->do_dma = do_mmap; + buf_list->do_mmap = do_mmap; buf_list->do_mplanes = true; buf_list->do_capture = true; break; @@ -69,27 +71,27 @@ int buffer_list_set_format(buffer_list_t *buf_list, unsigned width, unsigned hei fmt->type = buf_list->type; if (buf_list->do_mplanes) { - fmt->fmt.pix.colorspace = V4L2_COLORSPACE_RAW; - fmt->fmt.pix.width = width; - fmt->fmt.pix.height = height; - fmt->fmt.pix.pixelformat = format; - fmt->fmt.pix.field = V4L2_FIELD_ANY; - fmt->fmt.pix.bytesperline = fourcc_to_stride(width, format); - } else { fmt->fmt.pix_mp.colorspace = V4L2_COLORSPACE_JPEG; fmt->fmt.pix_mp.width = width; fmt->fmt.pix_mp.height = height; fmt->fmt.pix_mp.pixelformat = format; fmt->fmt.pix_mp.field = V4L2_FIELD_ANY; fmt->fmt.pix_mp.num_planes = 1; - fmt->fmt.pix_mp.plane_fmt[0].bytesperline = fourcc_to_stride(width, format); + //fmt->fmt.pix_mp.plane_fmt[0].bytesperline = fourcc_to_stride(width, format); + } else { + fmt->fmt.pix.colorspace = V4L2_COLORSPACE_RAW; + fmt->fmt.pix.width = width; + fmt->fmt.pix.height = height; + fmt->fmt.pix.pixelformat = format; + fmt->fmt.pix.field = V4L2_FIELD_ANY; + fmt->fmt.pix.bytesperline = fourcc_to_stride(width, format); } E_LOG_DEBUG(buf_list, "Configuring format ..."); E_XIOCTL(buf_list, buf_list->device->fd, VIDIOC_S_FMT, fmt, "Can't set format"); if (fmt->fmt.pix.width != width || fmt->fmt.pix.height != height) { - E_LOG_ERROR(buf_list, "Requested resolution=%ux%u is unavailable. Got %ux%u.", + E_LOG_INFO(buf_list, "Requested resolution=%ux%u is unavailable. Got %ux%u.", width, height, fmt->fmt.pix.width, fmt->fmt.pix.height); } @@ -102,6 +104,11 @@ int buffer_list_set_format(buffer_list_t *buf_list, unsigned width, unsigned hei E_LOG_INFO(buf_list, "Using: %ux%u/%s", fmt->fmt.pix.width, fmt->fmt.pix.height, fourcc_to_string(fmt->fmt.pix.pixelformat).buf); + + buf_list->fmt_width = fmt->fmt.pix.width; + buf_list->fmt_height = fmt->fmt.pix.height; + buf_list->fmt_format = fmt->fmt.pix.pixelformat; + return 0; error: diff --git a/buffer_list.h b/buffer_list.h index 1ee2933..4ff5189 100644 --- a/buffer_list.h +++ b/buffer_list.h @@ -14,9 +14,11 @@ typedef struct buffer_list_s { bool do_mmap; bool do_dma; bool do_capture; + + unsigned fmt_width, fmt_height, fmt_format; } buffer_list_t; -buffer_list_t *buffer_list_open(const char *name, struct device_s *dev, unsigned type); +buffer_list_t *buffer_list_open(const char *name, struct device_s *dev, unsigned type, bool do_mmap); void buffer_list_close(buffer_list_t *buf_list); int buffer_list_set_format(buffer_list_t *buffer_list, unsigned width, unsigned height, unsigned format); @@ -24,7 +26,7 @@ int buffer_list_request(buffer_list_t *buf_list, int nbufs); bool buffer_list_wait_pool(buffer_list_t *buf_list, int timeout); -buffer_t *buffer_list_output_enqueue(buffer_list_t *buf_list, buffer_t *dma_buf); -buffer_t *buffer_list_capture_dequeue(buffer_list_t *buf_list); - int buffer_list_stream(buffer_list_t *buf_list, bool do_on); + +buffer_t *buffer_list_mmap_dequeue(buffer_list_t *buf_list); +buffer_t *buffer_list_mmap_enqueue(buffer_list_t *buf_list, buffer_t *dma_buf); diff --git a/buffer_queue.c b/buffer_queue.c index 94664d8..31267bb 100644 --- a/buffer_queue.c +++ b/buffer_queue.c @@ -11,19 +11,37 @@ bool buffer_output_dequeue(buffer_t *buf) return false; } -bool buffer_capture_enqueue(buffer_t *buf) +bool buffer_consumed(buffer_t *buf) { - if (buf->enqueued || !buf->buf_list->do_mmap || !buf->buf_list->do_capture) { - return false; + if (buf->buf_list->do_mmap) { + if (buf->mmap_reflinks <= 0) { + return true; + } + + buf->mmap_reflinks--; + + // update used bytes + if (buf->buf_list->do_mplanes) { + buf->v4l2_plane.bytesused = buf->used; + } else { + buf->v4l2_buffer.bytesused = buf->used; + } + + if (buf->mmap_reflinks == 0) { + E_LOG_DEBUG(buf, "Queuing buffer..."); + E_XIOCTL(buf, buf->buf_list->device->fd, VIDIOC_QBUF, &buf->v4l2_buffer, "Can't queue buffer."); + } + } else { + if (buf->mmap_source) { + buffer_consumed(buf->mmap_source); + buf->mmap_source = NULL; + } } - E_LOG_DEBUG(buf, "Queuing buffer..."); - E_XIOCTL(buf, buf->buf_list->device->fd, VIDIOC_QBUF, &buf->v4l2_buffer, "Can't queue buffer."); - - buf->enqueued = true; + return true; error: - return true; + return false; } buffer_t *buffer_list_output_enqueue(buffer_list_t *buf_list, buffer_t *dma_buf) @@ -49,9 +67,42 @@ buffer_t *buffer_list_output_enqueue(buffer_list_t *buf_list, buffer_t *dma_buf) return NULL; } -buffer_t *buffer_list_capture_dequeue(buffer_list_t *buf_list) +buffer_t *buffer_list_mmap_enqueue(buffer_list_t *buf_list, buffer_t *dma_buf) { - if (!buf_list->do_mmap || !buf_list->do_capture) { + buffer_t *buf = NULL; + + if (!buf_list->do_mmap && !dma_buf->buf_list->do_mmap) { + E_LOG_PERROR(buf_list, "Cannot enqueue non-mmap to non-mmap: %s.", dma_buf->name); + } + + if (!buf_list->do_mmap) { + E_LOG_PERROR(buf_list, "Not yet supported: %s.", dma_buf->name); + } + + buf = buffer_list_mmap_dequeue(buf_list); + if (!buf) { + return NULL; + } + + if (dma_buf->used > buf->length) { + E_LOG_PERROR(buf_list, "The dma_buf (%s) is too long: %zu vs space=%zu", + dma_buf->name, dma_buf->used, buf->length); + } + + E_LOG_DEBUG(buf, "mmap copy: dest=%p, src=%p (%s), size=%zu, space=%zu", + buf->start, dma_buf->start, dma_buf->name, dma_buf->used, buf->length); + memcpy(buf->start, dma_buf->start, dma_buf->used); + buffer_consumed(buf); + + return NULL; + +error: + return NULL; +} + +buffer_t *buffer_list_mmap_dequeue(buffer_list_t *buf_list) +{ + if (!buf_list->do_mmap) { return NULL; } @@ -67,17 +118,21 @@ buffer_t *buffer_list_capture_dequeue(buffer_list_t *buf_list) } E_XIOCTL(buf_list, buf_list->device->fd, VIDIOC_DQBUF, &v4l2_buf, "Can't grab capture buffer"); - E_LOG_DEBUG(buf_list, "Grabbed INPUT buffer=%u, bytes=%d", - v4l2_buf.index, v4l2_buf.length); buffer_t *buf = buf_list->bufs[v4l2_buf.index]; buf->v4l2_plane = v4l2_plane; buf->v4l2_buffer = v4l2_buf; if (buf_list->do_mplanes) { buf->v4l2_buffer.m.planes = &buf->v4l2_plane; + buf->used = buf->v4l2_plane.bytesused; + } else { + buf->used = buf->v4l2_buffer.bytesused; } - buf->enqueued = false; + E_LOG_DEBUG(buf_list, "Grabbed mmap buffer=%u, bytes=%d, used=%d", + buf->index, buf->length, buf->used); + + buf->mmap_reflinks = 1; return buf; diff --git a/camera_stream b/camera_stream index 1dd7effb7e56c9cebad28d689ded373f3459250d..77efafa5263771b870647971238ade500f6f4617 100755 GIT binary patch delta 9115 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 + do_mmap = true; 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) { + } 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"); + E_LOG_ERROR(dev, "Video capture is not supported by device: %08x", dev->v4l2_cap.capabilities); } } else { - buf_list = &dev->capture_list; + buf_list = &dev->output_list; + do_mmap = true; 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) { + } 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"); + E_LOG_ERROR(dev, "Video output is not supported by device: %08x", dev->v4l2_cap.capabilities); } } - *buf_list = buffer_list_open(name, dev, type); + *buf_list = buffer_list_open(name, dev, type, do_mmap); if (!*buf_list) { goto error; } diff --git a/main.c b/main.c index b5700a1..4fb49bd 100644 --- a/main.c +++ b/main.c @@ -12,6 +12,7 @@ device_t *camera = NULL; device_t *isp_srgb = NULL; device_t *isp_yuuv = NULL; device_t *isp_yuuv_low = NULL; +device_t *codec_jpeg = NULL; int open_camera(const char *path) { @@ -27,7 +28,7 @@ int open_camera(const char *path) return 0; } -int open_isp(const char *srgb_path, const char *yuuv_path, const char *yuuv_low_path) +int open_isp(buffer_list_t *src, const char *srgb_path, const char *yuuv_path, const char *yuuv_low_path) { isp_srgb = device_open("ISP-SRGB", srgb_path); isp_yuuv = device_open("ISP-YUUV", yuuv_path); @@ -37,9 +38,24 @@ int open_isp(const char *srgb_path, const char *yuuv_path, const char *yuuv_low_ return -1; } - if (device_open_buffer_list(isp_srgb, false, camera_width, camera_height, camera_format, camera_nbufs) < 0 || - device_open_buffer_list(isp_yuuv, true, camera_width, camera_height, V4L2_PIX_FMT_YUYV, camera_nbufs) < 0 || - device_open_buffer_list(isp_yuuv, true, camera_width / 2, camera_height / 2, V4L2_PIX_FMT_YUYV, camera_nbufs) < 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; + } + + return 0; +} + +int open_jpeg(buffer_list_t *src, const char *jpeg_codec) +{ + codec_jpeg = device_open("JPEG", jpeg_codec); + if (!codec_jpeg) { + return -1; + } + + 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; } @@ -51,26 +67,61 @@ int main(int argc, char *argv[]) if (open_camera("/dev/video0") < 0) { goto error; } - - // if (open_isp("/dev/video13", "/dev/video14", "/dev/video15") < 0) { - // goto error; - // } + if (open_isp(camera->capture_list, "/dev/video13", "/dev/video14", "/dev/video15") < 0) { + goto error; + } + if (open_jpeg(isp_yuuv->capture_list, "/dev/video31") < 0) { + goto error; + } // return; if (device_stream(camera, true) < 0) { goto error; } - //return; + if (device_stream(isp_srgb, true) < 0) { + goto error; + } + if (device_stream(isp_yuuv, true) < 0) { + goto error; + } + if (device_stream(isp_yuuv_low, true) < 0) { + goto error; + } + if (device_stream(codec_jpeg, true) < 0) { + goto error; + } while(true) { - if (buffer_list_wait_pool(camera->capture_list, 1000000)) { - buffer_t *buf; - if (buf = buffer_list_capture_dequeue(camera->capture_list)) { - E_LOG_INFO(camera, "Got camera buffer: %p", buf); - buffer_capture_enqueue(buf); + buffer_t *buf; + + if (buffer_list_wait_pool(camera->capture_list, 100)) { + if (buf = buffer_list_mmap_dequeue(camera->capture_list)) { + buffer_list_mmap_enqueue(isp_srgb->output_list, buf); + buffer_consumed(buf); } } + + if (buffer_list_wait_pool(isp_yuuv->capture_list, 100)) { + if (buf = buffer_list_mmap_dequeue(isp_yuuv->capture_list)) { + buffer_list_mmap_enqueue(codec_jpeg->output_list, buf); + buffer_consumed(buf); + } + } + + if (buffer_list_wait_pool(isp_yuuv_low->capture_list, 100)) { + if (buf = buffer_list_mmap_dequeue(isp_yuuv_low->capture_list)) { + buffer_consumed(buf); + } + } + + if (buffer_list_wait_pool(codec_jpeg->capture_list, 100)) { + if (buf = buffer_list_mmap_dequeue(codec_jpeg->capture_list)) { + buffer_consumed(buf); + } + } + + usleep(100*1000); } error: