media: cedrus: add check for H264 and H265 limitations
authorJernej Skrabec <jernej.skrabec@gmail.com>
Sun, 12 Sep 2021 08:20:51 +0000 (10:20 +0200)
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Tue, 5 Oct 2021 07:35:36 +0000 (09:35 +0200)
Cedrus supports only YUV420 H264/H265 content and mostly only 8-bit
colours (except on H6, where 10-bit are also supported).

Add validation callback to SPS controls, which will reject unsupported
combinations.

Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
drivers/staging/media/sunxi/cedrus/cedrus.c

index e7741178465b463398baaa755ef4ddf9dc110179..9dd30cb568e890f70b27478df9e3c016a5940c1e 100644 (file)
 #include "cedrus_dec.h"
 #include "cedrus_hw.h"
 
+static int cedrus_try_ctrl(struct v4l2_ctrl *ctrl)
+{
+       if (ctrl->id == V4L2_CID_STATELESS_H264_SPS) {
+               const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p_h264_sps;
+
+               if (sps->chroma_format_idc != 1)
+                       /* Only 4:2:0 is supported */
+                       return -EINVAL;
+               if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8)
+                       /* Luma and chroma bit depth mismatch */
+                       return -EINVAL;
+               if (sps->bit_depth_luma_minus8 != 0)
+                       /* Only 8-bit is supported */
+                       return -EINVAL;
+       } else if (ctrl->id == V4L2_CID_MPEG_VIDEO_HEVC_SPS) {
+               const struct v4l2_ctrl_hevc_sps *sps = ctrl->p_new.p_hevc_sps;
+               struct cedrus_ctx *ctx = container_of(ctrl->handler, struct cedrus_ctx, hdl);
+
+               if (sps->chroma_format_idc != 1)
+                       /* Only 4:2:0 is supported */
+                       return -EINVAL;
+
+               if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8)
+                       /* Luma and chroma bit depth mismatch */
+                       return -EINVAL;
+
+               if (ctx->dev->capabilities & CEDRUS_CAPABILITY_H265_10_DEC) {
+                       if (sps->bit_depth_luma_minus8 != 0 && sps->bit_depth_luma_minus8 != 2)
+                               /* Only 8-bit and 10-bit are supported */
+                               return -EINVAL;
+               } else {
+                       if (sps->bit_depth_luma_minus8 != 0)
+                               /* Only 8-bit is supported */
+                               return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+static const struct v4l2_ctrl_ops cedrus_ctrl_ops = {
+       .try_ctrl = cedrus_try_ctrl,
+};
+
 static const struct cedrus_control cedrus_controls[] = {
        {
                .cfg = {
@@ -62,6 +106,7 @@ static const struct cedrus_control cedrus_controls[] = {
        {
                .cfg = {
                        .id     = V4L2_CID_STATELESS_H264_SPS,
+                       .ops    = &cedrus_ctrl_ops,
                },
                .codec          = CEDRUS_CODEC_H264,
        },
@@ -120,6 +165,7 @@ static const struct cedrus_control cedrus_controls[] = {
        {
                .cfg = {
                        .id     = V4L2_CID_MPEG_VIDEO_HEVC_SPS,
+                       .ops    = &cedrus_ctrl_ops,
                },
                .codec          = CEDRUS_CODEC_H265,
        },