diff --git a/arch/sim/src/sim/sim_decoder.c b/arch/sim/src/sim/sim_decoder.c index c922036e78136..fec73d63b748f 100644 --- a/arch/sim/src/sim/sim_decoder.c +++ b/arch/sim/src/sim/sim_decoder.c @@ -404,7 +404,7 @@ static int sim_decoder_process(sim_decoder_t *sim_decoder, if (src_buf != NULL) { - src_data = (uint8_t *)src_buf->m.userptr; + src_data = (uint8_t *)src_buf->m.vaddr; src_size = src_buf->bytesused; src_pts = src_buf->timestamp.tv_sec * 1000000 + src_buf->timestamp.tv_usec; @@ -423,7 +423,7 @@ static int sim_decoder_process(sim_decoder_t *sim_decoder, } ret = openh264_decoder_dequeue(sim_decoder->decoder, - (uint8_t *)dst_buf->m.userptr, + (uint8_t *)dst_buf->m.vaddr, &dst_pts, &dst_buf->bytesused); if (ret == 0 && src_buf == NULL) diff --git a/arch/sim/src/sim/sim_encoder.c b/arch/sim/src/sim/sim_encoder.c index cca304ecdca66..34018da0d5c36 100644 --- a/arch/sim/src/sim/sim_encoder.c +++ b/arch/sim/src/sim/sim_encoder.c @@ -472,7 +472,7 @@ static int sim_encoder_process(sim_encoder_t *sim_encoder, if (src_buf != NULL) { - src_data = (uint8_t *)src_buf->m.userptr; + src_data = (uint8_t *)src_buf->m.vaddr; src_size = src_buf->bytesused; src_pts = src_buf->timestamp.tv_sec * 1000000 + src_buf->timestamp.tv_usec; @@ -491,7 +491,7 @@ static int sim_encoder_process(sim_encoder_t *sim_encoder, } ret = x264_wrapper_dequeue(sim_encoder->encoder, - (uint8_t *)dst_buf->m.userptr, + (uint8_t *)dst_buf->m.vaddr, &dst_buf->bytesused, &dst_pts, &dst_buf->flags); diff --git a/drivers/video/v4l2_cap.c b/drivers/video/v4l2_cap.c index 9967450cf869e..4b14c53c4fafb 100644 --- a/drivers/video/v4l2_cap.c +++ b/drivers/video/v4l2_cap.c @@ -83,6 +83,7 @@ struct video_format_s uint16_t width; uint16_t height; uint32_t pixelformat; + uint32_t sizeimage; }; typedef struct video_format_s video_format_t; @@ -659,6 +660,10 @@ static void convert_to_imgdatafmt(FAR video_format_t *video, data->pixelformat = IMGDATA_PIX_FMT_JPEG; break; + case V4L2_PIX_FMT_ENTROPY: + data->pixelformat = IMGDATA_PIX_FMT_ENTROPY; + break; + default: /* V4L2_PIX_FMT_JPEG_WITH_SUBIMG */ data->pixelformat = IMGDATA_PIX_FMT_JPEG_WITH_SUBIMG; break; @@ -698,6 +703,10 @@ static void convert_to_imgsensorfmt(FAR video_format_t *video, sensor->pixelformat = IMGSENSOR_PIX_FMT_JPEG; break; + case V4L2_PIX_FMT_ENTROPY: + sensor->pixelformat = IMGSENSOR_PIX_FMT_ENTROPY; + break; + default: /* V4L2_PIX_FMT_JPEG_WITH_SUBIMG */ sensor->pixelformat = IMGSENSOR_PIX_FMT_JPEG_WITH_SUBIMG; break; @@ -1330,6 +1339,11 @@ static size_t get_bufsize(FAR video_format_t *vf) uint32_t height = vf->height; size_t ret = width * height; + if (vf->sizeimage) + { + return vf->sizeimage; + } + switch (vf->pixelformat) { case V4L2_PIX_FMT_NV12: @@ -1338,9 +1352,11 @@ static size_t get_bufsize(FAR video_format_t *vf) case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_UYVY: case V4L2_PIX_FMT_RGB565: - case V4L2_PIX_FMT_JPEG: default: return ret * 2; + case V4L2_PIX_FMT_JPEG: + case V4L2_PIX_FMT_ENTROPY: + return ret; } } @@ -2482,6 +2498,7 @@ static int capture_g_fmt(FAR struct file *filep, fmt->fmt.pix.width = type_inf->fmt[CAPTURE_FMT_MAIN].width; fmt->fmt.pix.height = type_inf->fmt[CAPTURE_FMT_MAIN].height; fmt->fmt.pix.pixelformat = type_inf->fmt[CAPTURE_FMT_MAIN].pixelformat; + fmt->fmt.pix.sizeimage = type_inf->fmt[CAPTURE_FMT_MAIN].sizeimage; return OK; } @@ -2528,6 +2545,7 @@ static int capture_s_fmt(FAR struct file *filep, type_inf->fmt[CAPTURE_FMT_SUB].width = fmt->fmt.pix.width; type_inf->fmt[CAPTURE_FMT_SUB].height = fmt->fmt.pix.height; + type_inf->fmt[CAPTURE_FMT_SUB].sizeimage = fmt->fmt.pix.sizeimage; type_inf->fmt[CAPTURE_FMT_SUB].pixelformat = fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_SUBIMG_UYVY ? V4L2_PIX_FMT_UYVY : V4L2_PIX_FMT_RGB565; @@ -2537,6 +2555,7 @@ static int capture_s_fmt(FAR struct file *filep, default: type_inf->fmt[CAPTURE_FMT_MAIN].width = fmt->fmt.pix.width; type_inf->fmt[CAPTURE_FMT_MAIN].height = fmt->fmt.pix.height; + type_inf->fmt[CAPTURE_FMT_MAIN].sizeimage = fmt->fmt.pix.sizeimage; type_inf->fmt[CAPTURE_FMT_MAIN].pixelformat = fmt->fmt.pix.pixelformat; type_inf->nr_fmt = 1; @@ -2590,6 +2609,7 @@ static int capture_try_fmt(FAR struct file *filep, sizeof(video_format_t)); vf[CAPTURE_FMT_SUB].width = fmt->fmt.pix.width; vf[CAPTURE_FMT_SUB].height = fmt->fmt.pix.height; + vf[CAPTURE_FMT_SUB].sizeimage = fmt->fmt.pix.sizeimage; vf[CAPTURE_FMT_SUB].pixelformat = fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_SUBIMG_UYVY ? V4L2_PIX_FMT_UYVY : V4L2_PIX_FMT_RGB565; @@ -2600,11 +2620,13 @@ static int capture_try_fmt(FAR struct file *filep, case V4L2_PIX_FMT_UYVY: case V4L2_PIX_FMT_RGB565: case V4L2_PIX_FMT_JPEG: + case V4L2_PIX_FMT_ENTROPY: case V4L2_PIX_FMT_JPEG_WITH_SUBIMG: nr_fmt = 1; vf[CAPTURE_FMT_MAIN].width = fmt->fmt.pix.width; vf[CAPTURE_FMT_MAIN].height = fmt->fmt.pix.height; vf[CAPTURE_FMT_MAIN].pixelformat = fmt->fmt.pix.pixelformat; + vf[CAPTURE_FMT_MAIN].sizeimage = fmt->fmt.pix.sizeimage; break; default: diff --git a/drivers/video/v4l2_m2m.c b/drivers/video/v4l2_m2m.c index 69aa3cbdb5401..b8ab4735eed1d 100644 --- a/drivers/video/v4l2_m2m.c +++ b/drivers/video/v4l2_m2m.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "video_framebuff.h" @@ -274,6 +275,7 @@ static int codec_reqbufs(FAR struct file *filep, FAR codec_file_t *cfile = filep->f_priv; FAR codec_type_inf_t *type_inf; uint32_t buf_size; + size_t buf_cnt; int ret = OK; if (reqbufs == NULL) @@ -282,18 +284,32 @@ static int codec_reqbufs(FAR struct file *filep, } reqbufs->mode = V4L2_BUF_MODE_FIFO; - if (reqbufs->count > V4L2_REQBUFS_COUNT_MAX) - { - reqbufs->count = V4L2_REQBUFS_COUNT_MAX; - } if (V4L2_TYPE_IS_OUTPUT(reqbufs->type)) { + ret = CODEC_OUTPUT_TRY_MEMORY(cmng->codec, cfile->priv, + reqbufs->memory); + if (ret < 0) + { + return ret; + } + buf_size = CODEC_OUTPUT_G_BUFSIZE(cmng->codec, cfile->priv); + buf_cnt = CODEC_OUTPUT_G_BUFCNT(cmng->codec, cfile->priv); + reqbufs->count = MIN(buf_cnt, reqbufs->count); } else { + ret = CODEC_CAPTURE_TRY_MEMORY(cmng->codec, cfile->priv, + reqbufs->memory); + if (ret < 0) + { + return ret; + } + buf_size = CODEC_CAPTURE_G_BUFSIZE(cmng->codec, cfile->priv); + buf_cnt = CODEC_CAPTURE_G_BUFCNT(cmng->codec, cfile->priv); + reqbufs->count = MIN(buf_cnt, reqbufs->count); } if (buf_size == 0) @@ -307,8 +323,18 @@ static int codec_reqbufs(FAR struct file *filep, reqbufs->count); if (ret == 0 && reqbufs->memory == V4L2_MEMORY_MMAP) { - kumm_free(type_inf->bufheap); - type_inf->bufheap = kumm_memalign(32, reqbufs->count * buf_size); + if (cmng->codec->ops->free_buf) + { + cmng->codec->ops->free_buf(cfile->priv, type_inf->bufheap); + } + else + { + kumm_free(type_inf->bufheap); + } + + type_inf->bufheap = cmng->codec->ops->alloc_buf ? + cmng->codec->ops->alloc_buf(cfile->priv, reqbufs->count * buf_size) : + kumm_memalign(32, reqbufs->count * buf_size); if (type_inf->bufheap == NULL) { ret = -ENOMEM; @@ -325,8 +351,13 @@ 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; + uint8_t i; - if (buf == NULL || buf->memory != V4L2_MEMORY_MMAP) + if (buf == NULL) { return -EINVAL; } @@ -342,22 +373,68 @@ static int codec_querybuf(FAR struct file *filep, return -EINVAL; } + memset(&format, 0, sizeof(format)); if (V4L2_TYPE_IS_OUTPUT(buf->type)) { - buf->length = CODEC_OUTPUT_G_BUFSIZE(cmng->codec, cfile->priv); - buf->m.offset = buf->length * buf->index; + bufsize = CODEC_OUTPUT_G_BUFSIZE(cmng->codec, cfile->priv); + CODEC_OUTPUT_G_FMT(cmng->codec, cfile->priv, &format); } else { - buf->length = CODEC_CAPTURE_G_BUFSIZE(cmng->codec, cfile->priv); - buf->m.offset = buf->length * buf->index + CAPTURE_BUF_OFFSET; + offset = CAPTURE_BUF_OFFSET; + bufsize = CODEC_CAPTURE_G_BUFSIZE(cmng->codec, cfile->priv); + CODEC_CAPTURE_G_FMT(cmng->codec, cfile->priv, &format); } - if (buf->length == 0) + if (bufsize == 0) { 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++) + { + switch (buf->memory) + { + case V4L2_MEMORY_MMAP: + buf->m.planes[i].length = + format.fmt.pix_mp.plane_fmt[i].sizeimage; + buf->m.planes[i].m.mem_offset = + offset + bufsize * buf->index; + 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; + } + } + } + else + { + switch (buf->memory) + { + case V4L2_MEMORY_MMAP: + buf->length = bufsize; + 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; + } + } + return OK; } @@ -369,7 +446,9 @@ static int codec_qbuf(FAR struct file *filep, FAR codec_file_t *cfile = filep->f_priv; FAR codec_type_inf_t *type_inf; FAR vbuf_container_t *container; - size_t buf_size; + struct v4l2_format format; + uint32_t offset = 0; + uint8_t i; if (buf == NULL) { @@ -389,28 +468,60 @@ static int codec_qbuf(FAR struct file *filep, return -EAGAIN; } - memcpy(&container->buf, buf, sizeof(struct v4l2_buffer)); - if (buf->memory == V4L2_MEMORY_MMAP) + memset(&format, 0, sizeof(format)); + if (V4L2_TYPE_IS_OUTPUT(buf->type)) + { + CODEC_OUTPUT_G_FMT(cmng->codec, cfile->priv, &format); + } + else { - /* only use userptr inside the container */ + offset = CAPTURE_BUF_OFFSET; + CODEC_CAPTURE_G_FMT(cmng->codec, cfile->priv, &format); + } - if (V4L2_TYPE_IS_OUTPUT(buf->type)) + memcpy(&container->buf, buf, sizeof(struct v4l2_buffer)); + + if (V4L2_TYPE_IS_MULTIPLANAR(buf->type)) + { + memcpy(container->planes, buf->m.planes, + sizeof(struct v4l2_plane) * format.fmt.pix_mp.num_planes); + container->buf.m.planes = container->planes; + for (i = 0; i < format.fmt.pix_mp.num_planes; i++) { - buf_size = CODEC_OUTPUT_G_BUFSIZE(cmng->codec, cfile->priv); + switch (container->buf.memory) + { + case V4L2_MEMORY_MMAP: + container->buf.m.planes[i].m.vaddr = + (FAR void *)(buf->m.planes[i].m.mem_offset - + offset + type_inf->bufheap); + break; + + case V4L2_MEMORY_USERPTR: + container->buf.m.planes[i].m.vaddr = + (FAR void *)buf->m.planes[i].m.userptr; + break; + + default: + return -EINVAL; + } } - else + } + else + { + switch (buf->memory) { - buf_size = CODEC_CAPTURE_G_BUFSIZE(cmng->codec, cfile->priv); - } + case V4L2_MEMORY_MMAP: + container->buf.m.vaddr = + (FAR void *)(type_inf->bufheap + buf->m.offset - offset); + break; - if (buf_size == 0) - { - return -EINVAL; - } + case V4L2_MEMORY_USERPTR: + container->buf.m.vaddr = (FAR void *)buf->m.userptr; + break; - container->buf.length = buf_size; - container->buf.m.userptr = (unsigned long)(type_inf->bufheap + - container->buf.length * buf->index); + default: + return -EINVAL; + } } video_framebuff_queue_container(&type_inf->bufinf, container); @@ -428,9 +539,15 @@ static int codec_qbuf(FAR struct file *filep, static int codec_dqbuf(FAR struct file *filep, FAR struct v4l2_buffer *buf) { + FAR struct v4l2_plane *plans = buf->m.planes; + FAR struct inode *inode = filep->f_inode; + 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; + uint8_t i; if (buf == NULL) { @@ -454,7 +571,61 @@ static int codec_dqbuf(FAR struct file *filep, return -EAGAIN; } + memset(&format, 0, sizeof(format)); + if (V4L2_TYPE_IS_OUTPUT(buf->type)) + { + CODEC_OUTPUT_G_FMT(cmng->codec, cfile->priv, &format); + } + else + { + offset = CAPTURE_BUF_OFFSET; + CODEC_CAPTURE_G_FMT(cmng->codec, cfile->priv, &format); + } + memcpy(buf, &container->buf, sizeof(struct v4l2_buffer)); + if (V4L2_TYPE_IS_MULTIPLANAR(buf->type)) + { + buf->m.planes = plans; + memcpy(plans, container->planes, + sizeof(struct v4l2_plane) * format.fmt.pix_mp.num_planes); + for (i = 0; i < format.fmt.pix_mp.num_planes; i++) + { + switch (container->buf.memory) + { + case V4L2_MEMORY_MMAP: + buf->m.planes[i].m.mem_offset = (uint32_t) + ((uint8_t *)buf->m.planes[i].m.vaddr - + 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; + } + } + } + else + { + switch (container->buf.memory) + { + case V4L2_MEMORY_MMAP: + buf->m.offset = (uint32_t)((uint8_t *)buf->m.vaddr - + type_inf->bufheap + offset); + break; + + case V4L2_MEMORY_USERPTR: + buf->m.userptr = (unsigned long)buf->m.vaddr; + break; + + default: + return -EINVAL; + } + } + video_framebuff_free_container(&type_inf->bufinf, container); vinfo("%s dequeue done\n", V4L2_TYPE_IS_OUTPUT(buf->type) ? @@ -853,10 +1024,18 @@ static int codec_close(FAR struct file *filep) video_framebuff_uninit(&cfile->capture_inf.bufinf); video_framebuff_uninit(&cfile->output_inf.bufinf); - kumm_free(cfile->capture_inf.bufheap); - kumm_free(cfile->output_inf.bufheap); - kmm_free(cfile); + if (cmng->codec->ops->free_buf) + { + cmng->codec->ops->free_buf(cfile->priv, cfile->capture_inf.bufheap); + cmng->codec->ops->free_buf(cfile->priv, cfile->output_inf.bufheap); + } + else + { + kumm_free(cfile->capture_inf.bufheap); + kumm_free(cfile->output_inf.bufheap); + } + kmm_free(cfile); return OK; } diff --git a/drivers/video/video_framebuff.c b/drivers/video/video_framebuff.c index f74f550e6beb3..152f8a736a6e8 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 5623cd6acb2b7..9dc470a161b60 100644 --- a/drivers/video/video_framebuff.h +++ b/drivers/video/video_framebuff.h @@ -38,8 +38,9 @@ struct vbuf_container_s { - struct v4l2_buffer buf; /* Buffer information */ - struct vbuf_container_s *next; /* Pointer to next buffer */ + struct v4l2_buffer buf; /* Buffer information */ + struct v4l2_plane planes[VIDEO_MAX_PLANES]; /* Buffer planes */ + struct vbuf_container_s *next; /* Pointer to next buffer */ }; typedef struct vbuf_container_s vbuf_container_t; @@ -89,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 */ diff --git a/include/nuttx/video/imgdata.h b/include/nuttx/video/imgdata.h index 99a80338d3712..df0f5a3e55c78 100644 --- a/include/nuttx/video/imgdata.h +++ b/include/nuttx/video/imgdata.h @@ -48,6 +48,7 @@ #define IMGDATA_PIX_FMT_YUYV (6) #define IMGDATA_PIX_FMT_YUV420P (7) #define IMGDATA_PIX_FMT_NV12 (8) +#define IMGDATA_PIX_FMT_ENTROPY (9) /* Method access helper macros */ diff --git a/include/nuttx/video/imgsensor.h b/include/nuttx/video/imgsensor.h index 3a3f9f3eb0778..1da25dfaf3745 100644 --- a/include/nuttx/video/imgsensor.h +++ b/include/nuttx/video/imgsensor.h @@ -124,6 +124,7 @@ #define IMGSENSOR_PIX_FMT_YUYV (6) #define IMGSENSOR_PIX_FMT_YUV420P (7) #define IMGSENSOR_PIX_FMT_NV12 (8) +#define IMGSENSOR_PIX_FMT_ENTROPY (9) /* Method access helper macros */ diff --git a/include/nuttx/video/v4l2_m2m.h b/include/nuttx/video/v4l2_m2m.h index 489035708ad59..d911453ce5c65 100644 --- a/include/nuttx/video/v4l2_m2m.h +++ b/include/nuttx/video/v4l2_m2m.h @@ -174,6 +174,26 @@ ((codec)->ops->output_g_bufsize ? \ (codec)->ops->output_g_bufsize(priv) : -ENOTTY) +#define CODEC_CAPTURE_G_BUFCNT(codec, priv) \ + ((codec)->ops->capture_g_bufcnt ? \ + (codec)->ops->capture_g_bufcnt(priv) : V4L2_REQBUFS_COUNT_MAX) + +#define CODEC_OUTPUT_G_BUFCNT(codec, priv) \ + ((codec)->ops->output_g_bufcnt ? \ + (codec)->ops->output_g_bufcnt(priv) : V4L2_REQBUFS_COUNT_MAX) + +#define CODEC_CAPTURE_TRY_MEMORY(codec, priv, mem) \ + ((codec)->ops->capture_try_memory ? \ + (codec)->ops->capture_try_memory(priv, mem) : \ + ((mem == V4L2_MEMORY_MMAP || mem == V4L2_MEMORY_USERPTR) ? \ + 0 : -ENOTTY)) + +#define CODEC_OUTPUT_TRY_MEMORY(codec, priv, mem) \ + ((codec)->ops->output_try_memory ? \ + (codec)->ops->output_try_memory(priv, mem) : \ + ((mem == V4L2_MEMORY_MMAP || mem == V4L2_MEMORY_USERPTR) ? \ + 0 : -ENOTTY)) + /**************************************************************************** * Public Types ****************************************************************************/ @@ -239,6 +259,20 @@ struct codec_ops_s CODE size_t (*capture_g_bufsize)(FAR void *priv); CODE size_t (*output_g_bufsize)(FAR void *priv); + CODE size_t (*capture_g_bufcnt)(FAR void *priv); + CODE size_t (*output_g_bufcnt)(FAR void *priv); + + CODE void *(*alloc_buf)(FAR void *priv, size_t size); + CODE void (*free_buf)(FAR void *priv, FAR void *addr); + + /* Memory mode query interface. + * If the driver does not implement this interface, the v4l2-m2m + * default driver only supports V4L2_MEMORY_MMAP and V4L2_MEMORY_USERPTR. + */ + + CODE int (*capture_try_memory)(FAR void *priv, enum v4l2_memory mem); + CODE int (*output_try_memory)(FAR void *priv, enum v4l2_memory mem); + /* Stream type-dependent parameter ioctls */ CODE int (*capture_g_parm)(FAR void *priv, diff --git a/include/sys/video_controls.h b/include/sys/video_controls.h index 2ea7f2722582a..bdb5e16a380fc 100644 --- a/include/sys/video_controls.h +++ b/include/sys/video_controls.h @@ -58,6 +58,8 @@ #define V4L2_CID_GAMMA USER_CID(7) /* Gamma value adjustment */ #define V4L2_CID_GAMMA_CURVE USER_CID(8) /* Gamma curve adjustment */ #define V4L2_CID_EXPOSURE USER_CID(9) /* Exposure value */ +#define V4L2_CID_AUTOGAIN USER_CID(10) /* Auto gain */ +#define V4L2_CID_GAIN USER_CID(11) /* Gain value */ /* Mirror horizontally(VIDEO) */ diff --git a/include/sys/videoio.h b/include/sys/videoio.h index 92823f2d0b881..d2c2e125ae962 100644 --- a/include/sys/videoio.h +++ b/include/sys/videoio.h @@ -73,9 +73,15 @@ extern "C" #define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B', 'G', 'R', '4') #define V4L2_PIX_FMT_ABGR32 v4l2_fourcc('A', 'R', '2', '4') #define V4L2_PIX_FMT_XBGR32 v4l2_fourcc('X', 'R', '2', '4') +#define V4L2_PIX_FMT_BGRA32 v4l2_fourcc('R', 'A', '2', '4') +#define V4L2_PIX_FMT_BGRX32 v4l2_fourcc('R', 'X', '2', '4') #define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R', 'G', 'B', '4') +#define V4L2_PIX_FMT_RGBA32 v4l2_fourcc('A', 'B', '2', '4') +#define V4L2_PIX_FMT_RGBX32 v4l2_fourcc('X', 'B', '2', '4') #define V4L2_PIX_FMT_ARGB32 v4l2_fourcc('B', 'A', '2', '4') #define V4L2_PIX_FMT_XRGB32 v4l2_fourcc('B', 'X', '2', '4') +#define V4L2_PIX_FMT_BGR48 v4l2_fourcc('B', 'G', 'R', '6') +#define V4L2_PIX_FMT_RGB48 v4l2_fourcc('R', 'G', 'B', '6') /* Grey formats */ @@ -90,6 +96,10 @@ extern "C" /* Grey bit-packed formats */ #define V4L2_PIX_FMT_Y10BPACK v4l2_fourcc('Y', '1', '0', 'B') +#define V4L2_PIX_FMT_Y10P v4l2_fourcc('Y', '1', '0', 'P') +#define V4L2_PIX_FMT_IPU3_Y10 v4l2_fourcc('i', 'p', '3', 'y') +#define V4L2_PIX_FMT_Y12P v4l2_fourcc('Y', '1', '2', 'P') +#define V4L2_PIX_FMT_Y14P v4l2_fourcc('Y', '1', '4', 'P') /* Palette formats */ @@ -110,7 +120,14 @@ extern "C" #define V4L2_PIX_FMT_YUV444 v4l2_fourcc('Y', '4', '4', '4') #define V4L2_PIX_FMT_YUV555 v4l2_fourcc('Y', 'U', 'V', 'O') #define V4L2_PIX_FMT_YUV565 v4l2_fourcc('Y', 'U', 'V', 'P') +#define V4L2_PIX_FMT_YUV24 v4l2_fourcc('Y', 'U', 'V', '3') #define V4L2_PIX_FMT_YUV32 v4l2_fourcc('Y', 'U', 'V', '4') +#define V4L2_PIX_FMT_AYUV32 v4l2_fourcc('A', 'Y', 'U', 'V') +#define V4L2_PIX_FMT_XYUV32 v4l2_fourcc('X', 'Y', 'U', 'V') +#define V4L2_PIX_FMT_VUYA32 v4l2_fourcc('V', 'U', 'Y', 'A') +#define V4L2_PIX_FMT_VUYX32 v4l2_fourcc('V', 'U', 'Y', 'X') +#define V4L2_PIX_FMT_YUVA32 v4l2_fourcc('Y', 'U', 'V', 'A') +#define V4L2_PIX_FMT_YUVX32 v4l2_fourcc('Y', 'U', 'V', 'X') #define V4L2_PIX_FMT_HI240 v4l2_fourcc('H', 'I', '2', '4') #define V4L2_PIX_FMT_HM12 v4l2_fourcc('H', 'M', '1', '2') #define V4L2_PIX_FMT_M420 v4l2_fourcc('M', '4', '2', '0') @@ -191,11 +208,53 @@ extern "C" #define V4L2_PIX_FMT_SGRBG16 v4l2_fourcc('G', 'R', '1', '6') #define V4L2_PIX_FMT_SRGGB16 v4l2_fourcc('R', 'G', '1', '6') +/* 12bit raw bayer packed, 6 bytes for every 4 pixels */ + +#define V4L2_PIX_FMT_SBGGR12P v4l2_fourcc('p', 'B', 'C', 'C') +#define V4L2_PIX_FMT_SGBRG12P v4l2_fourcc('p', 'G', 'C', 'C') +#define V4L2_PIX_FMT_SGRBG12P v4l2_fourcc('p', 'g', 'C', 'C') +#define V4L2_PIX_FMT_SRGGB12P v4l2_fourcc('p', 'R', 'C', 'C') +#define V4L2_PIX_FMT_SBGGR14 v4l2_fourcc('B', 'G', '1', '4') +#define V4L2_PIX_FMT_SGBRG14 v4l2_fourcc('G', 'B', '1', '4') +#define V4L2_PIX_FMT_SGRBG14 v4l2_fourcc('G', 'R', '1', '4') +#define V4L2_PIX_FMT_SRGGB14 v4l2_fourcc('R', 'G', '1', '4') + +/* 14bit raw bayer packed, 7 bytes for every 4 pixels */ + +#define V4L2_PIX_FMT_SBGGR14P v4l2_fourcc('p', 'B', 'E', 'E') +#define V4L2_PIX_FMT_SGBRG14P v4l2_fourcc('p', 'G', 'E', 'E') +#define V4L2_PIX_FMT_SGRBG14P v4l2_fourcc('p', 'g', 'E', 'E') +#define V4L2_PIX_FMT_SRGGB14P v4l2_fourcc('p', 'R', 'E', 'E') +#define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2') +#define V4L2_PIX_FMT_SGBRG16 v4l2_fourcc('G', 'B', '1', '6') +#define V4L2_PIX_FMT_SGRBG16 v4l2_fourcc('G', 'R', '1', '6') +#define V4L2_PIX_FMT_SRGGB16 v4l2_fourcc('R', 'G', '1', '6') + /* HSV formats */ #define V4L2_PIX_FMT_HSV24 v4l2_fourcc('H', 'S', 'V', '3') #define V4L2_PIX_FMT_HSV32 v4l2_fourcc('H', 'S', 'V', '4') +/* 10bit raw packed, 32 bytes for every 25 pixels, last LSB 6 bits unused */ + +#define V4L2_PIX_FMT_IPU3_SBGGR10 v4l2_fourcc('i', 'p', '3', 'b') +#define V4L2_PIX_FMT_IPU3_SGBRG10 v4l2_fourcc('i', 'p', '3', 'g') +#define V4L2_PIX_FMT_IPU3_SGRBG10 v4l2_fourcc('i', 'p', '3', 'G') +#define V4L2_PIX_FMT_IPU3_SRGGB10 v4l2_fourcc('i', 'p', '3', 'r') + +/* Raspberry Pi PiSP compressed formats. */ + +#define V4L2_PIX_FMT_PISP_COMP1_RGGB v4l2_fourcc('P', 'C', '1', 'R') +#define V4L2_PIX_FMT_PISP_COMP1_GRBG v4l2_fourcc('P', 'C', '1', 'G') +#define V4L2_PIX_FMT_PISP_COMP1_GBRG v4l2_fourcc('P', 'C', '1', 'g') +#define V4L2_PIX_FMT_PISP_COMP1_BGGR v4l2_fourcc('P', 'C', '1', 'B') +#define V4L2_PIX_FMT_PISP_COMP1_MONO v4l2_fourcc('P', 'C', '1', 'M') +#define V4L2_PIX_FMT_PISP_COMP2_RGGB v4l2_fourcc('P', 'C', '2', 'R') +#define V4L2_PIX_FMT_PISP_COMP2_GRBG v4l2_fourcc('P', 'C', '2', 'G') +#define V4L2_PIX_FMT_PISP_COMP2_GBRG v4l2_fourcc('P', 'C', '2', 'g') +#define V4L2_PIX_FMT_PISP_COMP2_BGGR v4l2_fourcc('P', 'C', '2', 'B') +#define V4L2_PIX_FMT_PISP_COMP2_MONO v4l2_fourcc('P', 'C', '2', 'M') + /* Compressed formats */ #define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M', 'J', 'P', 'G') @@ -215,6 +274,7 @@ extern "C" #define V4L2_PIX_FMT_VP8 v4l2_fourcc('V', 'P', '8', '0') #define V4L2_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0') #define V4L2_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C') +#define V4L2_PIX_FMT_ENTROPY v4l2_fourcc('E', 'N', 'T', 'R') /* JPEG + sub image */ @@ -228,10 +288,33 @@ extern "C" #define V4L2_PIX_FMT_SUBIMG_RGB565 v4l2_fourcc('S', 'R', 'G', 'B') +/* Line-based metadata formats */ + +#define V4L2_META_FMT_GENERIC_8 v4l2_fourcc('M', 'E', 'T', '8') +#define V4L2_META_FMT_GENERIC_CSI2_10 v4l2_fourcc('M', 'C', '1', 'A') +#define V4L2_META_FMT_GENERIC_CSI2_12 v4l2_fourcc('M', 'C', '1', 'C') +#define V4L2_META_FMT_GENERIC_CSI2_14 v4l2_fourcc('M', 'C', '1', 'E') +#define V4L2_META_FMT_GENERIC_CSI2_16 v4l2_fourcc('M', 'C', '1', 'G') +#define V4L2_META_FMT_GENERIC_CSI2_20 v4l2_fourcc('M', 'C', '1', 'K') +#define V4L2_META_FMT_GENERIC_CSI2_24 v4l2_fourcc('M', 'C', '1', 'O') + +/* Flags */ + +#define V4L2_PIX_FMT_FLAG_PREMUL_ALPHA 0x00000001 +#define V4L2_PIX_FMT_FLAG_SET_CSC 0x00000002 + /* MAX length of v4l2_fmtdesc description string */ #define V4L2_FMT_DSC_MAX (32) +#define V4L2_CTRL_ID_MASK (0x0fffffff) +#define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL) +#define V4L2_CTRL_ID2WHICH(id) ((id) & 0x0fff0000UL) +#define V4L2_CTRL_DRIVER_PRIV(id) (((id) & 0xffff) >= 0x1000) +#define V4L2_CTRL_WHICH_CUR_VAL 0 +#define V4L2_CTRL_WHICH_DEF_VAL 0x0f000000 +#define V4L2_CTRL_WHICH_REQUEST_VAL 0x0f010000 + /* MAX length of v4l2_query_ext_ctrl dims array */ #define V4L2_CTRL_MAX_DIMS (4) @@ -240,10 +323,6 @@ extern "C" #define V4L2_REQBUFS_COUNT_MAX CONFIG_VIDEO_REQBUFS_COUNT_MAX -/* Buffer error flag */ - -#define V4L2_BUF_FLAG_ERROR (0x0001) - /* Values for v4l2_std_id */ /* One bit for each */ @@ -421,10 +500,13 @@ enum v4l2_capabilities V4L2_CAP_SDR_CAPTURE = 0x00100000, /* Is a SDR capture device */ V4L2_CAP_EXT_PIX_FORMAT = 0x00200000, /* Supports the extended pixel format */ V4L2_CAP_SDR_OUTPUT = 0x00400000, /* Is a SDR output device */ + V4L2_CAP_META_CAPTURE = 0x00800000, /* Is a metadata capture device */ V4L2_CAP_READWRITE = 0x01000000, /* Read/write systemcalls */ V4L2_CAP_ASYNCIO = 0x02000000, /* Async I/O */ V4L2_CAP_STREAMING = 0x04000000, /* Streaming I/O ioctls */ + V4L2_CAP_META_OUTPUT = 0x08000000, /* Is a metadata output device */ V4L2_CAP_TOUCH = 0x10000000, /* Is a touch device */ + V4L2_CAP_IO_MC = 0x20000000, /* Is input/output controlled by the media controller */ V4L2_CAP_DEVICE_CAPS = 0x80000000, /* Sets device capabilities field */ }; @@ -764,6 +846,7 @@ struct v4l2_plane uint32_t mem_offset; unsigned long userptr; int fd; + void *vaddr; } m; uint32_t data_offset; uint32_t reserved[11]; @@ -794,6 +877,7 @@ struct v4l2_buffer unsigned long userptr; /* Address of buffer */ struct v4l2_plane *planes; int fd; + void *vaddr; /* The real kernel address of image data */ } m; uint32_t length; /* User set the buffer size */ }; @@ -804,6 +888,18 @@ typedef struct v4l2_buffer v4l2_buffer_t; #define V4L2_BUF_FLAG_KEYFRAME 0x00000008 +/* Image is a P-frame */ + +#define V4L2_BUF_FLAG_PFRAME 0x00000010 + +/* Image is a B-frame */ + +#define V4L2_BUF_FLAG_BFRAME 0x00000020 + +/* Buffer is ready, but the data contained within is corrupted. */ + +#define V4L2_BUF_FLAG_ERROR 0x00000040 + /* mem2mem encoder/decoder */ #define V4L2_BUF_FLAG_LAST 0x00100000 @@ -815,6 +911,7 @@ struct v4l2_fmtdesc uint32_t flags; char description[V4L2_FMT_DSC_MAX]; /* Description string */ uint32_t pixelformat; /* Format fourcc */ + uint32_t mbus_code; /* Media bus code */ }; enum v4l2_fmt_flag @@ -970,6 +1067,15 @@ struct v4l2_pix_format_mplane uint8_t reserved[7]; }; +struct v4l2_meta_format +{ + uint32_t dataformat; + uint32_t buffersize; + uint32_t width; + uint32_t height; + uint32_t bytesperline; +}; + struct v4l2_format { uint32_t type; /* enum #v4l2_buf_type. */ @@ -977,6 +1083,7 @@ struct v4l2_format { struct v4l2_pix_format pix; /* Image format */ struct v4l2_pix_format_mplane pix_mp; /* V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */ + struct v4l2_meta_format meta; /* V4L2_BUF_TYPE_META_CAPTURE */ } fmt; }; @@ -1196,6 +1303,34 @@ struct v4l2_querymenu }; }; +/* Control flags */ + +#define V4L2_CTRL_FLAG_DISABLED 0x0001 +#define V4L2_CTRL_FLAG_GRABBED 0x0002 +#define V4L2_CTRL_FLAG_READ_ONLY 0x0004 +#define V4L2_CTRL_FLAG_UPDATE 0x0008 +#define V4L2_CTRL_FLAG_INACTIVE 0x0010 +#define V4L2_CTRL_FLAG_SLIDER 0x0020 +#define V4L2_CTRL_FLAG_WRITE_ONLY 0x0040 +#define V4L2_CTRL_FLAG_VOLATILE 0x0080 +#define V4L2_CTRL_FLAG_HAS_PAYLOAD 0x0100 +#define V4L2_CTRL_FLAG_EXECUTE_ON_WRITE 0x0200 +#define V4L2_CTRL_FLAG_MODIFY_LAYOUT 0x0400 +#define V4L2_CTRL_FLAG_DYNAMIC_ARRAY 0x0800 + +/* Query flags, to be ORed with the control ID */ + +#define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000 +#define V4L2_CTRL_FLAG_NEXT_COMPOUND 0x40000000 + +/* User-class control IDs defined by V4L2 */ + +#define V4L2_CID_MAX_CTRLS 1024 + +/* IDs reserved for driver specific controls */ + +#define V4L2_CID_PRIVATE_BASE 0x08000000 + struct v4l2_input { uint32_t index; /* Which input */ @@ -1586,10 +1721,14 @@ struct v4l2_decoder_cmd #define VIDIOC_DQEVENT _VIDIOC(0x0059) -/* Subscribe or unsubscribe event */ +/* Subscribe event */ #define VIDIOC_SUBSCRIBE_EVENT _VIDIOC(0x005a) +/* Unsubscribe event */ + +#define VIDIOC_UNSUBSCRIBE_EVENT _VIDIOC(0x005b) + /* Get clip * Address pointing to struct v4l2_selection */