From 4a345ed048a044a09ac7e4ef01795952f7d666a2 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Sun, 10 Apr 2022 16:03:55 +0200 Subject: [PATCH] Create private data for `buffer_list_v4l2_t` --- device/buffer_list.c | 13 +++++++------ device/buffer_list.h | 10 ++++------ device/device.c | 6 +----- device/device.h | 3 ++- device/v4l2/buffer.c | 16 ++++++++-------- device/v4l2/buffer_list.c | 31 +++++++++++++++++++------------ device/v4l2/debug.c | 6 +++--- device/v4l2/v4l2.c | 3 ++- device/v4l2/v4l2.h | 8 +++++++- 9 files changed, 53 insertions(+), 43 deletions(-) diff --git a/device/buffer_list.c b/device/buffer_list.c index 99d3439..80907c1 100644 --- a/device/buffer_list.c +++ b/device/buffer_list.c @@ -3,7 +3,7 @@ #include "device/device.h" #include "opts/log.h" -buffer_list_t *buffer_list_open(const char *name, struct device_s *dev, bool do_capture, bool do_mmap) +buffer_list_t *buffer_list_open(const char *name, struct device_s *dev, unsigned width, unsigned height, unsigned format, unsigned bytesperline, bool do_capture, bool do_mmap) { buffer_list_t *buf_list = calloc(1, sizeof(buffer_list_t)); @@ -11,6 +11,11 @@ buffer_list_t *buffer_list_open(const char *name, struct device_s *dev, bool do_ buf_list->name = strdup(name); buf_list->do_capture = do_capture; buf_list->do_mmap = do_mmap; + + if (dev->hw->buffer_list_open(buf_list, width, height, format, bytesperline) < 0) { + goto error; + } + return buf_list; error: @@ -33,15 +38,11 @@ void buffer_list_close(buffer_list_t *buf_list) buf_list->nbufs = 0; } + buf_list->device->hw->buffer_list_close(buf_list); 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); diff --git a/device/buffer_list.h b/device/buffer_list.h index bbddd94..3c91609 100644 --- a/device/buffer_list.h +++ b/device/buffer_list.h @@ -15,10 +15,9 @@ typedef struct buffer_list_s { bool do_mmap, do_capture; - struct { - bool do_mplanes; - int type; - } v4l2; + union { + struct buffer_list_v4l2_s *v4l2; + }; unsigned fmt_width, fmt_height, fmt_format, fmt_bytesperline, fmt_interval_us; bool do_timestamps; @@ -29,11 +28,10 @@ typedef struct buffer_list_s { int frames; } buffer_list_t; -buffer_list_t *buffer_list_open(const char *name, struct device_s *dev, bool do_capture, bool do_mmap); +buffer_list_t *buffer_list_open(const char *name, struct device_s *dev, unsigned width, unsigned height, unsigned format, unsigned bytesperline, bool do_capture, bool do_mmap); 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 *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/device.c b/device/device.c index 85aeb44..cc3320d 100644 --- a/device/device.c +++ b/device/device.c @@ -75,15 +75,11 @@ int device_open_buffer_list(device_t *dev, bool do_capture, unsigned width, unsi sprintf(name, "%s:output", dev->name); } - *buf_list = buffer_list_open(name, dev, do_capture, do_mmap); + *buf_list = buffer_list_open(name, dev, width, height, format, bytesperline, do_capture, do_mmap); if (!*buf_list) { goto error; } - if (buffer_list_set_format(*buf_list, width, height, format, bytesperline) < 0) { - goto error; - } - if (buffer_list_set_buffers(*buf_list, nbufs) < 0) { goto error; } diff --git a/device/device.h b/device/device.h index d7de8bc..77df215 100644 --- a/device/device.h +++ b/device/device.h @@ -22,7 +22,8 @@ typedef struct device_hw_s { 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_open)(buffer_list_t *buf_list, unsigned width, unsigned height, unsigned format, unsigned bytesperline); + void (*buffer_list_close)(buffer_list_t *buf_list); 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; diff --git a/device/v4l2/buffer.c b/device/v4l2/buffer.c index f27c43b..8a6f7db 100644 --- a/device/v4l2/buffer.c +++ b/device/v4l2/buffer.c @@ -12,10 +12,10 @@ int v4l2_buffer_open(buffer_t *buf) buffer_list_t *buf_list = buf->buf_list; device_t *dev = buf_list->device; - v4l2_buf.type = buf_list->v4l2.type; + v4l2_buf.type = buf_list->v4l2->type; v4l2_buf.index = buf->index; - if (buf_list->v4l2.do_mplanes) { + if (buf_list->v4l2->do_mplanes) { v4l2_buf.length = 1; v4l2_buf.m.planes = &v4l2_plane; v4l2_plane.data_offset = 0; @@ -31,7 +31,7 @@ int v4l2_buffer_open(buffer_t *buf) uint64_t mem_offset = 0; - if (buf_list->v4l2.do_mplanes) { + if (buf_list->v4l2->do_mplanes) { mem_offset = v4l2_plane.m.mem_offset; buf->length = v4l2_plane.length; } else { @@ -77,7 +77,7 @@ int v4l2_buffer_enqueue(buffer_t *buf, const char *who) struct v4l2_buffer v4l2_buf = {0}; struct v4l2_plane v4l2_plane = {0}; - v4l2_buf.type = buf->buf_list->v4l2.type; + v4l2_buf.type = buf->buf_list->v4l2->type; v4l2_buf.index = buf->index; v4l2_buf.flags = 0; if (buf->flags.is_keyframe) @@ -92,7 +92,7 @@ int v4l2_buffer_enqueue(buffer_t *buf, const char *who) } // update used bytes - if (buf->buf_list->v4l2.do_mplanes) { + if (buf->buf_list->v4l2->do_mplanes) { v4l2_buf.length = 1; v4l2_buf.m.planes = &v4l2_plane; v4l2_plane.bytesused = buf->used; @@ -139,10 +139,10 @@ int v4l2_buffer_list_dequeue(buffer_list_t *buf_list, buffer_t **bufp) struct v4l2_buffer v4l2_buf = {0}; struct v4l2_plane v4l2_plane = {0}; - v4l2_buf.type = buf_list->v4l2.type; + v4l2_buf.type = buf_list->v4l2->type; v4l2_buf.memory = V4L2_MEMORY_MMAP; - if (buf_list->v4l2.do_mplanes) { + if (buf_list->v4l2->do_mplanes) { v4l2_buf.length = 1; v4l2_buf.m.planes = &v4l2_plane; } @@ -150,7 +150,7 @@ int v4l2_buffer_list_dequeue(buffer_list_t *buf_list, buffer_t **bufp) E_XIOCTL(buf_list, buf_list->device->v4l2->dev_fd, VIDIOC_DQBUF, &v4l2_buf, "Can't grab capture buffer (flags=%08x)", v4l2_buf.flags); buffer_t *buf = *bufp = buf_list->bufs[v4l2_buf.index]; - if (buf_list->v4l2.do_mplanes) { + if (buf_list->v4l2->do_mplanes) { buf->used = v4l2_plane.bytesused; } else { buf->used = v4l2_buf.bytesused; diff --git a/device/v4l2/buffer_list.c b/device/v4l2/buffer_list.c index ad336b6..3375fbc 100644 --- a/device/v4l2/buffer_list.c +++ b/device/v4l2/buffer_list.c @@ -5,28 +5,30 @@ #include "opts/log.h" #include "opts/fourcc.h" -int v4l2_buffer_list_set_format(buffer_list_t *buf_list, unsigned width, unsigned height, unsigned format, unsigned bytesperline) +int v4l2_buffer_list_open(buffer_list_t *buf_list, unsigned width, unsigned height, unsigned format, unsigned bytesperline) { device_t *dev = buf_list->device; + buf_list->v4l2 = calloc(1, sizeof(buffer_list_v4l2_t)); + struct v4l2_capability v4l2_cap; E_XIOCTL(dev, dev->v4l2->dev_fd, VIDIOC_QUERYCAP, &v4l2_cap, "Can't query device capabilities"); if (buf_list->do_capture) { if (v4l2_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) { - buf_list->v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf_list->v4l2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; } 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->v4l2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + buf_list->v4l2->do_mplanes = true; } 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->v4l2->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; } 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->v4l2->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + buf_list->v4l2->do_mplanes = true; } else { E_LOG_ERROR(dev, "Video output is not supported by device: %08x", v4l2_cap.capabilities); } @@ -40,7 +42,7 @@ int v4l2_buffer_list_set_format(buffer_list_t *buf_list, unsigned width, unsigne } struct v4l2_format fmt = { 0 }; - fmt.type = buf_list->v4l2.type; + fmt.type = buf_list->v4l2->type; unsigned orig_width = width; unsigned orig_height = height; @@ -60,7 +62,7 @@ int v4l2_buffer_list_set_format(buffer_list_t *buf_list, unsigned width, unsigne E_LOG_DEBUG(buf_list, "Get current format ..."); E_XIOCTL(buf_list, buf_list->device->v4l2->dev_fd, VIDIOC_G_FMT, &fmt, "Can't set format"); - if (buf_list->v4l2.do_mplanes) { + if (buf_list->v4l2->do_mplanes) { fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_JPEG; if (width) fmt.fmt.pix_mp.width = width; @@ -88,7 +90,7 @@ int v4l2_buffer_list_set_format(buffer_list_t *buf_list, unsigned width, unsigne E_LOG_DEBUG(buf_list, "Configuring format (%s)...", fourcc_to_string(format).buf); E_XIOCTL(buf_list, buf_list->device->v4l2->dev_fd, VIDIOC_S_FMT, &fmt, "Can't set format"); - if (buf_list->v4l2.do_mplanes) { + if (buf_list->v4l2->do_mplanes) { buf_list->fmt_width = fmt.fmt.pix_mp.width; buf_list->fmt_height = fmt.fmt.pix_mp.height; buf_list->fmt_format = fmt.fmt.pix_mp.pixelformat; @@ -140,7 +142,7 @@ int v4l2_buffer_list_set_buffers(buffer_list_t *buf_list, int nbufs) { struct v4l2_requestbuffers v4l2_req = {0}; v4l2_req.count = nbufs; - v4l2_req.type = buf_list->v4l2.type; + v4l2_req.type = buf_list->v4l2->type; v4l2_req.memory = buf_list->do_mmap ? V4L2_MEMORY_MMAP : V4L2_MEMORY_DMABUF; E_LOG_DEBUG(buf_list, "Requesting %u buffers", v4l2_req.count); @@ -159,10 +161,15 @@ error: int v4l2_buffer_list_set_stream(buffer_list_t *buf_list, bool do_on) { - enum v4l2_buf_type type = buf_list->v4l2.type; + enum v4l2_buf_type type = buf_list->v4l2->type; E_XIOCTL(buf_list, buf_list->device->v4l2->dev_fd, do_on ? VIDIOC_STREAMON : VIDIOC_STREAMOFF, &type, "Cannot set streaming state"); return 0; error: return -1; } + +void v4l2_buffer_list_close(buffer_list_t *buf_list) { + free(buf_list->v4l2); + buf_list->v4l2 = NULL; +} diff --git a/device/v4l2/debug.c b/device/v4l2/debug.c index 1d3b208..9b3de9b 100644 --- a/device/v4l2/debug.c +++ b/device/v4l2/debug.c @@ -12,9 +12,9 @@ int v4l2_buffer_list_refresh_states(buffer_list_t *buf_list) struct v4l2_buffer v4l2_buf = {0}; struct v4l2_plane v4l2_plane = {0}; - v4l2_buf.type = buf_list->v4l2.type; + v4l2_buf.type = buf_list->v4l2->type; - if (buf_list->v4l2.do_mplanes) { + if (buf_list->v4l2->do_mplanes) { v4l2_buf.length = 1; v4l2_buf.m.planes = &v4l2_plane; } @@ -30,7 +30,7 @@ int v4l2_buffer_list_refresh_states(buffer_list_t *buf_list) E_XIOCTL(buf_list, buf_list->device->v4l2->dev_fd, VIDIOC_QUERYBUF, &v4l2_buf, "Can't query buffer (flags=%08x)", i); E_LOG_INFO(buf_list, "Buffer: %d, Flags: %08x. Offset: %d", i, v4l2_buf.flags, - buf_list->v4l2.do_mplanes ? v4l2_plane.m.mem_offset : v4l2_buf.m.offset); + buf_list->v4l2->do_mplanes ? v4l2_plane.m.mem_offset : v4l2_buf.m.offset); } error: diff --git a/device/v4l2/v4l2.c b/device/v4l2/v4l2.c index a164b48..2e6e9f9 100644 --- a/device/v4l2/v4l2.c +++ b/device/v4l2/v4l2.c @@ -15,7 +15,8 @@ device_hw_t v4l2_device_hw = { .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_open = v4l2_buffer_list_open, + .buffer_list_close = v4l2_buffer_list_close, .buffer_list_set_buffers = v4l2_buffer_list_set_buffers, .buffer_list_set_stream = v4l2_buffer_list_set_stream }; diff --git a/device/v4l2/v4l2.h b/device/v4l2/v4l2.h index b0669a5..7d45253 100644 --- a/device/v4l2/v4l2.h +++ b/device/v4l2/v4l2.h @@ -15,6 +15,11 @@ typedef struct device_v4l2_s { int subdev_fd; } device_v4l2_t; +typedef struct buffer_list_v4l2_s { + bool do_mplanes; + int type; +} buffer_list_v4l2_t; + int v4l2_device_open(device_t *dev); void v4l2_device_close(device_t *dev); int v4l2_device_set_decoder_start(device_t *dev, bool do_on); @@ -29,7 +34,8 @@ 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_open(buffer_list_t *buf_list, unsigned width, unsigned height, unsigned format, unsigned bytesperline); +void v4l2_buffer_list_close(buffer_list_t *buf_list); 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);