On Fri Jan 9 11:15:23 2026 -0500, Detlev Casanova wrote:
> This is a preparation commit to add support for new variants of the
> decoder.
> 
> The functions will later be shared with vdpu381 (rk3588) and vdpu383
> (rk3576).
> 
> Tested-by: Diederik de Haas <[email protected]>  # Rock 5B
> Reviewed-by: Nicolas Dufresne <[email protected]>
> Signed-off-by: Detlev Casanova <[email protected]>
> Signed-off-by: Nicolas Dufresne <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>

Patch committed.

Thanks,
Hans Verkuil

 drivers/media/platform/rockchip/rkvdec/Makefile    |   1 +
 .../platform/rockchip/rkvdec/rkvdec-h264-common.c  | 258 +++++++++++++++++
 .../platform/rockchip/rkvdec/rkvdec-h264-common.h  |  85 ++++++
 .../media/platform/rockchip/rkvdec/rkvdec-h264.c   | 308 +--------------------
 4 files changed, 348 insertions(+), 304 deletions(-)

---

diff --git a/drivers/media/platform/rockchip/rkvdec/Makefile 
b/drivers/media/platform/rockchip/rkvdec/Makefile
index a8ff5e3d7bec..d2ba7a7c15e5 100644
--- a/drivers/media/platform/rockchip/rkvdec/Makefile
+++ b/drivers/media/platform/rockchip/rkvdec/Makefile
@@ -4,5 +4,6 @@ rockchip-vdec-y += \
                   rkvdec.o \
                   rkvdec-cabac.o \
                   rkvdec-h264.o \
