From c446124753c2888fc694efa66e04beaa86623e2a Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Tue, 6 Apr 2021 15:55:08 +0530 Subject: [PATCH] video: driver: add frame interval enum support. Added support for VIDIOC_ENUM_FRAMEINTERVALS to provide supported frame intervals range for a given resolution. Change-Id: I51174634739dd1141d308ba9bfd1cf3720b6ca42 Signed-off-by: Govindaraj Rajagopal --- driver/vidc/inc/msm_vidc.h | 1 + driver/vidc/inc/msm_vidc_v4l2.h | 2 + driver/vidc/src/msm_vidc.c | 71 +++++++++++++++++++++++++++++ driver/vidc/src/msm_vidc_platform.c | 1 + driver/vidc/src/msm_vidc_v4l2.c | 8 ++++ 5 files changed, 83 insertions(+) diff --git a/driver/vidc/inc/msm_vidc.h b/driver/vidc/inc/msm_vidc.h index 40990d2207..9f3d3d33c3 100644 --- a/driver/vidc/inc/msm_vidc.h +++ b/driver/vidc/inc/msm_vidc.h @@ -49,4 +49,5 @@ int msm_vidc_unsubscribe_event(void *instance, int msm_vidc_dqevent(void *instance, struct v4l2_event *event); int msm_vidc_g_crop(void *instance, struct v4l2_crop *a); int msm_vidc_enum_framesizes(void *instance, struct v4l2_frmsizeenum *fsize); +int msm_vidc_enum_frameintervals(void *instance, struct v4l2_frmivalenum *fival); #endif diff --git a/driver/vidc/inc/msm_vidc_v4l2.h b/driver/vidc/inc/msm_vidc_v4l2.h index 018bedc784..65ac6af676 100644 --- a/driver/vidc/inc/msm_vidc_v4l2.h +++ b/driver/vidc/inc/msm_vidc_v4l2.h @@ -54,6 +54,8 @@ int msm_v4l2_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc); int msm_v4l2_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize); +int msm_v4l2_enum_frameintervals(struct file *file, void *fh, + struct v4l2_frmivalenum *fival); int msm_v4l2_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *ctrl); int msm_v4l2_querymenu(struct file *file, void *fh, diff --git a/driver/vidc/src/msm_vidc.c b/driver/vidc/src/msm_vidc.c index eac500eb0d..ecdd22c150 100644 --- a/driver/vidc/src/msm_vidc.c +++ b/driver/vidc/src/msm_vidc.c @@ -603,6 +603,7 @@ int msm_vidc_enum_framesizes(void *instance, struct v4l2_frmsizeenum *fsize) { struct msm_vidc_inst *inst = instance; struct msm_vidc_inst_capability *capability; + enum msm_vidc_colorformat_type colorfmt; if (!inst || !fsize) { d_vpr_e("%s: invalid params: %pK %pK\n", @@ -614,6 +615,18 @@ int msm_vidc_enum_framesizes(void *instance, struct v4l2_frmsizeenum *fsize) return -EINVAL; } capability = inst->capabilities; + + /* only index 0 allowed as per v4l2 spec */ + if (fsize->index) + return -EINVAL; + + /* validate pixel format */ + colorfmt = v4l2_colorformat_to_driver(fsize->pixel_format, __func__); + if (colorfmt == MSM_VIDC_FMT_NONE) { + i_vpr_e(inst, "%s: unsupported pix fmt %#x\n", __func__, fsize->pixel_format); + return -EINVAL; + } + fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; fsize->stepwise.min_width = capability->cap[FRAME_WIDTH].min; fsize->stepwise.max_width = capability->cap[FRAME_WIDTH].max; @@ -628,6 +641,64 @@ int msm_vidc_enum_framesizes(void *instance, struct v4l2_frmsizeenum *fsize) } EXPORT_SYMBOL(msm_vidc_enum_framesizes); +int msm_vidc_enum_frameintervals(void *instance, struct v4l2_frmivalenum *fival) +{ + struct msm_vidc_inst *inst = instance; + struct msm_vidc_core *core; + struct msm_vidc_inst_capability *capability; + enum msm_vidc_colorformat_type colorfmt; + u32 fps, mbpf; + + if (!inst || !fival) { + d_vpr_e("%s: invalid params: %pK %pK\n", + __func__, inst, fival); + return -EINVAL; + } + core = inst->core; + + if (!inst->capabilities || !core->capabilities) { + i_vpr_e(inst, "capabilities not available\n", __func__); + return -EINVAL; + } + capability = inst->capabilities; + + /* only index 0 allowed as per v4l2 spec */ + if (fival->index) + return -EINVAL; + + /* validate pixel format */ + colorfmt = v4l2_colorformat_to_driver(fival->pixel_format, __func__); + if (colorfmt == MSM_VIDC_FMT_NONE) { + i_vpr_e(inst, "%s: unsupported pix fmt %#x\n", __func__, fival->pixel_format); + return -EINVAL; + } + + /* validate resolution */ + if (fival->width > capability->cap[FRAME_WIDTH].max || + fival->width < capability->cap[FRAME_WIDTH].min || + fival->height > capability->cap[FRAME_HEIGHT].max || + fival->height < capability->cap[FRAME_HEIGHT].min) { + i_vpr_e(inst, "%s: unsupported resolution %u x %u\n", __func__, + fival->width, fival->height); + return -EINVAL; + } + + /* calculate max supported fps for a given resolution */ + mbpf = NUM_MBS_PER_FRAME(fival->height, fival->width); + fps = core->capabilities[MAX_MBPS].value / mbpf; + + fival->type = V4L2_FRMIVAL_TYPE_STEPWISE; + fival->stepwise.min.numerator = 1; + fival->stepwise.min.denominator = min_t(u32, fps, MAXIMUM_FPS); + fival->stepwise.max.numerator = 1; + fival->stepwise.max.denominator = 1; + fival->stepwise.step.numerator = 1; + fival->stepwise.step.denominator = MAXIMUM_FPS; + + return 0; +} +EXPORT_SYMBOL(msm_vidc_enum_frameintervals); + int msm_vidc_subscribe_event(void *instance, const struct v4l2_event_subscription *sub) { diff --git a/driver/vidc/src/msm_vidc_platform.c b/driver/vidc/src/msm_vidc_platform.c index 0c3831b5b8..d1da9f3155 100644 --- a/driver/vidc/src/msm_vidc_platform.c +++ b/driver/vidc/src/msm_vidc_platform.c @@ -27,6 +27,7 @@ static struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = { .vidioc_enum_fmt_vid_cap = msm_v4l2_enum_fmt, .vidioc_enum_fmt_vid_out = msm_v4l2_enum_fmt, .vidioc_enum_framesizes = msm_v4l2_enum_framesizes, + .vidioc_enum_frameintervals = msm_v4l2_enum_frameintervals, .vidioc_s_fmt_vid_cap = msm_v4l2_s_fmt, .vidioc_s_fmt_vid_out = msm_v4l2_s_fmt, .vidioc_s_fmt_vid_cap_mplane = msm_v4l2_s_fmt, diff --git a/driver/vidc/src/msm_vidc_v4l2.c b/driver/vidc/src/msm_vidc_v4l2.c index fb4d1785ef..7d57e440d4 100644 --- a/driver/vidc/src/msm_vidc_v4l2.c +++ b/driver/vidc/src/msm_vidc_v4l2.c @@ -215,6 +215,14 @@ int msm_v4l2_enum_framesizes(struct file *file, void *fh, return msm_vidc_enum_framesizes((void *)vidc_inst, fsize); } +int msm_v4l2_enum_frameintervals(struct file *file, void *fh, + struct v4l2_frmivalenum *fival) +{ + struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh); + + return msm_vidc_enum_frameintervals((void *)vidc_inst, fival); +} + int msm_v4l2_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *ctrl) {