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 | |
15 | void 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 | |
36 | void *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 | |
46 | void 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 | |
94 | void 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 | |
121 | void 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 | |
149 | void 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 | |
185 | void 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 | |
195 | void |
196 | mtk_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 | |
227 | static 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 | */ |
241 | void 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 | |
305 | unsigned 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 | |
312 | int 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 | |