+                  rkvdec-h264-common.o \
                   rkvdec-hevc.o \
                   rkvdec-vp9.o
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.c 
b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.c
new file mode 100644
index 000000000000..e28f06394470
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.c
@@ -0,0 +1,258 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip video decoder h264 common functions
+ *
+ * Copyright (C) 2025 Collabora, Ltd.
+ *     Detlev Casanova <[email protected]>
+ *
+ * Copyright (C) 2019 Collabora, Ltd.
+ *     Boris Brezillon <[email protected]>
+ *
+ * Copyright (C) 2016 Rockchip Electronics Co., Ltd.
+ *     Jeffy Chen <[email protected]>
+ */
+
+#include <linux/v4l2-common.h>
+#include <media/v4l2-h264.h>
+#include <media/v4l2-mem2mem.h>
+
+#include "rkvdec.h"
+#include "rkvdec-h264-common.h"
+
+#define RKVDEC_NUM_REFLIST             3
+
+static void set_dpb_info(struct rkvdec_rps_entry *entries,
+                        u8 reflist,
+                        u8 refnum,
+                        u8 info,
+                        bool bottom)
+{
+       struct rkvdec_rps_entry *entry = &entries[(reflist * 4) + refnum / 8];
+       u8 idx = refnum % 8;
+
+       switch (idx) {
+       case 0:
+               entry->dpb_info0 = info;
+               entry->bottom_flag0 = bottom;
+               break;
+       case 1:
+               entry->dpb_info1 = info;
+               entry->bottom_flag1 = bottom;
+               break;
+       case 2:
+               entry->dpb_info2 = info;
+               entry->bottom_flag2 = bottom;
+               break;
+       case 3:
+               entry->dpb_info3 = info;
+               entry->bottom_flag3 = bottom;
+               break;
+       case 4:
+               entry->dpb_info4 = info;
+               entry->bottom_flag4 = bottom;
+               break;
+       case 5:
+               entry->dpb_info5 = info;
+               entry->bottom_flag5 = bottom;
+               break;
+       case 6:
+               entry->dpb_info6 = info;
+               entry->bottom_flag6 = bottom;
+               break;
+       case 7:
+               entry->dpb_info7 = info;
+               entry->bottom_flag7 = bottom;
+               break;
+       }
+}
+
+void lookup_ref_buf_idx(struct rkvdec_ctx *ctx,
+                       struct rkvdec_h264_run *run)
+{
+       const struct v4l2_ctrl_h264_decode_params *dec_params = 
run->decode_params;
+       u32 i;
+
+       for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
+               struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
+               const struct v4l2_h264_dpb_entry *dpb = run->decode_params->dpb;
+               struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q;
+               struct vb2_buffer *buf = NULL;
+
+               if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) {
+                       buf = vb2_find_buffer(cap_q, dpb[i].reference_ts);
+                       if (!buf)
+                               pr_debug("No buffer for reference_ts %llu",
+                                        dpb[i].reference_ts);
+               }
+
+               run->ref_buf[i] = buf;
+       }
+}
+
+void assemble_hw_rps(struct v4l2_h264_reflist_builder *builder,
+                    struct rkvdec_h264_run *run,
+                    struct rkvdec_h264_reflists *reflists,
+                    struct rkvdec_rps *hw_rps)
+{
+       const struct v4l2_ctrl_h264_decode_params *dec_params = 
run->decode_params;
+       const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb;
+
+       u32 i, j;
+
+       memset(hw_rps, 0, sizeof(*hw_rps));
+
+       /*
+        * Assign an invalid pic_num if DPB entry at that position is inactive.
+        * If we assign 0 in that position hardware will treat that as a real
+        * reference picture with pic_num 0, triggering output picture
+        * corruption.
+        */
+       for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
+               if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
+                       continue;
+
+               hw_rps->frame_num[i] = builder->refs[i].frame_num;
+       }
+
+       for (j = 0; j < RKVDEC_NUM_REFLIST; j++) {
+               for (i = 0; i < builder->num_valid; i++) {
+                       struct v4l2_h264_reference *ref;
+                       bool dpb_valid;
+                       bool bottom;
+
+                       switch (j) {
+                       case 0:
+                               ref = &reflists->p[i];
+                               break;
+                       case 1:
+                               ref = &reflists->b0[i];
+                               break;
+                       case 2:
+                               ref = &reflists->b1[i];
+                               break;
+                       }
+
+                       if (WARN_ON(ref->index >= ARRAY_SIZE(dec_params->dpb)))
+                               continue;
+
+                       dpb_valid = !!(run->ref_buf[ref->index]);
+                       bottom = ref->fields == V4L2_H264_BOTTOM_FIELD_REF;
+
+                       set_dpb_info(hw_rps->entries, j, i, ref->index | 
(dpb_valid << 4), bottom);
+               }
+       }
+}
+
+void assemble_hw_scaling_list(struct rkvdec_h264_run *run,
+                             struct rkvdec_h264_scaling_list *scaling_list)
+{
+       const struct v4l2_ctrl_h264_scaling_matrix *scaling = 
run->scaling_matrix;
+       const struct v4l2_ctrl_h264_pps *pps = run->pps;
+
+       if (!(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT))
+               return;
+
+       BUILD_BUG_ON(sizeof(scaling_list->scaling_list_4x4) !=
+                    sizeof(scaling->scaling_list_4x4));
+       BUILD_BUG_ON(sizeof(scaling_list->scaling_list_8x8) !=
+                    sizeof(scaling->scaling_list_8x8));
+
+       memcpy(scaling_list->scaling_list_4x4,
+              scaling->scaling_list_4x4,
+              sizeof(scaling->scaling_list_4x4));
+
+       memcpy(scaling_list->scaling_list_8x8,
+              scaling->scaling_list_8x8,
+              sizeof(scaling->scaling_list_8x8));
+}
+
+#define RKVDEC_H264_MAX_DEPTH_IN_BYTES         2
+
+int rkvdec_h264_adjust_fmt(struct rkvdec_ctx *ctx,
+                          struct v4l2_format *f)
+{
+       struct v4l2_pix_format_mplane *fmt = &f->fmt.pix_mp;
+
+       fmt->num_planes = 1;
+       if (!fmt->plane_fmt[0].sizeimage)
+               fmt->plane_fmt[0].sizeimage = fmt->width * fmt->height *
+                                             RKVDEC_H264_MAX_DEPTH_IN_BYTES;
+       return 0;
+}
+
+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;
+}
+
+int rkvdec_h264_validate_sps(struct rkvdec_ctx *ctx,
+                            const struct v4l2_ctrl_h264_sps *sps)
+{
+       unsigned int width, height;
+
+       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 && 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;
+       height = (sps->pic_height_in_map_units_minus1 + 1) * 16;
+
+       /*
+        * When frame_mbs_only_flag is not set, this is field height,
+        * which is half the final height (see (7-18) in the
+        * specification)
+        */
+       if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY))
+               height *= 2;
+
+       if (width > ctx->coded_fmt.fmt.pix_mp.width ||
+           height > ctx->coded_fmt.fmt.pix_mp.height)
+               return -EINVAL;
+
+       return 0;
+}
+
+void rkvdec_h264_run_preamble(struct rkvdec_ctx *ctx,
+                             struct rkvdec_h264_run *run)
+{
+       struct v4l2_ctrl *ctrl;
+
+       ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
+                             V4L2_CID_STATELESS_H264_DECODE_PARAMS);
+       run->decode_params = ctrl ? ctrl->p_cur.p : NULL;
+       ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
+                             V4L2_CID_STATELESS_H264_SPS);
+       run->sps = ctrl ? ctrl->p_cur.p : NULL;
+       ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
+                             V4L2_CID_STATELESS_H264_PPS);
+       run->pps = ctrl ? ctrl->p_cur.p : NULL;
+       ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
+                             V4L2_CID_STATELESS_H264_SCALING_MATRIX);
+       run->scaling_matrix = ctrl ? ctrl->p_cur.p : NULL;
+
+       rkvdec_run_preamble(ctx, &run->base);
+}
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h 
b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h
new file mode 100644
index 000000000000..5336370507d6
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Rockchip video decoder h264 common functions
+ *
+ * Copyright (C) 2025 Collabora, Ltd.
+ *     Detlev Casanova <[email protected]>
+ *
+ * Copyright (C) 2019 Collabora, Ltd.
+ *     Boris Brezillon <[email protected]>
+ *
+ * Copyright (C) 2016 Rockchip Electronics Co., Ltd.
+ *     Jeffy Chen <[email protected]>
+ */
+
+#include <media/v4l2-h264.h>
+#include <media/v4l2-mem2mem.h>
+
+#include "rkvdec.h"
+
+struct rkvdec_h264_scaling_list {
+       u8 scaling_list_4x4[6][16];
+       u8 scaling_list_8x8[6][64];
+       u8 padding[128];
+};
+
+struct rkvdec_h264_reflists {
+       struct v4l2_h264_reference p[V4L2_H264_REF_LIST_LEN];
+       struct v4l2_h264_reference b0[V4L2_H264_REF_LIST_LEN];
+       struct v4l2_h264_reference b1[V4L2_H264_REF_LIST_LEN];
+};
+
+struct rkvdec_h264_run {
+       struct rkvdec_run base;
+       const struct v4l2_ctrl_h264_decode_params *decode_params;
+       const struct v4l2_ctrl_h264_sps *sps;
+       const struct v4l2_ctrl_h264_pps *pps;
+       const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix;
+       struct vb2_buffer *ref_buf[V4L2_H264_NUM_DPB_ENTRIES];
+};
+
+struct rkvdec_rps_entry {
+       u32 dpb_info0:          5;
+       u32 bottom_flag0:       1;
+       u32 view_index_off0:    1;
+       u32 dpb_info1:          5;
+       u32 bottom_flag1:       1;
+       u32 view_index_off1:    1;
+       u32 dpb_info2:          5;
+       u32 bottom_flag2:       1;
+       u32 view_index_off2:    1;
+       u32 dpb_info3:          5;
+       u32 bottom_flag3:       1;
+       u32 view_index_off3:    1;
+       u32 dpb_info4:          5;
+       u32 bottom_flag4:       1;
+       u32 view_index_off4:    1;
+       u32 dpb_info5:          5;
+       u32 bottom_flag5:       1;
+       u32 view_index_off5:    1;
+       u32 dpb_info6:          5;
+       u32 bottom_flag6:       1;
+       u32 view_index_off6:    1;
+       u32 dpb_info7:          5;
+       u32 bottom_flag7:       1;
+       u32 view_index_off7:    1;
+} __packed;
+
+struct rkvdec_rps {
+       u16 frame_num[16];
+       u32 reserved0;
+       struct rkvdec_rps_entry entries[12];
+       u32 reserved1[66];
+} __packed;
+
+void lookup_ref_buf_idx(struct rkvdec_ctx *ctx, struct rkvdec_h264_run *run);
+void assemble_hw_rps(struct v4l2_h264_reflist_builder *builder,
+                    struct rkvdec_h264_run *run,
+                    struct rkvdec_h264_reflists *reflists,
+                    struct rkvdec_rps *hw_rps);
+void assemble_hw_scaling_list(struct rkvdec_h264_run *run,
+                             struct rkvdec_h264_scaling_list *scaling_list);
+int rkvdec_h264_adjust_fmt(struct rkvdec_ctx *ctx, struct v4l2_format *f);
+enum rkvdec_image_fmt rkvdec_h264_get_image_fmt(struct rkvdec_ctx *ctx, struct 
v4l2_ctrl *ctrl);
+int rkvdec_h264_validate_sps(struct rkvdec_ctx *ctx, const struct 
v4l2_ctrl_h264_sps *sps);
+void rkvdec_h264_run_preamble(struct rkvdec_ctx *ctx, struct rkvdec_h264_run 
*run);
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c 
b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
index d1d19dd6167b..a1af12c97914 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
@@ -15,57 +15,16 @@
 #include "rkvdec.h"
 #include "rkvdec-regs.h"
 #include "rkvdec-cabac.h"
