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 on 10-bit format buffers.

The new valid_fmt operation is implemented and return a valid pixelformat
for the provided SPS control.

Signed-off-by: Jonas Karlman <jo...@kwiboo.se>
---
Changes in v2:
- Only align decoded buffer instead of using frmsize step_width
---
 drivers/staging/media/rkvdec/rkvdec-h264.c | 20 ++++++++++++++++++++
 drivers/staging/media/rkvdec/rkvdec.c      | 19 +++++++++----------
 2 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c 
b/drivers/staging/media/rkvdec/rkvdec-h264.c
index 10756b9d6118..0757fc97d1ff 100644
--- a/drivers/staging/media/rkvdec/rkvdec-h264.c
+++ b/drivers/staging/media/rkvdec/rkvdec-h264.c
@@ -1018,6 +1018,25 @@ static int rkvdec_h264_adjust_fmt(struct rkvdec_ctx *ctx,
        return 0;
 }
 
+static u32 rkvdec_h264_valid_fmt(struct rkvdec_ctx *ctx, struct v4l2_ctrl 
*ctrl)
+{
+       const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p;
+
+       if (sps->bit_depth_luma_minus8 == 0) {
+               if (sps->chroma_format_idc == 2)
+                       return V4L2_PIX_FMT_NV16;
+               else
+                       return V4L2_PIX_FMT_NV12;
+       } else if (sps->bit_depth_luma_minus8 == 2) {
+               if (sps->chroma_format_idc == 2)
+                       return V4L2_PIX_FMT_NV20;
+               else
+                       return V4L2_PIX_FMT_NV15;
+       }
+
+       return 0;
+}
+
 static int rkvdec_h264_start(struct rkvdec_ctx *ctx)
 {
        struct rkvdec_dev *rkvdec = ctx->dev;
@@ -1125,6 +1144,7 @@ static int rkvdec_h264_run(struct rkvdec_ctx *ctx)
 
 const struct rkvdec_coded_fmt_ops rkvdec_h264_fmt_ops = {
        .adjust_fmt = rkvdec_h264_adjust_fmt,
+       .valid_fmt = rkvdec_h264_valid_fmt,
        .start = rkvdec_h264_start,
        .stop = rkvdec_h264_stop,
        .run = rkvdec_h264_run,
diff --git a/drivers/staging/media/rkvdec/rkvdec.c 
b/drivers/staging/media/rkvdec/rkvdec.c
index 11a88cb6407d..4faee9262392 100644
--- a/drivers/staging/media/rkvdec/rkvdec.c
+++ b/drivers/staging/media/rkvdec/rkvdec.c
@@ -31,7 +31,7 @@ static void rkvdec_fill_decoded_pixfmt(struct rkvdec_ctx *ctx,
                                       struct v4l2_pix_format_mplane *pix_mp)
 {
        v4l2_fill_pixfmt_mp(pix_mp, pix_mp->pixelformat,
-                           pix_mp->width, pix_mp->height);
+                           ALIGN(pix_mp->width, 64), pix_mp->height);
        pix_mp->plane_fmt[0].sizeimage += 128 *
                DIV_ROUND_UP(pix_mp->width, 16) *
                DIV_ROUND_UP(pix_mp->height, 16);
@@ -55,19 +55,15 @@ static int rkvdec_try_ctrl(struct v4l2_ctrl *ctrl)
        if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_SPS) {
                const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p;
                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;
 
                if (ctx->valid_fmt && ctx->valid_fmt != rkvdec_valid_fmt(ctx, 
ctrl))
@@ -157,6 +153,9 @@ static const struct rkvdec_ctrls rkvdec_h264_ctrls = {
 
 static const u32 rkvdec_h264_decoded_fmts[] = {
        V4L2_PIX_FMT_NV12,
+       V4L2_PIX_FMT_NV15,
+       V4L2_PIX_FMT_NV16,
+       V4L2_PIX_FMT_NV20,
 };
 
 static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = {
-- 
2.17.1

Reply via email to