1*0934d375SYunfei Dong // SPDX-License-Identifier: GPL-2.0
2*0934d375SYunfei Dong /*
3*0934d375SYunfei Dong  * Copyright (c) 2022 MediaTek Inc.
4*0934d375SYunfei Dong  * Author: Yunfei Dong <yunfei.dong@mediatek.com>
5*0934d375SYunfei Dong  */
6*0934d375SYunfei Dong 
7*0934d375SYunfei Dong #include "vdec_h264_req_common.h"
8*0934d375SYunfei Dong 
9*0934d375SYunfei Dong /* get used parameters for sps/pps */
10*0934d375SYunfei Dong #define GET_MTK_VDEC_FLAG(cond, flag) \
11*0934d375SYunfei Dong 	{ dst_param->cond = ((src_param->flags & flag) ? (1) : (0)); }
12*0934d375SYunfei Dong #define GET_MTK_VDEC_PARAM(param) \
13*0934d375SYunfei Dong 	{ dst_param->param = src_param->param; }
14*0934d375SYunfei Dong 
mtk_vdec_h264_get_ref_list(u8 * ref_list,const struct v4l2_h264_reference * v4l2_ref_list,int num_valid)15*0934d375SYunfei Dong void mtk_vdec_h264_get_ref_list(u8 *ref_list,
16*0934d375SYunfei Dong 				const struct v4l2_h264_reference *v4l2_ref_list,
17*0934d375SYunfei Dong 				int num_valid)
18*0934d375SYunfei Dong {
19*0934d375SYunfei Dong 	u32 i;
20*0934d375SYunfei Dong 
21*0934d375SYunfei Dong 	/*
22*0934d375SYunfei Dong 	 * TODO The firmware does not support field decoding. Future
23*0934d375SYunfei Dong 	 * implementation must use v4l2_ref_list[i].fields to obtain
24*0934d375SYunfei Dong 	 * the reference field parity.
25*0934d375SYunfei Dong 	 */
26*0934d375SYunfei Dong 
27*0934d375SYunfei Dong 	for (i = 0; i < num_valid; i++)
28*0934d375SYunfei Dong 		ref_list[i] = v4l2_ref_list[i].index;
29*0934d375SYunfei Dong 
30*0934d375SYunfei Dong 	/*
31*0934d375SYunfei Dong 	 * The firmware expects unused reflist entries to have the value 0x20.
32*0934d375SYunfei Dong 	 */
33*0934d375SYunfei Dong 	memset(&ref_list[num_valid], 0x20, 32 - num_valid);
34*0934d375SYunfei Dong }
35*0934d375SYunfei Dong 
mtk_vdec_h264_get_ctrl_ptr(struct mtk_vcodec_dec_ctx * ctx,int id)36*0934d375SYunfei Dong void *mtk_vdec_h264_get_ctrl_ptr(struct mtk_vcodec_dec_ctx *ctx, int id)
37*0934d375SYunfei Dong {
38*0934d375SYunfei Dong 	struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, id);
39*0934d375SYunfei Dong 
40*0934d375SYunfei Dong 	if (!ctrl)
41*0934d375SYunfei Dong 		return ERR_PTR(-EINVAL);
42*0934d375SYunfei Dong 
43*0934d375SYunfei Dong 	return ctrl->p_cur.p;
44*0934d375SYunfei Dong }
45*0934d375SYunfei Dong 
mtk_vdec_h264_fill_dpb_info(struct mtk_vcodec_dec_ctx * ctx,struct slice_api_h264_decode_param * decode_params,struct mtk_h264_dpb_info * h264_dpb_info)46*0934d375SYunfei Dong void mtk_vdec_h264_fill_dpb_info(struct mtk_vcodec_dec_ctx *ctx,
47*0934d375SYunfei Dong 				 struct slice_api_h264_decode_param *decode_params,
48*0934d375SYunfei Dong 				 struct mtk_h264_dpb_info *h264_dpb_info)
49*0934d375SYunfei Dong {
50*0934d375SYunfei Dong 	const struct slice_h264_dpb_entry *dpb;
51*0934d375SYunfei Dong 	struct vb2_queue *vq;
52*0934d375SYunfei Dong 	struct vb2_buffer *vb;
53*0934d375SYunfei Dong 	struct vb2_v4l2_buffer *vb2_v4l2;
54*0934d375SYunfei Dong 	int index;
55*0934d375SYunfei Dong 
56*0934d375SYunfei Dong 	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
57*0934d375SYunfei Dong 
58*0934d375SYunfei Dong 	for (index = 0; index < V4L2_H264_NUM_DPB_ENTRIES; index++) {
59*0934d375SYunfei Dong 		dpb = &decode_params->dpb[index];
60*0934d375SYunfei Dong 		if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) {
61*0934d375SYunfei Dong 			h264_dpb_info[index].reference_flag = 0;
62*0934d375SYunfei Dong 			continue;
63*0934d375SYunfei Dong 		}
64*0934d375SYunfei Dong 
65*0934d375SYunfei Dong 		vb = vb2_find_buffer(vq, dpb->reference_ts);
66*0934d375SYunfei Dong 		if (!vb) {
67*0934d375SYunfei Dong 			dev_err(&ctx->dev->plat_dev->dev,
68*0934d375SYunfei Dong 				"Reference invalid: dpb_index(%d) reference_ts(%lld)",
69*0934d375SYunfei Dong 				index, dpb->reference_ts);
70*0934d375SYunfei Dong 			continue;
71*0934d375SYunfei Dong 		}
72*0934d375SYunfei Dong 
73*0934d375SYunfei Dong 		/* 1 for short term reference, 2 for long term reference */
74*0934d375SYunfei Dong 		if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM))
75*0934d375SYunfei Dong 			h264_dpb_info[index].reference_flag = 1;
76*0934d375SYunfei Dong 		else
77*0934d375SYunfei Dong 			h264_dpb_info[index].reference_flag = 2;
78*0934d375SYunfei Dong 
79*0934d375SYunfei Dong 		vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
80*0934d375SYunfei Dong 		h264_dpb_info[index].field = vb2_v4l2->field;
81*0934d375SYunfei Dong 
82*0934d375SYunfei Dong 		h264_dpb_info[index].y_dma_addr =
83*0934d375SYunfei Dong 			vb2_dma_contig_plane_dma_addr(vb, 0);
84*0934d375SYunfei Dong 		if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
85*0934d375SYunfei Dong 			h264_dpb_info[index].c_dma_addr =
86*0934d375SYunfei Dong 				vb2_dma_contig_plane_dma_addr(vb, 1);
87*0934d375SYunfei Dong 		else
88*0934d375SYunfei Dong 			h264_dpb_info[index].c_dma_addr =
89*0934d375SYunfei Dong 				h264_dpb_info[index].y_dma_addr +
90*0934d375SYunfei Dong 				ctx->picinfo.fb_sz[0];
91*0934d375SYunfei Dong 	}
92*0934d375SYunfei Dong }
93*0934d375SYunfei Dong 
mtk_vdec_h264_copy_sps_params(struct mtk_h264_sps_param * dst_param,const struct v4l2_ctrl_h264_sps * src_param)94*0934d375SYunfei Dong void mtk_vdec_h264_copy_sps_params(struct mtk_h264_sps_param *dst_param,
95*0934d375SYunfei Dong 				   const struct v4l2_ctrl_h264_sps *src_param)
96*0934d375SYunfei Dong {
97*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(chroma_format_idc);
98*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(bit_depth_luma_minus8);
99*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(bit_depth_chroma_minus8);
100*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(log2_max_frame_num_minus4);
101*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(pic_order_cnt_type);
102*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(log2_max_pic_order_cnt_lsb_minus4);
103*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(max_num_ref_frames);
104*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(pic_width_in_mbs_minus1);
105*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(pic_height_in_map_units_minus1);
106*0934d375SYunfei Dong 
107*0934d375SYunfei Dong 	GET_MTK_VDEC_FLAG(separate_colour_plane_flag,
108*0934d375SYunfei Dong 			  V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE);
109*0934d375SYunfei Dong 	GET_MTK_VDEC_FLAG(qpprime_y_zero_transform_bypass_flag,
110*0934d375SYunfei Dong 			  V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS);
111*0934d375SYunfei Dong 	GET_MTK_VDEC_FLAG(delta_pic_order_always_zero_flag,
112*0934d375SYunfei Dong 			  V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO);
113*0934d375SYunfei Dong 	GET_MTK_VDEC_FLAG(frame_mbs_only_flag,
114*0934d375SYunfei Dong 			  V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY);
115*0934d375SYunfei Dong 	GET_MTK_VDEC_FLAG(mb_adaptive_frame_field_flag,
116*0934d375SYunfei Dong 			  V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD);
117*0934d375SYunfei Dong 	GET_MTK_VDEC_FLAG(direct_8x8_inference_flag,
118*0934d375SYunfei Dong 			  V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE);
119*0934d375SYunfei Dong }
120*0934d375SYunfei Dong 
mtk_vdec_h264_copy_pps_params(struct mtk_h264_pps_param * dst_param,const struct v4l2_ctrl_h264_pps * src_param)121*0934d375SYunfei Dong void mtk_vdec_h264_copy_pps_params(struct mtk_h264_pps_param *dst_param,
122*0934d375SYunfei Dong 				   const struct v4l2_ctrl_h264_pps *src_param)
123*0934d375SYunfei Dong {
124*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(num_ref_idx_l0_default_active_minus1);
125*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(num_ref_idx_l1_default_active_minus1);
126*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(weighted_bipred_idc);
127*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(pic_init_qp_minus26);
128*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(chroma_qp_index_offset);
129*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(second_chroma_qp_index_offset);
130*0934d375SYunfei Dong 
131*0934d375SYunfei Dong 	GET_MTK_VDEC_FLAG(entropy_coding_mode_flag,
132*0934d375SYunfei Dong 			  V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE);
133*0934d375SYunfei Dong 	GET_MTK_VDEC_FLAG(pic_order_present_flag,
134*0934d375SYunfei Dong 			  V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT);
135*0934d375SYunfei Dong 	GET_MTK_VDEC_FLAG(weighted_pred_flag,
136*0934d375SYunfei Dong 			  V4L2_H264_PPS_FLAG_WEIGHTED_PRED);
137*0934d375SYunfei Dong 	GET_MTK_VDEC_FLAG(deblocking_filter_control_present_flag,
138*0934d375SYunfei Dong 			  V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT);
139*0934d375SYunfei Dong 	GET_MTK_VDEC_FLAG(constrained_intra_pred_flag,
140*0934d375SYunfei Dong 			  V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED);
141*0934d375SYunfei Dong 	GET_MTK_VDEC_FLAG(redundant_pic_cnt_present_flag,
142*0934d375SYunfei Dong 			  V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT);
143*0934d375SYunfei Dong 	GET_MTK_VDEC_FLAG(transform_8x8_mode_flag,
144*0934d375SYunfei Dong 			  V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE);
145*0934d375SYunfei Dong 	GET_MTK_VDEC_FLAG(scaling_matrix_present_flag,
146*0934d375SYunfei Dong 			  V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT);
147*0934d375SYunfei Dong }
148*0934d375SYunfei Dong 
mtk_vdec_h264_copy_slice_hd_params(struct mtk_h264_slice_hd_param * dst_param,const struct v4l2_ctrl_h264_slice_params * src_param,const struct v4l2_ctrl_h264_decode_params * dec_param)149*0934d375SYunfei Dong void mtk_vdec_h264_copy_slice_hd_params(struct mtk_h264_slice_hd_param *dst_param,
150*0934d375SYunfei Dong 					const struct v4l2_ctrl_h264_slice_params *src_param,
151*0934d375SYunfei Dong 					const struct v4l2_ctrl_h264_decode_params *dec_param)
152*0934d375SYunfei Dong {
153*0934d375SYunfei Dong 	int temp;
154*0934d375SYunfei Dong 
155*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(first_mb_in_slice);
156*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(slice_type);
157*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(cabac_init_idc);
158*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(slice_qp_delta);
159*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(disable_deblocking_filter_idc);
160*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(slice_alpha_c0_offset_div2);
161*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(slice_beta_offset_div2);
162*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(num_ref_idx_l0_active_minus1);
163*0934d375SYunfei Dong 	GET_MTK_VDEC_PARAM(num_ref_idx_l1_active_minus1);
164*0934d375SYunfei Dong 
165*0934d375SYunfei Dong 	dst_param->frame_num = dec_param->frame_num;
166*0934d375SYunfei Dong 	dst_param->pic_order_cnt_lsb = dec_param->pic_order_cnt_lsb;
167*0934d375SYunfei Dong 
168*0934d375SYunfei Dong 	dst_param->delta_pic_order_cnt_bottom =
169*0934d375SYunfei Dong 		dec_param->delta_pic_order_cnt_bottom;
170*0934d375SYunfei Dong 	dst_param->delta_pic_order_cnt0 =
171*0934d375SYunfei Dong 		dec_param->delta_pic_order_cnt0;
172*0934d375SYunfei Dong 	dst_param->delta_pic_order_cnt1 =
173*0934d375SYunfei Dong 		dec_param->delta_pic_order_cnt1;
174*0934d375SYunfei Dong 
175*0934d375SYunfei Dong 	temp = dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC;
176*0934d375SYunfei Dong 	dst_param->field_pic_flag = temp ? 1 : 0;
177*0934d375SYunfei Dong 
178*0934d375SYunfei Dong 	temp = dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD;
179*0934d375SYunfei Dong 	dst_param->bottom_field_flag = temp ? 1 : 0;
180*0934d375SYunfei Dong 
181*0934d375SYunfei Dong 	GET_MTK_VDEC_FLAG(direct_spatial_mv_pred_flag,
182*0934d375SYunfei Dong 			  V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED);
183*0934d375SYunfei Dong }
184*0934d375SYunfei Dong 
mtk_vdec_h264_copy_scaling_matrix(struct slice_api_h264_scaling_matrix * dst_matrix,const struct v4l2_ctrl_h264_scaling_matrix * src_matrix)185*0934d375SYunfei Dong void mtk_vdec_h264_copy_scaling_matrix(struct slice_api_h264_scaling_matrix *dst_matrix,
186*0934d375SYunfei Dong 				       const struct v4l2_ctrl_h264_scaling_matrix *src_matrix)
187*0934d375SYunfei Dong {
188*0934d375SYunfei Dong 	memcpy(dst_matrix->scaling_list_4x4, src_matrix->scaling_list_4x4,
189*0934d375SYunfei Dong 	       sizeof(dst_matrix->scaling_list_4x4));
190*0934d375SYunfei Dong 
191*0934d375SYunfei Dong 	memcpy(dst_matrix->scaling_list_8x8, src_matrix->scaling_list_8x8,
192*0934d375SYunfei Dong 	       sizeof(dst_matrix->scaling_list_8x8));
193*0934d375SYunfei Dong }
194*0934d375SYunfei Dong 
195*0934d375SYunfei Dong void
mtk_vdec_h264_copy_decode_params(struct slice_api_h264_decode_param * dst_params,const struct v4l2_ctrl_h264_decode_params * src_params,const struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES])196*0934d375SYunfei Dong mtk_vdec_h264_copy_decode_params(struct slice_api_h264_decode_param *dst_params,
197*0934d375SYunfei Dong 				 const struct v4l2_ctrl_h264_decode_params *src_params,
198*0934d375SYunfei Dong 				 const struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES])
199*0934d375SYunfei Dong {
200*0934d375SYunfei Dong 	struct slice_h264_dpb_entry *dst_entry;
201*0934d375SYunfei Dong 	const struct v4l2_h264_dpb_entry *src_entry;
202*0934d375SYunfei Dong 	int i;
203*0934d375SYunfei Dong 
204*0934d375SYunfei Dong 	for (i = 0; i < ARRAY_SIZE(dst_params->dpb); i++) {
205*0934d375SYunfei Dong 		dst_entry = &dst_params->dpb[i];
206*0934d375SYunfei Dong 		src_entry = &dpb[i];
207*0934d375SYunfei Dong 
208*0934d375SYunfei Dong 		dst_entry->reference_ts = src_entry->reference_ts;
209*0934d375SYunfei Dong 		dst_entry->frame_num = src_entry->frame_num;
210*0934d375SYunfei Dong 		dst_entry->pic_num = src_entry->pic_num;
211*0934d375SYunfei Dong 		dst_entry->top_field_order_cnt = src_entry->top_field_order_cnt;
212*0934d375SYunfei Dong 		dst_entry->bottom_field_order_cnt =
213*0934d375SYunfei Dong 			src_entry->bottom_field_order_cnt;
214*0934d375SYunfei Dong 		dst_entry->flags = src_entry->flags;
215*0934d375SYunfei Dong 	}
216*0934d375SYunfei Dong 
217*0934d375SYunfei Dong 	/* num_slices is a leftover from the old H.264 support and is ignored
218*0934d375SYunfei Dong 	 * by the firmware.
219*0934d375SYunfei Dong 	 */
220*0934d375SYunfei Dong 	dst_params->num_slices = 0;
221*0934d375SYunfei Dong 	dst_params->nal_ref_idc = src_params->nal_ref_idc;
222*0934d375SYunfei Dong 	dst_params->top_field_order_cnt = src_params->top_field_order_cnt;
223*0934d375SYunfei Dong 	dst_params->bottom_field_order_cnt = src_params->bottom_field_order_cnt;
224*0934d375SYunfei Dong 	dst_params->flags = src_params->flags;
225*0934d375SYunfei Dong }
226*0934d375SYunfei Dong 
mtk_vdec_h264_dpb_entry_match(const struct v4l2_h264_dpb_entry * a,const struct v4l2_h264_dpb_entry * b)227*0934d375SYunfei Dong static bool mtk_vdec_h264_dpb_entry_match(const struct v4l2_h264_dpb_entry *a,
228*0934d375SYunfei Dong 					  const struct v4l2_h264_dpb_entry *b)
229*0934d375SYunfei Dong {
230*0934d375SYunfei Dong 	return a->top_field_order_cnt == b->top_field_order_cnt &&
231*0934d375SYunfei Dong 	       a->bottom_field_order_cnt == b->bottom_field_order_cnt;
232*0934d375SYunfei Dong }
233*0934d375SYunfei Dong 
234*0934d375SYunfei Dong /*
235*0934d375SYunfei Dong  * Move DPB entries of dec_param that refer to a frame already existing in dpb
236*0934d375SYunfei Dong  * into the already existing slot in dpb, and move other entries into new slots.
237*0934d375SYunfei Dong  *
238*0934d375SYunfei Dong  * This function is an adaptation of the similarly-named function in
239*0934d375SYunfei Dong  * hantro_h264.c.
240*0934d375SYunfei Dong  */
mtk_vdec_h264_update_dpb(const struct v4l2_ctrl_h264_decode_params * dec_param,struct v4l2_h264_dpb_entry * dpb)241*0934d375SYunfei Dong void mtk_vdec_h264_update_dpb(const struct v4l2_ctrl_h264_decode_params *dec_param,
242*0934d375SYunfei Dong 			      struct v4l2_h264_dpb_entry *dpb)
243*0934d375SYunfei Dong {
244*0934d375SYunfei Dong 	DECLARE_BITMAP(new, ARRAY_SIZE(dec_param->dpb)) = { 0, };
245*0934d375SYunfei Dong 	DECLARE_BITMAP(in_use, ARRAY_SIZE(dec_param->dpb)) = { 0, };
246*0934d375SYunfei Dong 	DECLARE_BITMAP(used, ARRAY_SIZE(dec_param->dpb)) = { 0, };
247*0934d375SYunfei Dong 	unsigned int i, j;
248*0934d375SYunfei Dong 
249*0934d375SYunfei Dong 	/* Disable all entries by default, and mark the ones in use. */
250*0934d375SYunfei Dong 	for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
251*0934d375SYunfei Dong 		if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
252*0934d375SYunfei Dong 			set_bit(i, in_use);
253*0934d375SYunfei Dong 		dpb[i].flags &= ~V4L2_H264_DPB_ENTRY_FLAG_ACTIVE;
254*0934d375SYunfei Dong 	}
255*0934d375SYunfei Dong 
256*0934d375SYunfei Dong 	/* Try to match new DPB entries with existing ones by their POCs. */
257*0934d375SYunfei Dong 	for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
258*0934d375SYunfei Dong 		const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
259*0934d375SYunfei Dong 
260*0934d375SYunfei Dong 		if (!(ndpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
261*0934d375SYunfei Dong 			continue;
262*0934d375SYunfei Dong 
263*0934d375SYunfei Dong 		/*
264*0934d375SYunfei Dong 		 * To cut off some comparisons, iterate only on target DPB
265*0934d375SYunfei Dong 		 * entries were already used.
266*0934d375SYunfei Dong 		 */
267*0934d375SYunfei Dong 		for_each_set_bit(j, in_use, ARRAY_SIZE(dec_param->dpb)) {
268*0934d375SYunfei Dong 			struct v4l2_h264_dpb_entry *cdpb;
269*0934d375SYunfei Dong 
270*0934d375SYunfei Dong 			cdpb = &dpb[j];
271*0934d375SYunfei Dong 			if (!mtk_vdec_h264_dpb_entry_match(cdpb, ndpb))
272*0934d375SYunfei Dong 				continue;
273*0934d375SYunfei Dong 
274*0934d375SYunfei Dong 			*cdpb = *ndpb;
275*0934d375SYunfei Dong 			set_bit(j, used);
276*0934d375SYunfei Dong 			/* Don't reiterate on this one. */
277*0934d375SYunfei Dong 			clear_bit(j, in_use);
278*0934d375SYunfei Dong 			break;
279*0934d375SYunfei Dong 		}
280*0934d375SYunfei Dong 
281*0934d375SYunfei Dong 		if (j == ARRAY_SIZE(dec_param->dpb))
282*0934d375SYunfei Dong 			set_bit(i, new);
283*0934d375SYunfei Dong 	}
284*0934d375SYunfei Dong 
285*0934d375SYunfei Dong 	/* For entries that could not be matched, use remaining free slots. */
286*0934d375SYunfei Dong 	for_each_set_bit(i, new, ARRAY_SIZE(dec_param->dpb)) {
287*0934d375SYunfei Dong 		const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
288*0934d375SYunfei Dong 		struct v4l2_h264_dpb_entry *cdpb;
289*0934d375SYunfei Dong 
290*0934d375SYunfei Dong 		/*
291*0934d375SYunfei Dong 		 * Both arrays are of the same sizes, so there is no way
292*0934d375SYunfei Dong 		 * we can end up with no space in target array, unless
293*0934d375SYunfei Dong 		 * something is buggy.
294*0934d375SYunfei Dong 		 */
295*0934d375SYunfei Dong 		j = find_first_zero_bit(used, ARRAY_SIZE(dec_param->dpb));
296*0934d375SYunfei Dong 		if (WARN_ON(j >= ARRAY_SIZE(dec_param->dpb)))
297*0934d375SYunfei Dong 			return;
298*0934d375SYunfei Dong 
299*0934d375SYunfei Dong 		cdpb = &dpb[j];
300*0934d375SYunfei Dong 		*cdpb = *ndpb;
301*0934d375SYunfei Dong 		set_bit(j, used);
302*0934d375SYunfei Dong 	}
303*0934d375SYunfei Dong }
304*0934d375SYunfei Dong 
mtk_vdec_h264_get_mv_buf_size(unsigned int width,unsigned int height)305*0934d375SYunfei Dong unsigned int mtk_vdec_h264_get_mv_buf_size(unsigned int width, unsigned int height)
306*0934d375SYunfei Dong {
307*0934d375SYunfei Dong 	int unit_size = (width / MB_UNIT_LEN) * (height / MB_UNIT_LEN) + 8;
308*0934d375SYunfei Dong 
309*0934d375SYunfei Dong 	return HW_MB_STORE_SZ * unit_size;
310*0934d375SYunfei Dong }
311*0934d375SYunfei Dong 
mtk_vdec_h264_find_start_code(unsigned char * data,unsigned int data_sz)312*0934d375SYunfei Dong int mtk_vdec_h264_find_start_code(unsigned char *data, unsigned int data_sz)
313*0934d375SYunfei Dong {
314*0934d375SYunfei Dong 	if (data_sz > 3 && data[0] == 0 && data[1] == 0 && data[2] == 1)
315*0934d375SYunfei Dong 		return 3;
316*0934d375SYunfei Dong 
317*0934d375SYunfei Dong 	if (data_sz > 4 && data[0] == 0 && data[1] == 0 && data[2] == 0 &&
318*0934d375SYunfei Dong 	    data[3] == 1)
319*0934d375SYunfei Dong 		return 4;
320*0934d375SYunfei Dong 
321*0934d375SYunfei Dong 	return -1;
322*0934d375SYunfei Dong }
323