+#include "rkvdec-h264-common.h"
 
 /* Size with u32 units. */
 #define RKV_CABAC_INIT_BUFFER_SIZE     (3680 + 128)
 #define RKV_ERROR_INFO_SIZE            (256 * 144 * 4)
 
-#define RKVDEC_NUM_REFLIST             3
-
-struct rkvdec_h264_scaling_list {
-       u8 scaling_list_4x4[6][16];
-       u8 scaling_list_8x8[6][64];
-       u8 padding[128];
-};
-
 struct rkvdec_sps_pps_packet {
        u32 info[8];
 };
 
-struct rkvdec_rps_entry {
-       u32 dpb_info0:          5;
-       u32 bottom_flag0:       1;
-       u32 view_index_off0:    1;
-       u32 dpb_info1:          5;
-       u32 bottom_flag1:       1;
-       u32 view_index_off1:    1;
-       u32 dpb_info2:          5;
-       u32 bottom_flag2:       1;
-       u32 view_index_off2:    1;
-       u32 dpb_info3:          5;
-       u32 bottom_flag3:       1;
-       u32 view_index_off3:    1;
-       u32 dpb_info4:          5;
-       u32 bottom_flag4:       1;
-       u32 view_index_off4:    1;
-       u32 dpb_info5:          5;
-       u32 bottom_flag5:       1;
-       u32 view_index_off5:    1;
-       u32 dpb_info6:          5;
-       u32 bottom_flag6:       1;
-       u32 view_index_off6:    1;
-       u32 dpb_info7:          5;
-       u32 bottom_flag7:       1;
-       u32 view_index_off7:    1;
-} __packed;
-
-struct rkvdec_rps {
-       u16 frame_num[16];
-       u32 reserved0;
-       struct rkvdec_rps_entry entries[12];
-       u32 reserved1[66];
-} __packed;
-
 struct rkvdec_ps_field {
        u16 offset;
        u8 len;
@@ -117,11 +76,6 @@ struct rkvdec_ps_field {
 #define SCALING_LIST_ADDRESS                           PS_FIELD(184, 32)
 #define IS_LONG_TERM(i)                                PS_FIELD(216 + (i), 1)
 
-#define DPB_OFFS(i, j)                                 (288 + ((j) * 32 * 7) + 
((i) * 7))
-#define DPB_INFO(i, j)                                 PS_FIELD(DPB_OFFS(i, 
j), 5)
-#define BOTTOM_FLAG(i, j)                              PS_FIELD(DPB_OFFS(i, j) 
+ 5, 1)
-#define VIEW_INDEX_OFF(i, j)                           PS_FIELD(DPB_OFFS(i, j) 
+ 6, 1)
-
 /* Data structure describing auxiliary buffer format. */
 struct rkvdec_h264_priv_tbl {
        s8 cabac_table[4][464][2];
@@ -131,21 +85,6 @@ struct rkvdec_h264_priv_tbl {
        u8 err_info[RKV_ERROR_INFO_SIZE];
 };
 
-struct rkvdec_h264_reflists {
-       struct v4l2_h264_reference p[V4L2_H264_REF_LIST_LEN];
-       struct v4l2_h264_reference b0[V4L2_H264_REF_LIST_LEN];
-       struct v4l2_h264_reference b1[V4L2_H264_REF_LIST_LEN];
-};
-
-struct rkvdec_h264_run {
-       struct rkvdec_run base;
-       const struct v4l2_ctrl_h264_decode_params *decode_params;
-       const struct v4l2_ctrl_h264_sps *sps;
-       const struct v4l2_ctrl_h264_pps *pps;
-       const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix;
-       struct vb2_buffer *ref_buf[V4L2_H264_NUM_DPB_ENTRIES];
-};
-
 struct rkvdec_h264_ctx {
        struct rkvdec_aux_buf priv_tbl;
        struct rkvdec_h264_reflists reflists;
@@ -269,155 +208,6 @@ static void assemble_hw_pps(struct rkvdec_ctx *ctx,
        }
 }
 
-static void lookup_ref_buf_idx(struct rkvdec_ctx *ctx,
-                              struct rkvdec_h264_run *run)
-{
-       const struct v4l2_ctrl_h264_decode_params *dec_params = 
run->decode_params;
-       u32 i;
-
-       for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
-               struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
-               const struct v4l2_h264_dpb_entry *dpb = run->decode_params->dpb;
-               struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q;
-               struct vb2_buffer *buf = NULL;
-
-               if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) {
-                       buf = vb2_find_buffer(cap_q, dpb[i].reference_ts);
-                       if (!buf)
-                               pr_debug("No buffer for reference_ts %llu",
-                                        dpb[i].reference_ts);
-               }
-
-               run->ref_buf[i] = buf;
-       }
-}
-
-static void set_dpb_info(struct rkvdec_rps_entry *entries,
-                        u8 reflist,
-                        u8 refnum,
-                        u8 info,
-                        bool bottom)
-{
-       struct rkvdec_rps_entry *entry = &entries[(reflist * 4) + refnum / 8];
-       u8 idx = refnum % 8;
-
-       switch (idx) {
-       case 0:
-               entry->dpb_info0 = info;
-               entry->bottom_flag0 = bottom;
-               break;
-       case 1:
-               entry->dpb_info1 = info;
-               entry->bottom_flag1 = bottom;
-               break;
-       case 2:
-               entry->dpb_info2 = info;
-               entry->bottom_flag2 = bottom;
-               break;
-       case 3:
-               entry->dpb_info3 = info;
-               entry->bottom_flag3 = bottom;
-               break;
-       case 4:
-               entry->dpb_info4 = info;
-               entry->bottom_flag4 = bottom;
-               break;
-       case 5:
-               entry->dpb_info5 = info;
-               entry->bottom_flag5 = bottom;
-               break;
-       case 6:
-               entry->dpb_info6 = info;
-               entry->bottom_flag6 = bottom;
-               break;
-       case 7:
-               entry->dpb_info7 = info;
-               entry->bottom_flag7 = bottom;
-               break;
-       }
-}
-
-static void assemble_hw_rps(struct rkvdec_ctx *ctx,
-                           struct v4l2_h264_reflist_builder *builder,
-                           struct rkvdec_h264_run *run)
-{
-       const struct v4l2_ctrl_h264_decode_params *dec_params = 
run->decode_params;
-       const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb;
-       struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
-       struct rkvdec_h264_priv_tbl *priv_tbl = h264_ctx->priv_tbl.cpu;
-
-       struct rkvdec_rps *hw_rps = &priv_tbl->rps;
-       u32 i, j;
-
-       memset(hw_rps, 0, sizeof(*hw_rps));
-
-       /*
-        * Assign an invalid pic_num if DPB entry at that position is inactive.
-        * If we assign 0 in that position hardware will treat that as a real
-        * reference picture with pic_num 0, triggering output picture
-        * corruption.
-        */
-       for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
-               if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
-                       continue;
-
-               hw_rps->frame_num[i] = builder->refs[i].frame_num;
-       }
-
-       for (j = 0; j < RKVDEC_NUM_REFLIST; j++) {
-               for (i = 0; i < builder->num_valid; i++) {
-                       struct v4l2_h264_reference *ref;
-                       bool dpb_valid;
-                       bool bottom;
-
-                       switch (j) {
-                       case 0:
-                               ref = &h264_ctx->reflists.p[i];
-                               break;
-                       case 1:
-                               ref = &h264_ctx->reflists.b0[i];
-                               break;
-                       case 2:
-                               ref = &h264_ctx->reflists.b1[i];
-                               break;
-                       }
-
-                       if (WARN_ON(ref->index >= ARRAY_SIZE(dec_params->dpb)))
-                               continue;
-
-                       dpb_valid = run->ref_buf[ref->index] != NULL;
-                       bottom = ref->fields == V4L2_H264_BOTTOM_FIELD_REF;
-
-                       set_dpb_info(hw_rps->entries, j, i, ref->index | 
(dpb_valid << 4), bottom);
-               }
-       }
-}
-
-static void assemble_hw_scaling_list(struct rkvdec_ctx *ctx,
-                                    struct rkvdec_h264_run *run)
-{
-       const struct v4l2_ctrl_h264_scaling_matrix *scaling = 
run->scaling_matrix;
-       const struct v4l2_ctrl_h264_pps *pps = run->pps;
-       struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
-       struct rkvdec_h264_priv_tbl *tbl = h264_ctx->priv_tbl.cpu;
-
-       if (!(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT))
-               return;
-
-       BUILD_BUG_ON(sizeof(tbl->scaling_list.scaling_list_4x4) !=
-                    sizeof(scaling->scaling_list_4x4));
-       BUILD_BUG_ON(sizeof(tbl->scaling_list.scaling_list_8x8) !=
-                    sizeof(scaling->scaling_list_8x8));
-
-       memcpy(tbl->scaling_list.scaling_list_4x4,
-              scaling->scaling_list_4x4,
-              sizeof(scaling->scaling_list_4x4));
-
-       memcpy(tbl->scaling_list.scaling_list_8x8,
-              scaling->scaling_list_8x8,
-              sizeof(scaling->scaling_list_8x8));
-}
-
 /*
  * Set the ref POC in the correct register.
  *
@@ -568,76 +358,6 @@ static void config_registers(struct rkvdec_ctx *ctx,
                           MIN(sizeof(*regs), sizeof(u32) * 
rkvdec->variant->num_regs));
 }
 
-#define RKVDEC_H264_MAX_DEPTH_IN_BYTES         2
-
-static int rkvdec_h264_adjust_fmt(struct rkvdec_ctx *ctx,
-                                 struct v4l2_format *f)
-{
-       struct v4l2_pix_format_mplane *fmt = &f->fmt.pix_mp;
-
-       fmt->num_planes = 1;
-       if (!fmt->plane_fmt[0].sizeimage)
-               fmt->plane_fmt[0].sizeimage = fmt->width * fmt->height *
-                                             RKVDEC_H264_MAX_DEPTH_IN_BYTES;
-       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;
-
-       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 && 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;
-       height = (sps->pic_height_in_map_units_minus1 + 1) * 16;
-
-       /*
-        * When frame_mbs_only_flag is not set, this is field height,
-        * which is half the final height (see (7-18) in the
-        * specification)
-        */
-       if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY))
-               height *= 2;
-
-       if (width > ctx->coded_fmt.fmt.pix_mp.width ||
-           height > ctx->coded_fmt.fmt.pix_mp.height)
-               return -EINVAL;
-
-       return 0;
-}
-
 static int rkvdec_h264_start(struct rkvdec_ctx *ctx)
 {
        struct rkvdec_dev *rkvdec = ctx->dev;
@@ -689,33 +409,13 @@ static void rkvdec_h264_stop(struct rkvdec_ctx *ctx)
        kfree(h264_ctx);
 }
 
