This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 6cc53f2f37ff949d7994f19ec51bb47c0b354dde Author: niyinghao <[email protected]> AuthorDate: Thu Sep 25 20:27:26 2025 +0800 v4l2-m2m: support userptr mode Add userptr buffer mode support for v4l2-m2m. Signed-off-by: niyinghao <[email protected]> --- drivers/video/v4l2_m2m.c | 33 ++++++++++++++++++++++++++++ drivers/video/video_framebuff.c | 48 +++++++++++++++++++++++++++++++++++++++++ drivers/video/video_framebuff.h | 2 ++ 3 files changed, 83 insertions(+) diff --git a/drivers/video/v4l2_m2m.c b/drivers/video/v4l2_m2m.c index 29fc0412a46..42359a98cde 100644 --- a/drivers/video/v4l2_m2m.c +++ b/drivers/video/v4l2_m2m.c @@ -352,6 +352,7 @@ static int codec_querybuf(FAR struct file *filep, FAR codec_mng_t *cmng = inode->i_private; FAR codec_file_t *cfile = filep->f_priv; FAR codec_type_inf_t *type_inf; + FAR vbuf_container_t *container; struct v4l2_format format; uint32_t offset = 0; size_t bufsize; @@ -391,6 +392,8 @@ static int codec_querybuf(FAR struct file *filep, return -EINVAL; } + container = video_framebuff_find_container(&type_inf->bufinf, buf->index); + if (V4L2_TYPE_IS_MULTIPLANAR(buf->type)) { for (i = 0; i < format.fmt.pix_mp.num_planes; i++) @@ -405,6 +408,11 @@ static int codec_querybuf(FAR struct file *filep, offset += buf->m.planes[i].length; break; + case V4L2_MEMORY_USERPTR: + buf->m.planes[i].m.userptr = container ? + container->buf.m.planes[i].m.userptr : 0; + break; + default: return -EINVAL; } @@ -419,6 +427,10 @@ static int codec_querybuf(FAR struct file *filep, buf->m.offset = offset + bufsize * buf->index; break; + case V4L2_MEMORY_USERPTR: + buf->m.userptr = container ? container->buf.m.userptr : 0; + break; + default: return -EINVAL; } @@ -459,6 +471,9 @@ static int codec_qbuf(FAR struct file *filep, } break; + case V4L2_MEMORY_USERPTR: + break; + default: return -EINVAL; } @@ -509,6 +524,11 @@ static int codec_qbuf(FAR struct file *filep, bufsize * buf->index + plane_offset); plane_offset += format.fmt.pix_mp.plane_fmt[i].sizeimage; break; + + case V4L2_MEMORY_USERPTR: + container->buf.m.planes[i].m.vaddr = + (FAR void *)buf->m.planes[i].m.userptr; + break; } } } @@ -527,6 +547,10 @@ static int codec_qbuf(FAR struct file *filep, (FAR void *)(type_inf->bufheap + bufsize * buf->index); } break; + + case V4L2_MEMORY_USERPTR: + container->buf.m.vaddr = (FAR void *)buf->m.userptr; + break; } } @@ -610,6 +634,11 @@ static int codec_dqbuf(FAR struct file *filep, type_inf->bufheap + offset); break; + case V4L2_MEMORY_USERPTR: + buf->m.planes[i].m.userptr = (unsigned long) + buf->m.planes[i].m.vaddr; + break; + default: return -EINVAL; } @@ -624,6 +653,10 @@ static int codec_dqbuf(FAR struct file *filep, type_inf->bufheap + offset); break; + case V4L2_MEMORY_USERPTR: + buf->m.userptr = (unsigned long)buf->m.vaddr; + break; + default: return -EINVAL; } diff --git a/drivers/video/video_framebuff.c b/drivers/video/video_framebuff.c index f74f550e6be..152f8a736a6 100644 --- a/drivers/video/video_framebuff.c +++ b/drivers/video/video_framebuff.c @@ -289,3 +289,51 @@ vbuf_container_t *video_framebuff_pop_curr_container(video_framebuff_t *fbuf) spin_unlock_irqrestore(&fbuf->lock_queue, flags); return ret; } + +vbuf_container_t *video_framebuff_find_container(video_framebuff_t *fbuf, + uint32_t index) +{ + vbuf_container_t *ret = NULL; + vbuf_container_t *curr; + vbuf_container_t *start; + irqstate_t flags; + + flags = spin_lock_irqsave(&fbuf->lock_queue); + if (fbuf->vbuf_top != NULL) + { + curr = start = fbuf->vbuf_top; + do + { + if (curr->buf.index == index) + { + ret = curr; + break; + } + + curr = curr->next; + } + while (curr != NULL && curr != start); + } + + spin_unlock_irqrestore(&fbuf->lock_queue, flags); + + if (ret == NULL) + { + nxmutex_lock(&fbuf->lock_empty); + curr = fbuf->vbuf_empty; + while (curr != NULL) + { + if (curr->buf.index == index) + { + ret = curr; + break; + } + + curr = curr->next; + } + + nxmutex_unlock(&fbuf->lock_empty); + } + + return ret; +} diff --git a/drivers/video/video_framebuff.h b/drivers/video/video_framebuff.h index 1fd252b99a9..9dc470a161b 100644 --- a/drivers/video/video_framebuff.h +++ b/drivers/video/video_framebuff.h @@ -90,5 +90,7 @@ void video_framebuff_capture_done (video_framebuff_t *fbuf); void video_framebuff_change_mode (video_framebuff_t *fbuf, enum v4l2_buf_mode mode); +vbuf_container_t *video_framebuff_find_container + (video_framebuff_t *fbuf, uint32_t index); #endif /* __DRIVERS_VIDEO_VIDEO_FRAMEBUFF_H */
