On Thu May 1 15:55:50 2025 -0400, Jonas Karlman wrote:
> Add support and enable decoding of H264 High 10 and 4:2:2 profiles.
> 
> Decoded CAPTURE buffer width is aligned to 64 pixels to accommodate HW
> requirement of 10-bit format buffers, fixes decoding of all the 4:2:2
> and 10bit 4:2:2 flusters tests except two stream that present some
> visual artifacts.
> 
> - Hi422FREXT17_SONY_A
> - Hi422FREXT19_SONY_A
> 
> The get_image_fmt() ops is implemented to select an image format
> required for the provided SPS control, and returns RKVDEC_IMG_FMT_ANY
> for other controls.
> 
> Signed-off-by: Jonas Karlman <jo...@kwiboo.se>
> Reviewed-by: Nicolas Dufresne <nicolas.dufre...@collabora.com>
> Tested-by: Nicolas Dufresne <nicolas.dufre...@collabora.com>
> Tested-by: Christopher Obbard <chris.obb...@collabora.com>
> Signed-off-by: Nicolas Dufresne <nicolas.dufre...@collabora.com>
> Signed-off-by: Hans Verkuil <hverk...@xs4all.nl>

Patch committed.

Thanks,
Hans Verkuil

 drivers/staging/media/rkvdec/rkvdec-h264.c | 37 ++++++++++++++++++++++-------
 drivers/staging/media/rkvdec/rkvdec.c      | 38 +++++++++++++++++++++++-------
 drivers/staging/media/rkvdec/rkvdec.h      |  3 +++
 3 files changed, 60 insertions(+), 18 deletions(-)

---

diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c 
b/drivers/staging/media/rkvdec/rkvdec-h264.c
index 8bce8902b8dd..d14b4d173448 100644
--- a/drivers/staging/media/rkvdec/rkvdec-h264.c
+++ b/drivers/staging/media/rkvdec/rkvdec-h264.c
@@ -1027,24 +1027,42 @@ static int rkvdec_h264_adjust_fmt(struct rkvdec_ctx 
*ctx,
        return 0;
 }
 
