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

source code of linux/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_common.c