diff --git a/drivers/mxc/hantro_v4l2/vsi-v4l2-config.c b/drivers/mxc/hantro_v4l2/vsi-v4l2-config.c index 93813bad0706..1e21d45ce43d 100644 --- a/drivers/mxc/hantro_v4l2/vsi-v4l2-config.c +++ b/drivers/mxc/hantro_v4l2/vsi-v4l2-config.c @@ -750,6 +750,93 @@ static struct vsi_video_fmt vsi_coded_fmt[] = { }, }; +static const struct vsi_v4l2_ctrl_applicable vsi_ctrl_formats[] = { + { + .id = V4L2_CID_MPEG_VIDEO_H264_PROFILE, + .applicable_pixelformat = {V4L2_PIX_FMT_H264}, + }, + { + .id = V4L2_CID_MPEG_VIDEO_VP8_PROFILE, + .applicable_pixelformat = {V4L2_PIX_FMT_VP8}, + }, + { + .id = V4L2_CID_MPEG_VIDEO_VP9_PROFILE, + .applicable_pixelformat = {V4L2_PIX_FMT_VP9}, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, + .applicable_pixelformat = {V4L2_PIX_FMT_HEVC}, + }, + { + .id = V4L2_CID_MPEG_VIDEO_H264_LEVEL, + .applicable_pixelformat = {V4L2_PIX_FMT_H264}, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_LEVEL, + .applicable_pixelformat = {V4L2_PIX_FMT_HEVC}, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP, + .applicable_pixelformat = {V4L2_PIX_FMT_HEVC}, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP, + .applicable_pixelformat = {V4L2_PIX_FMT_HEVC}, + }, + { + .id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP, + .applicable_pixelformat = {V4L2_PIX_FMT_H264}, + }, + { + .id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP, + .applicable_pixelformat = {V4L2_PIX_FMT_H264}, + }, + { + .id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP, + .applicable_pixelformat = {V4L2_PIX_FMT_H264}, + }, + { + .id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, + .applicable_pixelformat = {V4L2_PIX_FMT_H264}, + }, + { + .id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, + .applicable_pixelformat = {V4L2_PIX_FMT_H264}, + }, + { + .id = V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE, + .applicable_pixelformat = {V4L2_PIX_FMT_H264}, + }, + { + .id = V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET, + .applicable_pixelformat = {V4L2_PIX_FMT_H264}, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP, + .applicable_pixelformat = {V4L2_PIX_FMT_HEVC}, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP, + .applicable_pixelformat = {V4L2_PIX_FMT_HEVC}, + }, + { + .id = V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP, + .applicable_pixelformat = {V4L2_PIX_FMT_VP8, V4L2_PIX_FMT_VP9}, + }, + { + .id = V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP, + .applicable_pixelformat = {V4L2_PIX_FMT_VP8, V4L2_PIX_FMT_VP9}, + }, + { + .id = V4L2_CID_MPEG_VIDEO_VPX_MIN_QP, + .applicable_pixelformat = {V4L2_PIX_FMT_VP8, V4L2_PIX_FMT_VP9}, + }, + { + .id = V4L2_CID_MPEG_VIDEO_VPX_MAX_QP, + .applicable_pixelformat = {V4L2_PIX_FMT_VP8, V4L2_PIX_FMT_VP9}, + }, +}; + static int istiledfmt(int pixelformat) { switch (pixelformat) { @@ -2168,4 +2255,41 @@ void vsi_v4l2_update_ctrlcfg(struct v4l2_ctrl_config *cfg) } } +static const struct vsi_v4l2_ctrl_applicable *vsi_v4l2_find_ctrl_applicable(u32 ctrl_id) +{ + int i; + for (i = 0; i < ARRAY_SIZE(vsi_ctrl_formats); i++) { + if (vsi_ctrl_formats[i].id == ctrl_id) + return &vsi_ctrl_formats[i]; + } + + return NULL; +} + +bool vsi_v4l2_ctrl_is_applicable(struct vsi_v4l2_ctx *ctx, u32 ctrl_id) +{ + const struct vsi_v4l2_ctrl_applicable *app; + struct v4l2_format fmt; + int i; + + app = vsi_v4l2_find_ctrl_applicable(ctrl_id); + if (!app) + return true; + + for (i = 0; i < ARRAY_SIZE(app->applicable_pixelformat); i++) { + if (!app->applicable_pixelformat[i]) + break; + if (isencoder(ctx)) { + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + fmt.fmt.pix_mp.pixelformat = app->applicable_pixelformat[i]; + } else { + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + fmt.fmt.pix.pixelformat = app->applicable_pixelformat[i]; + } + if (vsi_find_format(ctx, &fmt)) + return true; + } + + return false; +} diff --git a/drivers/mxc/hantro_v4l2/vsi-v4l2-dec.c b/drivers/mxc/hantro_v4l2/vsi-v4l2-dec.c index a750f2490e3d..e207dfd1ec73 100644 --- a/drivers/mxc/hantro_v4l2/vsi-v4l2-dec.c +++ b/drivers/mxc/hantro_v4l2/vsi-v4l2-dec.c @@ -1093,6 +1093,7 @@ static struct v4l2_ctrl_config vsi_v4l2_dec_ctrl_defs[] = { static int vsi_dec_setup_ctrls(struct v4l2_ctrl_handler *handler) { + struct vsi_v4l2_ctx *ctx = container_of(handler, struct vsi_v4l2_ctx, ctrlhdl); int i, ctrl_num = ARRAY_SIZE(vsi_v4l2_dec_ctrl_defs); struct v4l2_ctrl *ctrl = NULL; @@ -1102,6 +1103,12 @@ static int vsi_dec_setup_ctrls(struct v4l2_ctrl_handler *handler) return handler->error; for (i = 0; i < ctrl_num; i++) { + if (!vsi_v4l2_ctrl_is_applicable(ctx, vsi_v4l2_dec_ctrl_defs[i].id)) { + v4l2_klog(LOGLVL_CONFIG, "ctrl %d is not applicable for vsidec\n", + vsi_v4l2_dec_ctrl_defs[i].id); + continue; + } + vsi_v4l2_update_ctrlcfg(&vsi_v4l2_dec_ctrl_defs[i]); if (is_vsi_ctrl(vsi_v4l2_dec_ctrl_defs[i].id)) ctrl = v4l2_ctrl_new_custom(handler, &vsi_v4l2_dec_ctrl_defs[i], NULL); diff --git a/drivers/mxc/hantro_v4l2/vsi-v4l2-enc.c b/drivers/mxc/hantro_v4l2/vsi-v4l2-enc.c index f5ebe00aea2e..67c88ef364e3 100644 --- a/drivers/mxc/hantro_v4l2/vsi-v4l2-enc.c +++ b/drivers/mxc/hantro_v4l2/vsi-v4l2-enc.c @@ -1406,6 +1406,7 @@ static struct v4l2_ctrl_config vsi_v4l2_encctrl_defs[] = { static int vsi_setup_enc_ctrls(struct v4l2_ctrl_handler *handler) { + struct vsi_v4l2_ctx *ctx = container_of(handler, struct vsi_v4l2_ctx, ctrlhdl); int i, ctrl_num = ARRAY_SIZE(vsi_v4l2_encctrl_defs); struct v4l2_ctrl *ctrl = NULL; @@ -1415,6 +1416,12 @@ static int vsi_setup_enc_ctrls(struct v4l2_ctrl_handler *handler) return handler->error; for (i = 0; i < ctrl_num; i++) { + if (!vsi_v4l2_ctrl_is_applicable(ctx, vsi_v4l2_encctrl_defs[i].id)) { + v4l2_klog(LOGLVL_CONFIG, "ctrl %d is not applicable for vsienc\n", + vsi_v4l2_encctrl_defs[i].id); + continue; + } + vsi_v4l2_update_ctrlcfg(&vsi_v4l2_encctrl_defs[i]); if (is_vsi_ctrl(vsi_v4l2_encctrl_defs[i].id)) ctrl = v4l2_ctrl_new_custom(handler, &vsi_v4l2_encctrl_defs[i], NULL); diff --git a/drivers/mxc/hantro_v4l2/vsi-v4l2-priv.h b/drivers/mxc/hantro_v4l2/vsi-v4l2-priv.h index a74cb82bc387..223239e02e5f 100644 --- a/drivers/mxc/hantro_v4l2/vsi-v4l2-priv.h +++ b/drivers/mxc/hantro_v4l2/vsi-v4l2-priv.h @@ -371,6 +371,11 @@ struct vsi_v4l2_ctx { struct dentry *debugfs; }; +struct vsi_v4l2_ctrl_applicable { + u32 id; + u32 applicable_pixelformat[4]; +}; + int vsi_v4l2_release(struct file *filp); void vsi_remove_ctx(struct vsi_v4l2_ctx *ctx); struct vsi_v4l2_ctx *vsi_create_ctx(void); @@ -444,6 +449,7 @@ void vsi_convertIPCM(struct vsi_v4l2_ctx *ctx); int vsiv4l2_verifycrop(struct v4l2_selection *s); void vsi_v4l2_update_ctrlcfg(struct v4l2_ctrl_config *cfg); void vsi_v4l2_reset_performance(struct vsi_v4l2_ctx *ctx); +bool vsi_v4l2_ctrl_is_applicable(struct vsi_v4l2_ctx *ctx, u32 ctrl_id); static inline int isencoder(struct vsi_v4l2_ctx *ctx) {