diff --git a/device/v4l2/buffer.c b/device/v4l2/buffer.c index 759311c..f331c34 100644 --- a/device/v4l2/buffer.c +++ b/device/v4l2/buffer.c @@ -29,7 +29,7 @@ int v4l2_buffer_open(buffer_t *buf) v4l2_buf.memory = V4L2_MEMORY_DMABUF; } - ERR_IOCTL(buf_list, dev->v4l2->dev_fd, VIDIOC_QUERYBUF, &v4l2_buf, "Cannot query buffer %d", index); + ERR_IOCTL(buf_list, buf_list->v4l2->dev_fd, VIDIOC_QUERYBUF, &v4l2_buf, "Cannot query buffer %d", index); uint64_t mem_offset = 0; @@ -42,7 +42,7 @@ int v4l2_buffer_open(buffer_t *buf) } if (buf_list->do_mmap) { - buf->start = mmap(NULL, buf->length, PROT_READ | PROT_WRITE, MAP_SHARED, dev->v4l2->dev_fd, mem_offset); + buf->start = mmap(NULL, buf->length, PROT_READ | PROT_WRITE, MAP_SHARED, buf_list->v4l2->dev_fd, mem_offset); if (buf->start == MAP_FAILED) { goto error; } @@ -51,7 +51,7 @@ int v4l2_buffer_open(buffer_t *buf) v4l2_exp.type = v4l2_buf.type; v4l2_exp.index = buf->index; v4l2_exp.plane = 0; - ERR_IOCTL(buf_list, dev->v4l2->dev_fd, VIDIOC_EXPBUF, &v4l2_exp, "Can't export queue buffer=%u to DMA", index); + ERR_IOCTL(buf_list, buf_list->v4l2->dev_fd, VIDIOC_EXPBUF, &v4l2_exp, "Can't export queue buffer=%u to DMA", index); buf->dma_fd = v4l2_exp.fd; } @@ -120,7 +120,7 @@ int v4l2_buffer_enqueue(buffer_t *buf, const char *who) v4l2_buf.timestamp.tv_sec = buf->captured_time_us / (1000LL * 1000LL); v4l2_buf.timestamp.tv_usec = buf->captured_time_us % (1000LL * 1000LL); - ERR_IOCTL(buf, buf->buf_list->dev->v4l2->dev_fd, VIDIOC_QBUF, &v4l2_buf, "Can't queue buffer."); + ERR_IOCTL(buf, buf->buf_list->v4l2->dev_fd, VIDIOC_QBUF, &v4l2_buf, "Can't queue buffer."); return 0; @@ -141,7 +141,7 @@ int v4l2_buffer_list_dequeue(buffer_list_t *buf_list, buffer_t **bufp) v4l2_buf.m.planes = &v4l2_plane; } - ERR_IOCTL(buf_list, buf_list->dev->v4l2->dev_fd, VIDIOC_DQBUF, &v4l2_buf, "Can't grab capture buffer (flags=%08x)", v4l2_buf.flags); + ERR_IOCTL(buf_list, buf_list->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) { @@ -164,7 +164,7 @@ int v4l2_buffer_list_pollfd(buffer_list_t *buf_list, struct pollfd *pollfd, bool int count_enqueued = buffer_list_count_enqueued(buf_list); // Can something be dequeued? - pollfd->fd = buf_list->dev->v4l2->dev_fd; + pollfd->fd = buf_list->v4l2->dev_fd; pollfd->events = POLLHUP; if (count_enqueued > 0 && can_dequeue) { if (buf_list->do_capture) diff --git a/device/v4l2/buffer_list.c b/device/v4l2/buffer_list.c index ad265b2..cb07d4b 100644 --- a/device/v4l2/buffer_list.c +++ b/device/v4l2/buffer_list.c @@ -10,9 +10,13 @@ int v4l2_buffer_list_open(buffer_list_t *buf_list, unsigned width, unsigned heig device_t *dev = buf_list->dev; buf_list->v4l2 = calloc(1, sizeof(buffer_list_v4l2_t)); + buf_list->v4l2->dev_fd = dev->v4l2->dev_fd; + if (buf_list->v4l2->dev_fd < 0) { + return -1; + } struct v4l2_capability v4l2_cap; - ERR_IOCTL(dev, dev->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"); if (buf_list->do_capture) { if (v4l2_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) { @@ -60,7 +64,7 @@ int v4l2_buffer_list_open(buffer_list_t *buf_list, unsigned width, unsigned heig } LOG_DEBUG(buf_list, "Get current format ..."); - ERR_IOCTL(buf_list, buf_list->dev->v4l2->dev_fd, VIDIOC_G_FMT, &fmt, "Can't set format"); + ERR_IOCTL(buf_list, buf_list->v4l2->dev_fd, VIDIOC_G_FMT, &fmt, "Can't set format"); if (buf_list->v4l2->do_mplanes) { fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_JPEG; @@ -88,7 +92,7 @@ int v4l2_buffer_list_open(buffer_list_t *buf_list, unsigned width, unsigned heig } LOG_DEBUG(buf_list, "Configuring format (%s)...", fourcc_to_string(format).buf); - ERR_IOCTL(buf_list, buf_list->dev->v4l2->dev_fd, VIDIOC_S_FMT, &fmt, "Can't set format"); + ERR_IOCTL(buf_list, buf_list->v4l2->dev_fd, VIDIOC_S_FMT, &fmt, "Can't set format"); if (buf_list->v4l2->do_mplanes) { buf_list->fmt_width = fmt.fmt.pix_mp.width; @@ -135,7 +139,7 @@ int v4l2_buffer_list_open(buffer_list_t *buf_list, unsigned width, unsigned heig LOG_DEBUG(buf_list, "Requesting %u buffers", v4l2_req.count); - ERR_IOCTL(buf_list, buf_list->dev->v4l2->dev_fd, VIDIOC_REQBUFS, &v4l2_req, "Can't request buffers"); + ERR_IOCTL(buf_list, buf_list->v4l2->dev_fd, VIDIOC_REQBUFS, &v4l2_req, "Can't request buffers"); if (v4l2_req.count < 1) { LOG_ERROR(buf_list, "Insufficient buffer memory: %u", v4l2_req.count); } @@ -150,7 +154,7 @@ error: int v4l2_buffer_list_set_stream(buffer_list_t *buf_list, bool do_on) { enum v4l2_buf_type type = buf_list->v4l2->type; - ERR_IOCTL(buf_list, buf_list->dev->v4l2->dev_fd, do_on ? VIDIOC_STREAMON : VIDIOC_STREAMOFF, &type, "Cannot set streaming state"); + ERR_IOCTL(buf_list, buf_list->v4l2->dev_fd, do_on ? VIDIOC_STREAMON : VIDIOC_STREAMOFF, &type, "Cannot set streaming state"); return 0; error: @@ -158,6 +162,12 @@ error: } void v4l2_buffer_list_close(buffer_list_t *buf_list) { + if (!buf_list->v4l2) + return; + + if (buf_list->dev->v4l2->dev_fd != buf_list->v4l2->dev_fd) { + close(buf_list->v4l2->dev_fd); + } free(buf_list->v4l2); buf_list->v4l2 = NULL; } diff --git a/device/v4l2/debug.c b/device/v4l2/debug.c index c040d02..39651b7 100644 --- a/device/v4l2/debug.c +++ b/device/v4l2/debug.c @@ -28,7 +28,7 @@ int v4l2_buffer_list_refresh_states(buffer_list_t *buf_list) for (int i = 0; i < buf_list->nbufs; i++) { v4l2_buf.index = i; - ERR_IOCTL(buf_list, buf_list->dev->v4l2->dev_fd, VIDIOC_QUERYBUF, &v4l2_buf, "Can't query buffer (flags=%08x)", i); + ERR_IOCTL(buf_list, buf_list->v4l2->dev_fd, VIDIOC_QUERYBUF, &v4l2_buf, "Can't query buffer (flags=%08x)", i); 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); } diff --git a/device/v4l2/v4l2.h b/device/v4l2/v4l2.h index 8ee4891..4bcc8e5 100644 --- a/device/v4l2/v4l2.h +++ b/device/v4l2/v4l2.h @@ -23,6 +23,7 @@ typedef struct device_v4l2_s { } device_v4l2_t; typedef struct buffer_list_v4l2_s { + int dev_fd; bool do_mplanes; int type; } buffer_list_v4l2_t;