Skip to content

Commit 6f32ea3

Browse files
ndufresnemchehab
authored andcommitted
media: rkvdec-h264: Add field decoding support
This makes use of the new feature in the reference builder to program up to 32 references when doing field decoding. It also signals the parity (top or bottom) of the field to the hardware. Signed-off-by: Nicolas Dufresne <[email protected]> Reviewed-by: Sebastian Fricke <[email protected]> Signed-off-by: Hans Verkuil <[email protected]> Signed-off-by: Mauro Carvalho Chehab <[email protected]>
1 parent 5e57a86 commit 6f32ea3

File tree

1 file changed

+21
-27
lines changed

1 file changed

+21
-27
lines changed

drivers/staging/media/rkvdec/rkvdec-h264.c

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,10 @@ struct rkvdec_h264_priv_tbl {
9797
u8 err_info[RKV_ERROR_INFO_SIZE];
9898
};
9999

100-
#define RKVDEC_H264_DPB_SIZE 16
101-
102100
struct rkvdec_h264_reflists {
103101
struct v4l2_h264_reference p[V4L2_H264_REF_LIST_LEN];
104102
struct v4l2_h264_reference b0[V4L2_H264_REF_LIST_LEN];
105103
struct v4l2_h264_reference b1[V4L2_H264_REF_LIST_LEN];
106-
u8 num_valid;
107104
};
108105

109106
struct rkvdec_h264_run {
@@ -747,23 +744,26 @@ static void lookup_ref_buf_idx(struct rkvdec_ctx *ctx,
747744
struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q;
748745
int buf_idx = -1;
749746

750-
if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
747+
if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) {
751748
buf_idx = vb2_find_timestamp(cap_q,
752749
dpb[i].reference_ts, 0);
750+
if (buf_idx < 0)
751+
pr_debug("No buffer for reference_ts %llu",
752+
dpb[i].reference_ts);
753+
}
753754

754755
run->ref_buf_idx[i] = buf_idx;
755756
}
756757
}
757758

758759
static void assemble_hw_rps(struct rkvdec_ctx *ctx,
760+
struct v4l2_h264_reflist_builder *builder,
759761
struct rkvdec_h264_run *run)
760762
{
761763
const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params;
762764
const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb;
763765
struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
764-
const struct v4l2_ctrl_h264_sps *sps = run->sps;
765766
struct rkvdec_h264_priv_tbl *priv_tbl = h264_ctx->priv_tbl.cpu;
766-
u32 max_frame_num = 1 << (sps->log2_max_frame_num_minus4 + 4);
767767

768768
u32 *hw_rps = priv_tbl->rps;
769769
u32 i, j;
@@ -781,37 +781,36 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx,
781781
if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
782782
continue;
783783

784-
if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM ||
785-
dpb[i].frame_num <= dec_params->frame_num) {
786-
p[i] = dpb[i].frame_num;
787-
continue;
788-
}
789-
790-
p[i] = dpb[i].frame_num - max_frame_num;
784+
p[i] = builder->refs[i].frame_num;
791785
}
792786

793787
for (j = 0; j < RKVDEC_NUM_REFLIST; j++) {
794-
for (i = 0; i < h264_ctx->reflists.num_valid; i++) {
795-
bool dpb_valid = run->ref_buf_idx[i] >= 0;
796-
u8 idx = 0;
788+
for (i = 0; i < builder->num_valid; i++) {
789+
struct v4l2_h264_reference *ref;
790+
bool dpb_valid;
791+
bool bottom;
797792

798793
switch (j) {
799794
case 0:
800-
idx = h264_ctx->reflists.p[i].index;
795+
ref = &h264_ctx->reflists.p[i];
801796
break;
802797
case 1:
803-
idx = h264_ctx->reflists.b0[i].index;
798+
ref = &h264_ctx->reflists.b0[i];
804799
break;
805800
case 2:
806-
idx = h264_ctx->reflists.b1[i].index;
801+
ref = &h264_ctx->reflists.b1[i];
807802
break;
808803
}
809804

810-
if (idx >= ARRAY_SIZE(dec_params->dpb))
805+
if (WARN_ON(ref->index >= ARRAY_SIZE(dec_params->dpb)))
811806
continue;
812807

808+
dpb_valid = run->ref_buf_idx[ref->index] >= 0;
809+
bottom = ref->fields == V4L2_H264_BOTTOM_FIELD_REF;
810+
813811
set_ps_field(hw_rps, DPB_INFO(i, j),
814-
idx | dpb_valid << 4);
812+
ref->index | dpb_valid << 4);
813+
set_ps_field(hw_rps, BOTTOM_FLAG(i, j), bottom);
815814
}
816815
}
817816
}
@@ -999,10 +998,6 @@ static void config_registers(struct rkvdec_ctx *ctx,
999998
rkvdec->regs + RKVDEC_REG_H264_BASE_REFER15);
1000999
}
10011000

1002-
/*
1003-
* Since support frame mode only
1004-
* top_field_order_cnt is the same as bottom_field_order_cnt
1005-
*/
10061001
reg = RKVDEC_CUR_POC(dec_params->top_field_order_cnt);
10071002
writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_CUR_POC0);
10081003

@@ -1166,15 +1161,14 @@ static int rkvdec_h264_run(struct rkvdec_ctx *ctx)
11661161
/* Build the P/B{0,1} ref lists. */
11671162
v4l2_h264_init_reflist_builder(&reflist_builder, run.decode_params,
11681163
run.sps, run.decode_params->dpb);
1169-
h264_ctx->reflists.num_valid = reflist_builder.num_valid;
11701164
v4l2_h264_build_p_ref_list(&reflist_builder, h264_ctx->reflists.p);
11711165
v4l2_h264_build_b_ref_lists(&reflist_builder, h264_ctx->reflists.b0,
11721166
h264_ctx->reflists.b1);
11731167

11741168
assemble_hw_scaling_list(ctx, &run);
11751169
assemble_hw_pps(ctx, &run);
11761170
lookup_ref_buf_idx(ctx, &run);
1177-
assemble_hw_rps(ctx, &run);
1171+
assemble_hw_rps(ctx, &reflist_builder, &run);
11781172
config_registers(ctx, &run);
11791173

11801174
rkvdec_run_postamble(ctx, &run.base);

0 commit comments

Comments
 (0)