/* Size with u32 units. */
#define RKV_CABAC_INIT_BUFFER_SIZE (3680 + 128)
-#define RKV_RPS_SIZE ((128 + 128) / 4)
#define RKV_ERROR_INFO_SIZE (256 * 144 * 4)
#define RKVDEC_NUM_REFLIST 3
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;
struct rkvdec_h264_priv_tbl {
s8 cabac_table[4][464][2];
struct rkvdec_h264_scaling_list scaling_list;
- u32 rps[RKV_RPS_SIZE];
+ struct rkvdec_rps rps;
struct rkvdec_sps_pps_packet param_set[256];
u8 err_info[RKV_ERROR_INFO_SIZE];
};
}
}
+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)
struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
struct rkvdec_h264_priv_tbl *priv_tbl = h264_ctx->priv_tbl.cpu;
- u32 *hw_rps = priv_tbl->rps;
+ struct rkvdec_rps *hw_rps = &priv_tbl->rps;
u32 i, j;
- u16 *p = (u16 *)hw_rps;
- memset(hw_rps, 0, sizeof(priv_tbl->rps));
+ memset(hw_rps, 0, sizeof(*hw_rps));
/*
* Assign an invalid pic_num if DPB entry at that position is inactive.
if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
continue;
- p[i] = builder->refs[i].frame_num;
+ hw_rps->frame_num[i] = builder->refs[i].frame_num;
}
for (j = 0; j < RKVDEC_NUM_REFLIST; j++) {
dpb_valid = run->ref_buf[ref->index] != NULL;
bottom = ref->fields == V4L2_H264_BOTTOM_FIELD_REF;
- set_ps_field(hw_rps, DPB_INFO(i, j),
- ref->index | dpb_valid << 4);
- set_ps_field(hw_rps, BOTTOM_FLAG(i, j), bottom);
+ set_dpb_info(hw_rps->entries, j, i, ref->index | (dpb_valid << 4), bottom);
}
}
}