You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/02/13 15:17:54 UTC
[nuttx] 02/02: drivers/video/video: add poll support to capture
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit a1e04617f81a8b5c8b3103b509117bb672a3603b
Author: jihandong <ji...@xiaomi.com>
AuthorDate: Tue Jan 31 17:23:28 2023 +0800
drivers/video/video: add poll support to capture
support part of Linux std:
https://www.kernel.org/doc/html/v4.9/media/uapi/v4l/func-poll.html
Capture devices set the POLLIN and POLLRDNORM flags in the revents field
Signed-off-by: jihandong <ji...@xiaomi.com>
---
drivers/video/video.c | 54 +++++++++++++++++++++++++++++++++++++++++
drivers/video/video_framebuff.c | 5 ++++
drivers/video/video_framebuff.h | 2 ++
3 files changed, 61 insertions(+)
diff --git a/drivers/video/video.c b/drivers/video/video.c
index ad7d20cc6f..4c8ee4c6a3 100644
--- a/drivers/video/video.c
+++ b/drivers/video/video.c
@@ -119,6 +119,7 @@ struct video_type_inf_s
struct v4l2_fract frame_interval;
video_framebuff_t bufinf;
FAR uint8_t *bufheap; /* for V4L2_MEMORY_MMAP buffers */
+ FAR struct pollfd *fds;
uint32_t seqnum;
};
@@ -200,6 +201,8 @@ static ssize_t video_write(FAR struct file *filep,
static int video_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
static int video_mmap(FAR struct file *filep,
FAR struct mm_map_entry_s *map);
+static int video_poll(FAR struct file *filep, FAR struct pollfd *fds,
+ bool setup);
/* Common function */
@@ -290,6 +293,8 @@ static const struct file_operations g_video_fops =
NULL, /* seek */
video_ioctl, /* ioctl */
video_mmap, /* mmap */
+ NULL, /* truncate */
+ video_poll, /* poll */
};
static bool g_video_initialized = false;
@@ -3154,6 +3159,53 @@ static int video_mmap(FAR struct file *filep, FAR struct mm_map_entry_s *map)
return ret;
}
+static int video_poll(FAR struct file *filep, struct pollfd *fds, bool setup)
+{
+ FAR struct inode *inode = filep->f_inode;
+ FAR video_mng_t *priv = (FAR video_mng_t *)inode->i_private;
+ FAR video_type_inf_t *type_inf;
+ enum v4l2_buf_type buf_type;
+ irqstate_t flags;
+
+ buf_type = priv->still_inf.state == VIDEO_STATE_CAPTURE ?
+ V4L2_BUF_TYPE_STILL_CAPTURE : V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ type_inf = get_video_type_inf(priv, buf_type);
+ if (type_inf == NULL)
+ {
+ return -EINVAL;
+ }
+
+ flags = enter_critical_section();
+
+ if (setup)
+ {
+ if (type_inf->fds == NULL)
+ {
+ type_inf->fds = fds;
+ fds->priv = &type_inf->fds;
+ if (!video_framebuff_is_empty(&type_inf->bufinf))
+ {
+ poll_notify(&type_inf->fds, 1, POLLIN);
+ }
+ }
+ else
+ {
+ leave_critical_section(flags);
+ return -EBUSY;
+ }
+ }
+ else if (fds->priv)
+ {
+ type_inf->fds = NULL;
+ fds->priv = NULL;
+ }
+
+ leave_critical_section(flags);
+
+ return OK;
+}
+
static FAR void *video_register(FAR const char *devpath)
{
FAR video_mng_t *priv;
@@ -3259,6 +3311,8 @@ static int video_complete_capture(uint8_t err_code, uint32_t datasize,
return -EINVAL;
}
+ poll_notify(&type_inf->fds, 1, POLLIN);
+
if (err_code == 0)
{
type_inf->bufinf.vbuf_curr->buf.flags = 0;
diff --git a/drivers/video/video_framebuff.c b/drivers/video/video_framebuff.c
index bb4a2ecf9f..fc66745e9f 100644
--- a/drivers/video/video_framebuff.c
+++ b/drivers/video/video_framebuff.c
@@ -120,6 +120,11 @@ int video_framebuff_realloc_container(video_framebuff_t *fbuf, int sz)
return OK;
}
+int video_framebuff_is_empty(video_framebuff_t *fbuf)
+{
+ return fbuf->vbuf_top == NULL || fbuf->vbuf_top == fbuf->vbuf_next;
+}
+
vbuf_container_t *video_framebuff_get_container(video_framebuff_t *fbuf)
{
vbuf_container_t *ret;
diff --git a/drivers/video/video_framebuff.h b/drivers/video/video_framebuff.h
index cf2bbbb4bb..a4183a5f9c 100644
--- a/drivers/video/video_framebuff.h
+++ b/drivers/video/video_framebuff.h
@@ -71,6 +71,8 @@ vbuf_container_t *video_framebuff_get_container
(video_framebuff_t *fbuf);
void video_framebuff_free_container
(video_framebuff_t *fbuf, vbuf_container_t *cnt);
+int video_framebuff_is_empty
+ (video_framebuff_t *fbuf);
void video_framebuff_queue_container
(video_framebuff_t *fbuf, vbuf_container_t *tgt);
vbuf_container_t *video_framebuff_dq_valid_container