Commit 2e2c3d6c authored by Nicolas Dufresne's avatar Nicolas Dufresne Committed by Mauro Carvalho Chehab
Browse files

media: h264: Use v4l2_h264_reference for reflist



In preparation for adding field decoding support, convert the byte arrays
for reflist into array of struct v4l2_h264_reference. That struct will
allow us to mark which field of the reference picture is being referenced.

[hverkuil: top_field_order_cnt -> pic_order_count]

Signed-off-by: default avatarNicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: default avatarEzequiel Garcia <ezequiel@vanguardiasur.com.ar>
Tested-by: default avatarDmitry Osipenko <dmitry.osipenko@collabora.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent 4d52db40
Loading
Loading
Loading
Loading
+17 −4
Original line number Diff line number Diff line
@@ -12,11 +12,24 @@
#define GET_MTK_VDEC_PARAM(param) \
	{ dst_param->param = src_param->param; }

void mtk_vdec_h264_get_ref_list(u8 *ref_list,
				const struct v4l2_h264_reference *v4l2_ref_list,
				int num_valid)
{
	u32 i;

	/*
	 * TODO The firmware does not support field decoding. Future
	 * implementation must use v4l2_ref_list[i].fields to obtain
	 * the reference field parity.
	 */

	for (i = 0; i < num_valid; i++)
		ref_list[i] = v4l2_ref_list[i].index;

	/*
	 * The firmware expects unused reflist entries to have the value 0x20.
	 */
void mtk_vdec_h264_fixup_ref_list(u8 *ref_list, size_t num_valid)
{
	memset(&ref_list[num_valid], 0x20, 32 - num_valid);
}

+7 −4
Original line number Diff line number Diff line
@@ -164,12 +164,15 @@ struct h264_fb {
};

/**
 * mtk_vdec_h264_fixup_ref_list - fixup unused reference to 0x20.
 * mtk_vdec_h264_get_ref_list - translate V4L2 reference list
 *
 * @ref_list:	reference picture list
 * @ref_list:		Mediatek reference picture list
 * @v4l2_ref_list:	V4L2 reference picture list
 * @num_valid:		used reference number
 */
void mtk_vdec_h264_fixup_ref_list(u8 *ref_list, size_t num_valid);
void mtk_vdec_h264_get_ref_list(u8 *ref_list,
				const struct v4l2_h264_reference *v4l2_ref_list,
				int num_valid);

/**
 * mtk_vdec_h264_get_ctrl_ptr - get each CID contrl address.
+10 −5
Original line number Diff line number Diff line
@@ -102,6 +102,9 @@ static int get_vdec_decode_parameters(struct vdec_h264_slice_inst *inst)
	const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix;
	struct mtk_h264_dec_slice_param *slice_param = &inst->h264_slice_param;
	struct v4l2_h264_reflist_builder reflist_builder;
	struct v4l2_h264_reference v4l2_p0_reflist[V4L2_H264_REF_LIST_LEN];
	struct v4l2_h264_reference v4l2_b0_reflist[V4L2_H264_REF_LIST_LEN];
	struct v4l2_h264_reference v4l2_b1_reflist[V4L2_H264_REF_LIST_LEN];
	u8 *p0_reflist = slice_param->decode_params.ref_pic_list_p0;
	u8 *b0_reflist = slice_param->decode_params.ref_pic_list_b0;
	u8 *b1_reflist = slice_param->decode_params.ref_pic_list_b1;
@@ -137,12 +140,14 @@ static int get_vdec_decode_parameters(struct vdec_h264_slice_inst *inst)
	/* Build the reference lists */
	v4l2_h264_init_reflist_builder(&reflist_builder, dec_params, sps,
				       inst->dpb);
	v4l2_h264_build_p_ref_list(&reflist_builder, p0_reflist);
	v4l2_h264_build_b_ref_lists(&reflist_builder, b0_reflist, b1_reflist);
	v4l2_h264_build_p_ref_list(&reflist_builder, v4l2_p0_reflist);
	v4l2_h264_build_b_ref_lists(&reflist_builder, v4l2_b0_reflist,
				    v4l2_b1_reflist);

	/* Adapt the built lists to the firmware's expectations */
	mtk_vdec_h264_fixup_ref_list(p0_reflist, reflist_builder.num_valid);
	mtk_vdec_h264_fixup_ref_list(b0_reflist, reflist_builder.num_valid);
	mtk_vdec_h264_fixup_ref_list(b1_reflist, reflist_builder.num_valid);
	mtk_vdec_h264_get_ref_list(p0_reflist, v4l2_p0_reflist, reflist_builder.num_valid);
	mtk_vdec_h264_get_ref_list(b0_reflist, v4l2_b0_reflist, reflist_builder.num_valid);
	mtk_vdec_h264_get_ref_list(b1_reflist, v4l2_b1_reflist, reflist_builder.num_valid);

	memcpy(&inst->vsi_ctx.h264_slice_params, slice_param,
	       sizeof(inst->vsi_ctx.h264_slice_params));
+17 −10
Original line number Diff line number Diff line
@@ -222,6 +222,9 @@ static int get_vdec_sig_decode_parameters(struct vdec_h264_slice_inst *inst)
	const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix;
	struct vdec_h264_slice_lat_dec_param *slice_param = &inst->h264_slice_param;
	struct v4l2_h264_reflist_builder reflist_builder;
	struct v4l2_h264_reference v4l2_p0_reflist[V4L2_H264_REF_LIST_LEN];
	struct v4l2_h264_reference v4l2_b0_reflist[V4L2_H264_REF_LIST_LEN];
	struct v4l2_h264_reference v4l2_b1_reflist[V4L2_H264_REF_LIST_LEN];
	u8 *p0_reflist = slice_param->decode_params.ref_pic_list_p0;
	u8 *b0_reflist = slice_param->decode_params.ref_pic_list_b0;
	u8 *b1_reflist = slice_param->decode_params.ref_pic_list_b1;
@@ -256,13 +259,14 @@ static int get_vdec_sig_decode_parameters(struct vdec_h264_slice_inst *inst)

	/* Build the reference lists */
	v4l2_h264_init_reflist_builder(&reflist_builder, dec_params, sps, inst->dpb);
	v4l2_h264_build_p_ref_list(&reflist_builder, p0_reflist);
	v4l2_h264_build_p_ref_list(&reflist_builder, v4l2_p0_reflist);
	v4l2_h264_build_b_ref_lists(&reflist_builder, v4l2_b0_reflist, v4l2_b1_reflist);

	v4l2_h264_build_b_ref_lists(&reflist_builder, b0_reflist, b1_reflist);
	/* Adapt the built lists to the firmware's expectations */
	mtk_vdec_h264_fixup_ref_list(p0_reflist, reflist_builder.num_valid);
	mtk_vdec_h264_fixup_ref_list(b0_reflist, reflist_builder.num_valid);
	mtk_vdec_h264_fixup_ref_list(b1_reflist, reflist_builder.num_valid);
	mtk_vdec_h264_get_ref_list(p0_reflist, v4l2_p0_reflist, reflist_builder.num_valid);
	mtk_vdec_h264_get_ref_list(b0_reflist, v4l2_b0_reflist, reflist_builder.num_valid);
	mtk_vdec_h264_get_ref_list(b1_reflist, v4l2_b1_reflist, reflist_builder.num_valid);

	memcpy(&inst->vsi_ctx.h264_slice_params, slice_param,
	       sizeof(inst->vsi_ctx.h264_slice_params));

@@ -276,6 +280,9 @@ static void vdec_h264_slice_fill_decode_reflist(struct vdec_h264_slice_inst *ins
	struct v4l2_ctrl_h264_decode_params *dec_params = &share_info->dec_params;
	struct v4l2_ctrl_h264_sps *sps = &share_info->sps;
	struct v4l2_h264_reflist_builder reflist_builder;
	struct v4l2_h264_reference v4l2_p0_reflist[V4L2_H264_REF_LIST_LEN];
	struct v4l2_h264_reference v4l2_b0_reflist[V4L2_H264_REF_LIST_LEN];
	struct v4l2_h264_reference v4l2_b1_reflist[V4L2_H264_REF_LIST_LEN];
	u8 *p0_reflist = slice_param->decode_params.ref_pic_list_p0;
	u8 *b0_reflist = slice_param->decode_params.ref_pic_list_b0;
	u8 *b1_reflist = slice_param->decode_params.ref_pic_list_b1;
@@ -291,13 +298,13 @@ static void vdec_h264_slice_fill_decode_reflist(struct vdec_h264_slice_inst *ins
	/* Build the reference lists */
	v4l2_h264_init_reflist_builder(&reflist_builder, dec_params, sps,
				       inst->dpb);
	v4l2_h264_build_p_ref_list(&reflist_builder, p0_reflist);
	v4l2_h264_build_b_ref_lists(&reflist_builder, b0_reflist, b1_reflist);
	v4l2_h264_build_p_ref_list(&reflist_builder, v4l2_p0_reflist);
	v4l2_h264_build_b_ref_lists(&reflist_builder, v4l2_b0_reflist, v4l2_b1_reflist);

	/* Adapt the built lists to the firmware's expectations */
	mtk_vdec_h264_fixup_ref_list(p0_reflist, reflist_builder.num_valid);
	mtk_vdec_h264_fixup_ref_list(b0_reflist, reflist_builder.num_valid);
	mtk_vdec_h264_fixup_ref_list(b1_reflist, reflist_builder.num_valid);
	mtk_vdec_h264_get_ref_list(p0_reflist, v4l2_p0_reflist, reflist_builder.num_valid);
	mtk_vdec_h264_get_ref_list(b0_reflist, v4l2_b0_reflist, reflist_builder.num_valid);
	mtk_vdec_h264_get_ref_list(b1_reflist, v4l2_b1_reflist, reflist_builder.num_valid);
}

static int vdec_h264_slice_alloc_mv_buf(struct vdec_h264_slice_inst *inst,
+12 −7
Original line number Diff line number Diff line
@@ -45,9 +45,9 @@ struct tegra_vde_h264_decoder_ctx {
};

struct h264_reflists {
	u8 p[V4L2_H264_NUM_DPB_ENTRIES];
	u8 b0[V4L2_H264_NUM_DPB_ENTRIES];
	u8 b1[V4L2_H264_NUM_DPB_ENTRIES];
	struct v4l2_h264_reference p[V4L2_H264_NUM_DPB_ENTRIES];
	struct v4l2_h264_reference b0[V4L2_H264_NUM_DPB_ENTRIES];
	struct v4l2_h264_reference b1[V4L2_H264_NUM_DPB_ENTRIES];
};

static int tegra_vde_wait_mbe(struct tegra_vde *vde)
@@ -765,10 +765,10 @@ static int tegra_vde_h264_setup_frames(struct tegra_ctx *ctx,
	struct tegra_m2m_buffer *tb = vb_to_tegra_buf(&dst->vb2_buf);
	struct tegra_ctx_h264 *h = &ctx->h264;
	struct v4l2_h264_reflist_builder b;
	struct v4l2_h264_reference *dpb_id;
	struct h264_reflists reflists;
	struct vb2_buffer *ref;
	unsigned int i;
	u8 *dpb_id;
	int err;

	/*
@@ -811,14 +811,16 @@ static int tegra_vde_h264_setup_frames(struct tegra_ctx *ctx,
	}

	for (i = 0; i < b.num_valid; i++) {
		ref = get_ref_buf(ctx, dst, dpb_id[i]);
		int dpb_idx = dpb_id[i].index;

		err = tegra_vde_h264_setup_frame(ctx, h264, &b, ref, dpb_id[i],
		ref = get_ref_buf(ctx, dst, dpb_idx);

		err = tegra_vde_h264_setup_frame(ctx, h264, &b, ref, dpb_idx,
						 h264->dpb_frames_nb++);
		if (err)
			return err;

		if (b.refs[dpb_id[i]].pic_order_count < b.cur_pic_order_count)
		if (b.refs[dpb_idx].pic_order_count < b.cur_pic_order_count)
			h264->dpb_ref_frames_with_earlier_poc_nb++;
	}

@@ -880,6 +882,9 @@ static int tegra_vde_h264_setup_context(struct tegra_ctx *ctx,
	if (h->pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE)
		return -EOPNOTSUPP;

	if (h->decode_params->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC)
		return -EOPNOTSUPP;

	if (h->sps->profile_idc == 66)
		h264->baseline_profile = 1;

Loading