+static enum rkvdec_image_fmt rkvdec_h264_get_image_fmt(struct rkvdec_ctx *ctx,
+                                                      struct v4l2_ctrl *ctrl)
+{
+       const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p_h264_sps;
+
+       if (ctrl->id != V4L2_CID_STATELESS_H264_SPS)
+               return RKVDEC_IMG_FMT_ANY;
+
+       if (sps->bit_depth_luma_minus8 == 0) {
+               if (sps->chroma_format_idc == 2)
+                       return RKVDEC_IMG_FMT_422_8BIT;
+               else
+                       return RKVDEC_IMG_FMT_420_8BIT;
+       } else if (sps->bit_depth_luma_minus8 == 2) {
+               if (sps->chroma_format_idc == 2)
+                       return RKVDEC_IMG_FMT_422_10BIT;
+               else
+                       return RKVDEC_IMG_FMT_420_10BIT;
+       }
+
+       return RKVDEC_IMG_FMT_ANY;
+}
+
 static int rkvdec_h264_validate_sps(struct rkvdec_ctx *ctx,
                                    const struct v4l2_ctrl_h264_sps *sps)
 {
        unsigned int width, height;
 
-       /*
-        * TODO: The hardware supports 10-bit and 4:2:2 profiles,
-        * but it's currently broken in the driver.
-        * Reject them for now, until it's fixed.
-        */
-       if (sps->chroma_format_idc > 1)
-               /* Only 4:0:0 and 4:2:0 are supported */
+       if (sps->chroma_format_idc > 2)
+               /* Only 4:0:0, 4:2:0 and 4:2:2 are 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 */
+       if (sps->bit_depth_luma_minus8 != 0 && sps->bit_depth_luma_minus8 != 2)
+               /* Only 8-bit and 10-bit is supported */
                return -EINVAL;
 
        width = (sps->pic_width_in_mbs_minus1 + 1) * 16;
@@ -1190,4 +1208,5 @@ const struct rkvdec_coded_fmt_ops rkvdec_h264_fmt_ops = {
        .stop = rkvdec_h264_stop,
        .run = rkvdec_h264_run,
        .try_ctrl = rkvdec_h264_try_ctrl,
+       .get_image_fmt = rkvdec_h264_get_image_fmt,
 };
diff --git a/drivers/staging/media/rkvdec/rkvdec.c 
b/drivers/staging/media/rkvdec/rkvdec.c
index f7eb67520ab0..3367902f22de 100644
--- a/drivers/staging/media/rkvdec/rkvdec.c
+++ b/drivers/staging/media/rkvdec/rkvdec.c
@@ -186,9 +186,10 @@ static const struct rkvdec_ctrl_desc 
rkvdec_h264_ctrl_descs[] = {
        {
                .cfg.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE,
                .cfg.min = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE,
-               .cfg.max = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
+               .cfg.max = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA,
                .cfg.menu_skip_mask =
-                       BIT(V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED),
+                       BIT(V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED) |
+                       BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE),
                .cfg.def = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN,
        },
        {
@@ -203,11 +204,23 @@ static const struct rkvdec_ctrls rkvdec_h264_ctrls = {
        .num_ctrls = ARRAY_SIZE(rkvdec_h264_ctrl_descs),
 };
 
-static const struct rkvdec_decoded_fmt_desc rkvdec_h264_vp9_decoded_fmts[] = {
+static const struct rkvdec_decoded_fmt_desc rkvdec_h264_decoded_fmts[] = {
        {
                .fourcc = V4L2_PIX_FMT_NV12,
                .image_fmt = RKVDEC_IMG_FMT_420_8BIT,
        },
+       {
+               .fourcc = V4L2_PIX_FMT_NV15,
+               .image_fmt = RKVDEC_IMG_FMT_420_10BIT,
+       },
+       {
+               .fourcc = V4L2_PIX_FMT_NV16,
+               .image_fmt = RKVDEC_IMG_FMT_422_8BIT,
+       },
+       {
+               .fourcc = V4L2_PIX_FMT_NV20,
+               .image_fmt = RKVDEC_IMG_FMT_422_10BIT,
+       },
 };
 
 static const struct rkvdec_ctrl_desc rkvdec_vp9_ctrl_descs[] = {
@@ -230,21 +243,28 @@ static const struct rkvdec_ctrls rkvdec_vp9_ctrls = {
        .num_ctrls = ARRAY_SIZE(rkvdec_vp9_ctrl_descs),
 };
 
+static const struct rkvdec_decoded_fmt_desc rkvdec_vp9_decoded_fmts[] = {
+       {
+               .fourcc = V4L2_PIX_FMT_NV12,
+               .image_fmt = RKVDEC_IMG_FMT_420_8BIT,
+       },
+};
+
 static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = {
        {
                .fourcc = V4L2_PIX_FMT_H264_SLICE,
                .frmsize = {
-                       .min_width = 48,
+                       .min_width = 64,
                        .max_width = 4096,
-                       .step_width = 16,
+                       .step_width = 64,
                        .min_height = 48,
                        .max_height = 2560,
                        .step_height = 16,
                },
                .ctrls = &rkvdec_h264_ctrls,
                .ops = &rkvdec_h264_fmt_ops,
-               .num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_vp9_decoded_fmts),
-               .decoded_fmts = rkvdec_h264_vp9_decoded_fmts,
+               .num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_decoded_fmts),
+               .decoded_fmts = rkvdec_h264_decoded_fmts,
                .subsystem_flags = VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF,
        },
        {
@@ -259,8 +279,8 @@ static const struct rkvdec_coded_fmt_desc 
rkvdec_coded_fmts[] = {
                },
                .ctrls = &rkvdec_vp9_ctrls,
                .ops = &rkvdec_vp9_fmt_ops,
-               .num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_vp9_decoded_fmts),
-               .decoded_fmts = rkvdec_h264_vp9_decoded_fmts,
+               .num_decoded_fmts = ARRAY_SIZE(rkvdec_vp9_decoded_fmts),
+               .decoded_fmts = rkvdec_vp9_decoded_fmts,
        }
 };
 
diff --git a/drivers/staging/media/rkvdec/rkvdec.h 
b/drivers/staging/media/rkvdec/rkvdec.h
index e466a2753ccf..9a9f4fced7a1 100644
--- a/drivers/staging/media/rkvdec/rkvdec.h
+++ b/drivers/staging/media/rkvdec/rkvdec.h
@@ -80,6 +80,9 @@ struct rkvdec_coded_fmt_ops {
 enum rkvdec_image_fmt {
        RKVDEC_IMG_FMT_ANY = 0,
        RKVDEC_IMG_FMT_420_8BIT,
+       RKVDEC_IMG_FMT_420_10BIT,
+       RKVDEC_IMG_FMT_422_8BIT,
+       RKVDEC_IMG_FMT_422_10BIT,
 };
 
 struct rkvdec_decoded_fmt_desc {

Reply via email to