From bf10c49be3c31fd7f85e8a878f35e375e64b89ca Mon Sep 17 00:00:00 2001 From: yaojingwei Date: Thu, 23 Nov 2023 11:40:36 +0800 Subject: [PATCH] video: extend imgsensor_s interface for getting sensor device params. Signed-off-by: yaojingwei --- drivers/video/video.c | 183 ++++++++++++++++++++++++++++++-- include/nuttx/video/imgsensor.h | 6 ++ 2 files changed, 179 insertions(+), 10 deletions(-) diff --git a/drivers/video/video.c b/drivers/video/video.c index 105e2d87458f0..1acbb10212b8f 100644 --- a/drivers/video/video.c +++ b/drivers/video/video.c @@ -703,7 +703,8 @@ static bool is_bufsize_sufficient(FAR video_mng_t *vmng, uint32_t bufsize) return true; } -static void initialize_frame_setting(FAR uint8_t *nr_fmt, +static void initialize_frame_setting(FAR struct imgsensor_s *imgsensor, + FAR uint8_t *nr_fmt, FAR video_format_t *fmt, FAR struct v4l2_fract *interval) { @@ -712,20 +713,70 @@ static void initialize_frame_setting(FAR uint8_t *nr_fmt, /* Initial setting : QVGA YUV4:2:2 15FPS */ *nr_fmt = 1; - fmt[VIDEO_FMT_MAIN].width = VIDEO_HSIZE_QVGA; - fmt[VIDEO_FMT_MAIN].height = VIDEO_VSIZE_QVGA; - fmt[VIDEO_FMT_MAIN].pixelformat = V4L2_PIX_FMT_UYVY; - interval->denominator = 15; - interval->numerator = 1; + if (imgsensor && imgsensor->frmsizes) + { + if (imgsensor->frmsizes[0].type == V4L2_FRMSIZE_TYPE_DISCRETE) + { + fmt[VIDEO_FMT_MAIN].width = + imgsensor->frmsizes[0].discrete.width; + fmt[VIDEO_FMT_MAIN].height = + imgsensor->frmsizes[0].discrete.height; + } + else + { + fmt[VIDEO_FMT_MAIN].width = + imgsensor->frmsizes[0].stepwise.min_width; + fmt[VIDEO_FMT_MAIN].height = + imgsensor->frmsizes[0].stepwise.min_height; + } + } + else + { + fmt[VIDEO_FMT_MAIN].width = VIDEO_HSIZE_QVGA; + fmt[VIDEO_FMT_MAIN].height = VIDEO_VSIZE_QVGA; + } + + if (imgsensor && imgsensor->fmtdescs) + { + fmt[VIDEO_FMT_MAIN].pixelformat = imgsensor->fmtdescs[0].pixelformat; + } + else + { + fmt[VIDEO_FMT_MAIN].pixelformat = V4L2_PIX_FMT_UYVY; + } + + if (imgsensor && imgsensor->frmintervals) + { + if (imgsensor->frmintervals[0].type == V4L2_FRMIVAL_TYPE_DISCRETE) + { + interval->denominator = + imgsensor->frmintervals[0].discrete.denominator; + interval->numerator = + imgsensor->frmintervals[0].discrete.numerator; + } + else + { + interval->denominator = + imgsensor->frmintervals[0].stepwise.min.denominator; + interval->numerator = + imgsensor->frmintervals[0].stepwise.min.numerator; + } + } + else + { + interval->denominator = 15; + interval->numerator = 1; + } } -static void initialize_streamresources(FAR video_type_inf_t *type_inf) +static void initialize_streamresources(FAR video_type_inf_t *type_inf, + FAR struct imgsensor_s *imgsensor) { memset(type_inf, 0, sizeof(video_type_inf_t)); type_inf->remaining_capnum = VIDEO_REMAINING_CAPNUM_INFINITY; nxmutex_init(&type_inf->lock_state); nxsem_init(&type_inf->wait_capture.dqbuf_wait_flg, 0, 0); - initialize_frame_setting(&type_inf->nr_fmt, + initialize_frame_setting(imgsensor, &type_inf->nr_fmt, type_inf->fmt, &type_inf->frame_interval); video_framebuff_init(&type_inf->bufinf); @@ -951,8 +1002,8 @@ static void initialize_scenes_parameter(FAR video_mng_t *vmng) static void initialize_resources(FAR video_mng_t *vmng) { - initialize_streamresources(&vmng->video_inf); - initialize_streamresources(&vmng->still_inf); + initialize_streamresources(&vmng->video_inf, vmng->imgsensor); + initialize_streamresources(&vmng->still_inf, vmng->imgsensor); initialize_scenes_parameter(vmng); } @@ -3073,6 +3124,103 @@ static int video_s_ext_ctrls_scene(FAR struct video_mng_s *vmng, return ret; } +static int video_enum_fmt(FAR video_mng_t *vmng, struct v4l2_fmtdesc *f) +{ + if (vmng->imgsensor && vmng->imgsensor->fmtdescs) + { + if (f->index > vmng->imgsensor->fmtdescs_num) + { + return -EINVAL; + } + else + { + f->pixelformat = vmng->imgsensor->fmtdescs[f->index].pixelformat; + strlcpy(f->description, + vmng->imgsensor->fmtdescs[f->index].description, + sizeof(f->description)); + } + } + else + { + if (f->index > 0) + return -EINVAL; + + f->pixelformat = V4L2_PIX_FMT_UYVY; + } + + return 0; +} + +static int video_enum_frmsize(FAR video_mng_t *vmng, + struct v4l2_frmsizeenum *f) +{ + if (vmng->imgsensor && vmng->imgsensor->frmsizes) + { + if (f->index > vmng->imgsensor->frmsizes_num) + { + return -EINVAL; + } + else + { + f->type = vmng->imgsensor->frmsizes[f->index].type; + if (f->type == V4L2_FRMSIZE_TYPE_DISCRETE) + { + f->discrete = vmng->imgsensor->frmsizes[f->index].discrete; + } + else + { + f->stepwise = vmng->imgsensor->frmsizes[f->index].stepwise; + } + } + } + else + { + if (f->index > 0) + return -EINVAL; + + f->type = V4L2_FRMIVAL_TYPE_DISCRETE; + f->discrete.width = VIDEO_HSIZE_QVGA; + f->discrete.height = VIDEO_VSIZE_QVGA; + } + + return 0; +} + +static int video_enum_frminterval(FAR video_mng_t *vmng, + struct v4l2_frmivalenum *f) +{ + if (vmng->imgsensor && vmng->imgsensor->frmintervals) + { + if (f->index > vmng->imgsensor->frmintervals_num) + { + return -EINVAL; + } + else + { + f->type = vmng->imgsensor->frmintervals[f->index].type; + if (f->type == V4L2_FRMIVAL_TYPE_DISCRETE) + { + f->discrete = vmng->imgsensor->frmintervals[f->index].discrete; + } + else + { + f->stepwise = vmng->imgsensor->frmintervals[f->index].stepwise; + } + } + } + else + { + if (f->index > 0) + return -EINVAL; + + f->type = V4L2_FRMIVAL_TYPE_DISCRETE; + f->discrete.denominator = 15; + f->discrete.numerator = 1; + } + + return 0; +} + /**************************************************************************** * Name: video_ioctl * @@ -3228,6 +3376,21 @@ static int video_ioctl(FAR struct file *filep, int cmd, unsigned long arg) (FAR struct v4s_ext_controls_scene *)arg); break; + case VIDIOC_ENUM_FMT: + ret = video_enum_fmt(priv, + (FAR struct v4l2_fmtdesc *)arg); + break; + + case VIDIOC_ENUM_FRAMEINTERVALS: + ret = video_enum_frminterval(priv, + (FAR struct v4l2_frmivalenum *)arg); + break; + + case VIDIOC_ENUM_FRAMESIZES: + ret = video_enum_frmsize(priv, + (FAR struct v4l2_frmsizeenum *)arg); + break; + default: verr("Unrecognized cmd: %d\n", cmd); ret = - ENOTTY; diff --git a/include/nuttx/video/imgsensor.h b/include/nuttx/video/imgsensor.h index 36fa9baef187b..ad1f3bd56608e 100644 --- a/include/nuttx/video/imgsensor.h +++ b/include/nuttx/video/imgsensor.h @@ -393,6 +393,12 @@ struct imgsensor_ops_s struct imgsensor_s { FAR const struct imgsensor_ops_s *ops; + size_t fmtdescs_num; + FAR const struct v4l2_fmtdesc *fmtdescs; + size_t frmsizes_num; + FAR const struct v4l2_frmsizeenum *frmsizes; + size_t frmintervals_num; + FAR const struct v4l2_frmivalenum *frmintervals; }; #ifdef __cplusplus