From a99a43c595e40de8e584c47b0d05a61d931b416e Mon Sep 17 00:00:00 2001 From: John Cox Date: Mon, 30 Jan 2023 16:34:55 +0000 Subject: [PATCH] media: bcm2835-v4l2-codec: Add profile & level ctrls to decode In order to support discovery of what profile & levels are supported by stateful decoders implement the profile and level controls where they are defined by V4L2. Signed-off-by: John Cox --- .../bcm2835-codec/bcm2835-v4l2-codec.c | 86 ++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) --- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c @@ -3195,6 +3195,89 @@ static int queue_init(void *priv, struct return vb2_queue_init(dst_vq); } +static void dec_add_profile_ctrls(struct bcm2835_codec_dev *const dev, + struct v4l2_ctrl_handler *const hdl) +{ + 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); + 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); + 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); + break; + /* No profiles defined by V4L2 */ + case V4L2_PIX_FMT_H263: + case V4L2_PIX_FMT_JPEG: + case V4L2_PIX_FMT_MJPEG: + case V4L2_PIX_FMT_VC1_ANNEX_G: + default: + break; + } + } +} + /* * File operations */ @@ -3334,11 +3417,12 @@ static int bcm2835_codec_open(struct fil break; case DECODE: { - v4l2_ctrl_handler_init(hdl, 1); + v4l2_ctrl_handler_init(hdl, 1 + dev->supported_fmts[0].num_entries * 2); v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops, V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 1, 1, 1); + dec_add_profile_ctrls(dev, hdl); if (hdl->error) { rc = hdl->error; goto free_ctrl_handler;