From 3ad45d26aba6f69f82220f59824b4d8422b2b220 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Tue, 14 Feb 2023 15:35:43 +0000 Subject: [PATCH] vc04_services: bcm2835_codec: Ignore READ_ONLY ctrls in s_ctrl In adding the MPEG2/MPEG4/H264 level and profile controls to the decoder, they weren't declared as read-only, nor handlers added to bcm2835_codec_s_ctrl. That resulted in an error message "Invalid control" being logged every time v4l2_ctrl_handler_setup was called from bcm2835_codec_create_component. Define those controls as read only, and exit early from s_ctrl on read only controls. Fixes: "media: bcm2835-v4l2-codec: Add profile & level ctrls to decode" Signed-off-by: Dave Stevenson --- .../bcm2835-codec/bcm2835-v4l2-codec.c | 127 ++++++++++-------- 1 file changed, 68 insertions(+), 59 deletions(-) --- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c @@ -2224,6 +2224,9 @@ static int bcm2835_codec_s_ctrl(struct v container_of(ctrl->handler, struct bcm2835_codec_ctx, hdl); int ret = 0; + if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY) + return 0; + switch (ctrl->id) { case V4L2_CID_MPEG_VIDEO_BITRATE: ctx->bitrate = ctrl->val; @@ -2376,7 +2379,7 @@ static int bcm2835_codec_s_ctrl(struct v break; default: - v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n"); + v4l2_err(&ctx->dev->v4l2_dev, "Invalid control %08x\n", ctrl->id); return -EINVAL; } @@ -3198,74 +3201,80 @@ static int queue_init(void *priv, struct static void dec_add_profile_ctrls(struct bcm2835_codec_dev *const dev, struct v4l2_ctrl_handler *const hdl) { + struct v4l2_ctrl *ctrl; unsigned int i; const struct bcm2835_codec_fmt_list *const list = &dev->supported_fmts[0]; for (i = 0; i < list->num_entries; ++i) { switch (list->list[i].fourcc) { case V4L2_PIX_FMT_H264: - v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops, - V4L2_CID_MPEG_VIDEO_H264_LEVEL, - V4L2_MPEG_VIDEO_H264_LEVEL_4_2, - ~(BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2)), - V4L2_MPEG_VIDEO_H264_LEVEL_4_0); - v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops, - V4L2_CID_MPEG_VIDEO_H264_PROFILE, - V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, - ~(BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | - BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) | - BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | - BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)), - V4L2_MPEG_VIDEO_H264_PROFILE_HIGH); + ctrl = v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops, + V4L2_CID_MPEG_VIDEO_H264_LEVEL, + V4L2_MPEG_VIDEO_H264_LEVEL_4_2, + ~(BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2)), + V4L2_MPEG_VIDEO_H264_LEVEL_4_0); + ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; + ctrl = v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops, + V4L2_CID_MPEG_VIDEO_H264_PROFILE, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, + ~(BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) | + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)), + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH); + ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; break; case V4L2_PIX_FMT_MPEG2: - v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops, - V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL, - V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH, - ~(BIT(V4L2_MPEG_VIDEO_MPEG2_LEVEL_LOW) | - BIT(V4L2_MPEG_VIDEO_MPEG2_LEVEL_MAIN) | - BIT(V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH_1440) | - BIT(V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH)), - V4L2_MPEG_VIDEO_MPEG2_LEVEL_MAIN); - v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops, - V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE, - V4L2_MPEG_VIDEO_MPEG2_PROFILE_MAIN, - ~(BIT(V4L2_MPEG_VIDEO_MPEG2_PROFILE_SIMPLE) | - BIT(V4L2_MPEG_VIDEO_MPEG2_PROFILE_MAIN)), - V4L2_MPEG_VIDEO_MPEG2_PROFILE_MAIN); + ctrl = v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops, + V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL, + V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH, + ~(BIT(V4L2_MPEG_VIDEO_MPEG2_LEVEL_LOW) | + BIT(V4L2_MPEG_VIDEO_MPEG2_LEVEL_MAIN) | + BIT(V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH_1440) | + BIT(V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH)), + V4L2_MPEG_VIDEO_MPEG2_LEVEL_MAIN); + ctrl = v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops, + V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE, + V4L2_MPEG_VIDEO_MPEG2_PROFILE_MAIN, + ~(BIT(V4L2_MPEG_VIDEO_MPEG2_PROFILE_SIMPLE) | + BIT(V4L2_MPEG_VIDEO_MPEG2_PROFILE_MAIN)), + V4L2_MPEG_VIDEO_MPEG2_PROFILE_MAIN); + ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; break; case V4L2_PIX_FMT_MPEG4: - v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops, - V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL, - V4L2_MPEG_VIDEO_MPEG4_LEVEL_5, - ~(BIT(V4L2_MPEG_VIDEO_MPEG4_LEVEL_0) | - BIT(V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B) | - BIT(V4L2_MPEG_VIDEO_MPEG4_LEVEL_1) | - BIT(V4L2_MPEG_VIDEO_MPEG4_LEVEL_2) | - BIT(V4L2_MPEG_VIDEO_MPEG4_LEVEL_3) | - BIT(V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B) | - BIT(V4L2_MPEG_VIDEO_MPEG4_LEVEL_4) | - BIT(V4L2_MPEG_VIDEO_MPEG4_LEVEL_5)), - V4L2_MPEG_VIDEO_MPEG4_LEVEL_4); - v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops, - V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE, - V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE, - ~(BIT(V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE) | - BIT(V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)), - V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE); + ctrl = v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops, + V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_5, + ~(BIT(V4L2_MPEG_VIDEO_MPEG4_LEVEL_0) | + BIT(V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B) | + BIT(V4L2_MPEG_VIDEO_MPEG4_LEVEL_1) | + BIT(V4L2_MPEG_VIDEO_MPEG4_LEVEL_2) | + BIT(V4L2_MPEG_VIDEO_MPEG4_LEVEL_3) | + BIT(V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B) | + BIT(V4L2_MPEG_VIDEO_MPEG4_LEVEL_4) | + BIT(V4L2_MPEG_VIDEO_MPEG4_LEVEL_5)), + V4L2_MPEG_VIDEO_MPEG4_LEVEL_4); + ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; + ctrl = v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops, + V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE, + V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE, + ~(BIT(V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE) | + BIT(V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)), + V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE); + ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; break; /* No profiles defined by V4L2 */ case V4L2_PIX_FMT_H263: