From 33b7062bf1eb76b1c6010b96ab88b0b94916402b Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Sun, 10 Apr 2022 11:24:25 +0200 Subject: [PATCH] Make `device/buffer_list*` be generic --- cmd/camera_stream.c | 2 +- device/buffer.c | 2 +- device/buffer_list.c | 94 +++++++++++++++++++++++++++++++ device/{hw => }/buffer_list.h | 4 +- device/buffer_lock.c | 2 +- device/buffer_queue.c | 2 +- device/camera.c | 2 +- device/camera_decoder.c | 4 +- device/camera_direct.c | 4 +- device/camera_isp.c | 4 +- device/camera_legacy_isp.c | 4 +- device/hw/device.c | 2 +- device/hw/device.h | 4 ++ device/links.c | 2 +- device/v4l2/buffer.c | 4 +- device/{hw => v4l2}/buffer_list.c | 89 +++-------------------------- device/v4l2/debug.c | 2 +- device/v4l2/device.c | 3 + device/v4l2/v4l2.h | 4 ++ http/http_ffmpeg.c | 2 +- http/http_h264.c | 2 +- 21 files changed, 134 insertions(+), 104 deletions(-) create mode 100644 device/buffer_list.c rename device/{hw => }/buffer_list.h (87%) rename device/{hw => v4l2}/buffer_list.c (72%) diff --git a/cmd/camera_stream.c b/cmd/camera_stream.c index cc52c23..adc9e56 100644 --- a/cmd/camera_stream.c +++ b/cmd/camera_stream.c @@ -1,5 +1,5 @@ #include "device/buffer.h" -#include "device/hw/buffer_list.h" +#include "device/buffer_list.h" #include "device/hw/device.h" #include "device/links.h" #include "device/hw/v4l2.h" diff --git a/device/buffer.c b/device/buffer.c index 86762c3..fe2cc4e 100644 --- a/device/buffer.c +++ b/device/buffer.c @@ -1,5 +1,5 @@ #include "device/buffer.h" -#include "device/hw/buffer_list.h" +#include "device/buffer_list.h" #include "device/hw/device.h" #include "device/hw/v4l2.h" diff --git a/device/buffer_list.c b/device/buffer_list.c new file mode 100644 index 0000000..4718c69 --- /dev/null +++ b/device/buffer_list.c @@ -0,0 +1,94 @@ +#include "device/buffer.h" +#include "device/buffer_list.h" +#include "device/hw/device.h" +#include "device/hw/v4l2.h" + +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->do_capture = do_capture; + buf_list->do_mmap = do_mmap; + return buf_list; + +error: + buffer_list_close(buf_list); + return NULL; +} + +void buffer_list_close(buffer_list_t *buf_list) +{ + if (!buf_list) { + return; + } + + if (buf_list->bufs) { + for (int i = 0; i < buf_list->nbufs; i++) { + buffer_close(buf_list->bufs[i]); + } + free(buf_list->bufs); + buf_list->bufs = NULL; + buf_list->nbufs = 0; + } + + free(buf_list->name); + free(buf_list); +} + +int buffer_list_set_format(buffer_list_t *buf_list, unsigned width, unsigned height, unsigned format, unsigned bytesperline) +{ + return buf_list->device->hw->buffer_list_set_format(buf_list, width, height, format, bytesperline); +} + +int buffer_list_set_buffers(buffer_list_t *buf_list, int nbufs) +{ + int got_bufs = buf_list->device->hw->buffer_list_set_buffers(buf_list, nbufs); + if (got_bufs <= 0) { + goto error; + } + + buf_list->bufs = calloc(got_bufs, sizeof(buffer_t*)); + buf_list->nbufs = got_bufs; + + for (unsigned i = 0; i < buf_list->nbufs; i++) { + char name[64]; + sprintf(name, "%s:buf%d", buf_list->name, i); + buffer_t *buf = buffer_open(name, buf_list, i); + if (!buf) { + E_LOG_ERROR(buf_list, "Cannot open buffer: %u", i); + goto error; + } + buf_list->bufs[i] = buf; + } + + E_LOG_DEBUG(buf_list, "Opened %u buffers", buf_list->nbufs); + return 0; + +error: + return -1; +} + +int buffer_list_set_stream(buffer_list_t *buf_list, bool do_on) +{ + if (!buf_list) { + return -1; + } + + if (buf_list->streaming == do_on) { + return 0; + } + + if (buf_list->device->hw->buffer_list_set_stream(buf_list, do_on) < 0) { + goto error; + } + buf_list->streaming = do_on; + + int enqueued = buffer_list_count_enqueued(buf_list); + E_LOG_DEBUG(buf_list, "Streaming %s... Was %d of %d enqueud", do_on ? "started" : "stopped", enqueued, buf_list->nbufs); + return 0; + +error: + return -1; +} diff --git a/device/hw/buffer_list.h b/device/buffer_list.h similarity index 87% rename from device/hw/buffer_list.h rename to device/buffer_list.h index cb1379f..c6d5b31 100644 --- a/device/hw/buffer_list.h +++ b/device/buffer_list.h @@ -14,7 +14,7 @@ typedef struct buffer_list_s { buffer_t **bufs; int nbufs; - bool do_mmap, do_dma, do_capture; + bool do_mmap, do_capture; struct { bool do_mplanes; @@ -34,7 +34,7 @@ buffer_list_t *buffer_list_open(const char *name, struct device_s *dev, bool do_ void buffer_list_close(buffer_list_t *buf_list); int buffer_list_set_stream(buffer_list_t *buf_list, bool do_on); -int buffer_list_set_format(buffer_list_t *buffer_list, unsigned width, unsigned height, unsigned format, unsigned bytesperline); +int buffer_list_set_format(buffer_list_t *buf_list, unsigned width, unsigned height, unsigned format, unsigned bytesperline); int buffer_list_set_buffers(buffer_list_t *buf_list, int nbufs); int buffer_list_pollfd(buffer_list_t *buf_list, struct pollfd *pollfd, bool can_dequeue); diff --git a/device/buffer_lock.c b/device/buffer_lock.c index c0bf3b3..e19aee6 100644 --- a/device/buffer_lock.c +++ b/device/buffer_lock.c @@ -1,5 +1,5 @@ #include "device/buffer_lock.h" -#include "device/hw/buffer_list.h" +#include "device/buffer_list.h" #include "device/buffer.h" #include "device/hw/v4l2.h" diff --git a/device/buffer_queue.c b/device/buffer_queue.c index f40d3b3..c475507 100644 --- a/device/buffer_queue.c +++ b/device/buffer_queue.c @@ -1,5 +1,5 @@ #include "device/buffer.h" -#include "device/hw/buffer_list.h" +#include "device/buffer_list.h" #include "device/hw/device.h" #include "device/hw/v4l2.h" #include diff --git a/device/camera.c b/device/camera.c index 130dfd7..1625b39 100644 --- a/device/camera.c +++ b/device/camera.c @@ -1,7 +1,7 @@ #include "camera.h" #include "device/hw/device.h" -#include "device/hw/buffer_list.h" +#include "device/buffer_list.h" #include "device/links.h" #include "device/hw/v4l2.h" diff --git a/device/camera_decoder.c b/device/camera_decoder.c index b28266a..48b153d 100644 --- a/device/camera_decoder.c +++ b/device/camera_decoder.c @@ -1,11 +1,11 @@ #include "camera.h" #include "device/buffer.h" -#include "device/hw/buffer_list.h" +#include "device/buffer_list.h" #include "device/hw/device.h" #include "device/links.h" #include "device/hw/v4l2.h" -#include "device/hw/buffer_list.h" +#include "device/buffer_list.h" #include "http/http.h" int camera_configure_decoder(camera_t *camera) diff --git a/device/camera_direct.c b/device/camera_direct.c index 8635633..0d23a4c 100644 --- a/device/camera_direct.c +++ b/device/camera_direct.c @@ -1,11 +1,11 @@ #include "camera.h" #include "device/buffer.h" -#include "device/hw/buffer_list.h" +#include "device/buffer_list.h" #include "device/hw/device.h" #include "device/links.h" #include "device/hw/v4l2.h" -#include "device/hw/buffer_list.h" +#include "device/buffer_list.h" #include "http/http.h" int camera_configure_direct(camera_t *camera) diff --git a/device/camera_isp.c b/device/camera_isp.c index 57afaef..0c06f8f 100644 --- a/device/camera_isp.c +++ b/device/camera_isp.c @@ -1,11 +1,11 @@ #include "camera.h" #include "device/buffer.h" -#include "device/hw/buffer_list.h" +#include "device/buffer_list.h" #include "device/hw/device.h" #include "device/links.h" #include "device/hw/v4l2.h" -#include "device/hw/buffer_list.h" +#include "device/buffer_list.h" #include "http/http.h" void write_yuvu(buffer_t *buffer); diff --git a/device/camera_legacy_isp.c b/device/camera_legacy_isp.c index 15d7442..e9a9e65 100644 --- a/device/camera_legacy_isp.c +++ b/device/camera_legacy_isp.c @@ -1,11 +1,11 @@ #include "camera.h" #include "device/buffer.h" -#include "device/hw/buffer_list.h" +#include "device/buffer_list.h" #include "device/hw/device.h" #include "device/links.h" #include "device/hw/v4l2.h" -#include "device/hw/buffer_list.h" +#include "device/buffer_list.h" #include "http/http.h" void write_yuvu(buffer_t *buffer) diff --git a/device/hw/device.c b/device/hw/device.c index e90a6d6..8f16385 100644 --- a/device/hw/device.c +++ b/device/hw/device.c @@ -1,6 +1,6 @@ #include "device/hw/device.h" #include "device/buffer.h" -#include "device/hw/buffer_list.h" +#include "device/buffer_list.h" #include "device/hw/v4l2.h" device_t *device_open(const char *name, const char *path, device_hw_t *hw) { diff --git a/device/hw/device.h b/device/hw/device.h index 6607464..8b467b4 100644 --- a/device/hw/device.h +++ b/device/hw/device.h @@ -15,6 +15,10 @@ typedef struct device_hw_s { int (*buffer_enqueue)(buffer_t *buf, const char *who); int (*buffer_list_dequeue)(buffer_list_t *buf_list, buffer_t **bufp); int (*buffer_list_pollfd)(buffer_list_t *buf_list, struct pollfd *pollfd, bool can_dequeue); + + int (*buffer_list_set_format)(buffer_list_t *buf_list, unsigned width, unsigned height, unsigned format, unsigned bytesperline); + int (*buffer_list_set_buffers)(buffer_list_t *buf_list, int nbufs); + int (*buffer_list_set_stream)(buffer_list_t *buf_list, bool do_on); } device_hw_t; typedef struct device_s { diff --git a/device/links.c b/device/links.c index c9941de..f98397f 100644 --- a/device/links.c +++ b/device/links.c @@ -1,7 +1,7 @@ #include "device/links.h" #include "device/hw/device.h" #include "device/buffer.h" -#include "device/hw/buffer_list.h" +#include "device/buffer_list.h" #include "device/hw/v4l2.h" #define N_FDS 50 diff --git a/device/v4l2/buffer.c b/device/v4l2/buffer.c index a470a15..0c417f3 100644 --- a/device/v4l2/buffer.c +++ b/device/v4l2/buffer.c @@ -1,6 +1,6 @@ #include "device/v4l2/v4l2.h" #include "device/buffer.h" -#include "device/hw/buffer_list.h" +#include "device/buffer_list.h" #include "device/hw/device.h" int v4l2_buffer_open(buffer_t *buf) @@ -43,9 +43,7 @@ int v4l2_buffer_open(buffer_t *buf) if (buf->start == MAP_FAILED) { goto error; } - } - if (buf_list->do_dma) { struct v4l2_exportbuffer v4l2_exp = {0}; v4l2_exp.type = v4l2_buf.type; v4l2_exp.index = buf->index; diff --git a/device/hw/buffer_list.c b/device/v4l2/buffer_list.c similarity index 72% rename from device/hw/buffer_list.c rename to device/v4l2/buffer_list.c index 8ba86cd..4c96762 100644 --- a/device/hw/buffer_list.c +++ b/device/v4l2/buffer_list.c @@ -1,42 +1,30 @@ +#include "device/v4l2/v4l2.h" #include "device/buffer.h" -#include "device/hw/buffer_list.h" +#include "device/buffer_list.h" #include "device/hw/device.h" -#include "device/hw/v4l2.h" -buffer_list_t *buffer_list_open(const char *name, struct device_s *dev, bool do_capture, bool do_mmap) +int v4l2_buffer_list_set_format(buffer_list_t *buf_list, unsigned width, unsigned height, unsigned format, unsigned bytesperline) { - buffer_list_t *buf_list = calloc(1, sizeof(buffer_list_t)); - - buf_list->device = dev; - buf_list->name = strdup(name); - buf_list->do_capture = do_capture; + device_t *dev = buf_list->device; struct v4l2_capability v4l2_cap; E_XIOCTL(dev, dev->fd, VIDIOC_QUERYCAP, &v4l2_cap, "Can't query device capabilities"); - if (do_capture) { + if (buf_list->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); } @@ -49,43 +37,12 @@ buffer_list_t *buffer_list_open(const char *name, struct device_s *dev, bool do_ strcat(buf_list->name, MPLANE_SUFFIX); } - return buf_list; - -error: - buffer_list_close(buf_list); - return NULL; -} - -void buffer_list_close(buffer_list_t *buf_list) -{ - if (!buf_list) { - return; - } - - if (buf_list->bufs) { - for (int i = 0; i < buf_list->nbufs; i++) { - buffer_close(buf_list->bufs[i]); - } - free(buf_list->bufs); - buf_list->bufs = NULL; - buf_list->nbufs = 0; - } - - free(buf_list->name); - free(buf_list); -} - -int buffer_list_set_format(buffer_list_t *buf_list, unsigned width, unsigned height, unsigned format, unsigned bytesperline) -{ struct v4l2_format fmt = { 0 }; - fmt.type = buf_list->v4l2.type; unsigned orig_width = width; unsigned orig_height = height; -retry: - // JPEG is in 16x16 blocks (shrink image to fit) (but adapt to 32x32) // And ISP output if (strstr(buf_list->name, "JPEG") || strstr(buf_list->name, "H264") || buf_list->do_capture && strstr(buf_list->name, "ISP")) { @@ -177,7 +134,7 @@ error: return -1; } -int buffer_list_set_buffers(buffer_list_t *buf_list, int nbufs) +int v4l2_buffer_list_set_buffers(buffer_list_t *buf_list, int nbufs) { struct v4l2_requestbuffers v4l2_req = {0}; v4l2_req.count = nbufs; @@ -192,48 +149,18 @@ int buffer_list_set_buffers(buffer_list_t *buf_list, int nbufs) } E_LOG_DEBUG(buf_list, "Got %u buffers", v4l2_req.count); - - buf_list->bufs = calloc(v4l2_req.count, sizeof(buffer_t*)); - buf_list->nbufs = v4l2_req.count; - - for (unsigned i = 0; i < buf_list->nbufs; i++) { - char name[64]; - sprintf(name, "%s:buf%d", buf_list->name, i); - buffer_t *buf = buffer_open(name, buf_list, i); - if (!buf) { - E_LOG_ERROR(buf_list, "Cannot open buffer: %u", i); - goto error; - } - buf_list->bufs[i] = buf; - } - - E_LOG_DEBUG(buf_list, "Opened %u buffers", buf_list->nbufs); - return 0; + return v4l2_req.count; error: return -1; } -int buffer_list_set_stream(buffer_list_t *buf_list, bool do_on) +int v4l2_buffer_list_set_stream(buffer_list_t *buf_list, bool do_on) { - if (!buf_list) { - return -1; - } - - if (buf_list->streaming == do_on) { - return 0; - } - enum v4l2_buf_type type = buf_list->v4l2.type; - E_XIOCTL(buf_list, buf_list->device->fd, do_on ? VIDIOC_STREAMON : VIDIOC_STREAMOFF, &type, "Cannot set streaming state"); - buf_list->streaming = do_on; - int enqueued = buffer_list_count_enqueued(buf_list); - - E_LOG_DEBUG(buf_list, "Streaming %s... Was %d of %d enqueud", do_on ? "started" : "stopped", enqueued, buf_list->nbufs); return 0; - error: return -1; } diff --git a/device/v4l2/debug.c b/device/v4l2/debug.c index c59be35..237d6a1 100644 --- a/device/v4l2/debug.c +++ b/device/v4l2/debug.c @@ -1,5 +1,5 @@ #include "device/v4l2/v4l2.h" -#include "device/hw/buffer_list.h" +#include "device/buffer_list.h" #include "device/hw/device.h" int v4l2_buffer_list_refresh_states(buffer_list_t *buf_list) diff --git a/device/v4l2/device.c b/device/v4l2/device.c index d2c7ab0..3b32a9a 100644 --- a/device/v4l2/device.c +++ b/device/v4l2/device.c @@ -8,6 +8,9 @@ device_hw_t v4l2_device_hw = { .buffer_enqueue = v4l2_buffer_enqueue, .buffer_list_dequeue = v4l2_buffer_list_dequeue, .buffer_list_pollfd = v4l2_buffer_list_pollfd, + .buffer_list_set_format = v4l2_buffer_list_set_format, + .buffer_list_set_buffers = v4l2_buffer_list_set_buffers, + .buffer_list_set_stream = v4l2_buffer_list_set_stream }; device_t *device_v4l2_open(const char *name, const char *path) diff --git a/device/v4l2/v4l2.h b/device/v4l2/v4l2.h index dbfca2c..80ecbdd 100644 --- a/device/v4l2/v4l2.h +++ b/device/v4l2/v4l2.h @@ -13,3 +13,7 @@ int v4l2_buffer_enqueue(buffer_t *buf, const char *who); int v4l2_buffer_list_dequeue(buffer_list_t *buf_list, buffer_t **bufp); int v4l2_buffer_list_refresh_states(buffer_list_t *buf_list); int v4l2_buffer_list_pollfd(buffer_list_t *buf_list, struct pollfd *pollfd, bool can_dequeue); + +int v4l2_buffer_list_set_format(buffer_list_t *buf_list, unsigned width, unsigned height, unsigned format, unsigned bytesperline); +int v4l2_buffer_list_set_buffers(buffer_list_t *buf_list, int nbufs); +int v4l2_buffer_list_set_stream(buffer_list_t *buf_list, bool do_on); diff --git a/http/http_ffmpeg.c b/http/http_ffmpeg.c index bdb6776..ce8d04c 100644 --- a/http/http_ffmpeg.c +++ b/http/http_ffmpeg.c @@ -5,7 +5,7 @@ #include "http/http.h" #include "device/buffer.h" #include "device/buffer_lock.h" -#include "device/hw/buffer_list.h" +#include "device/buffer_list.h" #include "device/hw/device.h" #include "ffmpeg/remuxer.h" diff --git a/http/http_h264.c b/http/http_h264.c index da2f06a..616520f 100644 --- a/http/http_h264.c +++ b/http/http_h264.c @@ -5,7 +5,7 @@ #include "http/http.h" #include "device/buffer.h" #include "device/buffer_lock.h" -#include "device/hw/buffer_list.h" +#include "device/buffer_list.h" #include "device/hw/device.h" DEFINE_BUFFER_LOCK(http_h264, 0);