media: bcm2835-v4l2-codec: Add profile & level ctrls to decode
authorJohn Cox <jc@kynesim.co.uk>
Mon, 30 Jan 2023 16:34:55 +0000 (16:34 +0000)
committerPhil Elwell <8911409+pelwell@users.noreply.github.com>
Tue, 31 Jan 2023 15:09:59 +0000 (15:09 +0000)
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 <jc@kynesim.co.uk>
drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c

index 2b15070..67c18d5 100644 (file)
@@ -3193,6 +3193,89 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
        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
  */
@@ -3332,11 +3415,12 @@ static int bcm2835_codec_open(struct file *file)
        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;