-static void rkvdec_h264_run_preamble(struct rkvdec_ctx *ctx,
-                                    struct rkvdec_h264_run *run)
-{
-       struct v4l2_ctrl *ctrl;
-
-       ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
-                             V4L2_CID_STATELESS_H264_DECODE_PARAMS);
-       run->decode_params = ctrl ? ctrl->p_cur.p : NULL;
-       ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
-                             V4L2_CID_STATELESS_H264_SPS);
-       run->sps = ctrl ? ctrl->p_cur.p : NULL;
-       ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
-                             V4L2_CID_STATELESS_H264_PPS);
-       run->pps = ctrl ? ctrl->p_cur.p : NULL;
-       ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
-                             V4L2_CID_STATELESS_H264_SCALING_MATRIX);
-       run->scaling_matrix = ctrl ? ctrl->p_cur.p : NULL;
-
-       rkvdec_run_preamble(ctx, &run->base);
-}
-
 static int rkvdec_h264_run(struct rkvdec_ctx *ctx)
 {
        struct v4l2_h264_reflist_builder reflist_builder;
        struct rkvdec_dev *rkvdec = ctx->dev;
        struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
        struct rkvdec_h264_run run;
+       struct rkvdec_h264_priv_tbl *tbl = h264_ctx->priv_tbl.cpu;
 
        rkvdec_h264_run_preamble(ctx, &run);
 
@@ -726,10 +426,10 @@ static int rkvdec_h264_run(struct rkvdec_ctx *ctx)
        v4l2_h264_build_b_ref_lists(&reflist_builder, h264_ctx->reflists.b0,
                                    h264_ctx->reflists.b1);
 
-       assemble_hw_scaling_list(ctx, &run);
+       assemble_hw_scaling_list(&run, &tbl->scaling_list);
        assemble_hw_pps(ctx, &run);
        lookup_ref_buf_idx(ctx, &run);
-       assemble_hw_rps(ctx, &reflist_builder, &run);
+       assemble_hw_rps(&reflist_builder, &run, &h264_ctx->reflists, &tbl->rps);
        config_registers(ctx, &run);
 
        rkvdec_run_postamble(ctx, &run.base);
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to