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 <jihandong@xiaomi.com>
This commit is contained in:
parent
ae7bc4e300
commit
a1e04617f8
@ -119,6 +119,7 @@ struct video_type_inf_s
|
|||||||
struct v4l2_fract frame_interval;
|
struct v4l2_fract frame_interval;
|
||||||
video_framebuff_t bufinf;
|
video_framebuff_t bufinf;
|
||||||
FAR uint8_t *bufheap; /* for V4L2_MEMORY_MMAP buffers */
|
FAR uint8_t *bufheap; /* for V4L2_MEMORY_MMAP buffers */
|
||||||
|
FAR struct pollfd *fds;
|
||||||
uint32_t seqnum;
|
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_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
|
||||||
static int video_mmap(FAR struct file *filep,
|
static int video_mmap(FAR struct file *filep,
|
||||||
FAR struct mm_map_entry_s *map);
|
FAR struct mm_map_entry_s *map);
|
||||||
|
static int video_poll(FAR struct file *filep, FAR struct pollfd *fds,
|
||||||
|
bool setup);
|
||||||
|
|
||||||
/* Common function */
|
/* Common function */
|
||||||
|
|
||||||
@ -290,6 +293,8 @@ static const struct file_operations g_video_fops =
|
|||||||
NULL, /* seek */
|
NULL, /* seek */
|
||||||
video_ioctl, /* ioctl */
|
video_ioctl, /* ioctl */
|
||||||
video_mmap, /* mmap */
|
video_mmap, /* mmap */
|
||||||
|
NULL, /* truncate */
|
||||||
|
video_poll, /* poll */
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool g_video_initialized = false;
|
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;
|
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)
|
static FAR void *video_register(FAR const char *devpath)
|
||||||
{
|
{
|
||||||
FAR video_mng_t *priv;
|
FAR video_mng_t *priv;
|
||||||
@ -3259,6 +3311,8 @@ static int video_complete_capture(uint8_t err_code, uint32_t datasize,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
poll_notify(&type_inf->fds, 1, POLLIN);
|
||||||
|
|
||||||
if (err_code == 0)
|
if (err_code == 0)
|
||||||
{
|
{
|
||||||
type_inf->bufinf.vbuf_curr->buf.flags = 0;
|
type_inf->bufinf.vbuf_curr->buf.flags = 0;
|
||||||
|
@ -120,6 +120,11 @@ int video_framebuff_realloc_container(video_framebuff_t *fbuf, int sz)
|
|||||||
return OK;
|
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 *video_framebuff_get_container(video_framebuff_t *fbuf)
|
||||||
{
|
{
|
||||||
vbuf_container_t *ret;
|
vbuf_container_t *ret;
|
||||||
|
@ -71,6 +71,8 @@ vbuf_container_t *video_framebuff_get_container
|
|||||||
(video_framebuff_t *fbuf);
|
(video_framebuff_t *fbuf);
|
||||||
void video_framebuff_free_container
|
void video_framebuff_free_container
|
||||||
(video_framebuff_t *fbuf, vbuf_container_t *cnt);
|
(video_framebuff_t *fbuf, vbuf_container_t *cnt);
|
||||||
|
int video_framebuff_is_empty
|
||||||
|
(video_framebuff_t *fbuf);
|
||||||
void video_framebuff_queue_container
|
void video_framebuff_queue_container
|
||||||
(video_framebuff_t *fbuf, vbuf_container_t *tgt);
|
(video_framebuff_t *fbuf, vbuf_container_t *tgt);
|
||||||
vbuf_container_t *video_framebuff_dq_valid_container
|
vbuf_container_t *video_framebuff_dq_valid_container
|
||||||
|
Loading…
Reference in New Issue
Block a user