xref: /linux/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c (revision 97a48d1aab549acb9b7f4a80d484f59710643199)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Rockchip video decoder hevc common functions
4  *
5  * Copyright (C) 2025 Collabora, Ltd.
6  *      Detlev Casanova <detlev.casanova@collabora.com>
7  *
8  * Copyright (C) 2023 Collabora, Ltd.
9  *      Sebastian Fricke <sebastian.fricke@collabora.com>
10  *
11  * Copyright (C) 2019 Collabora, Ltd.
12  *	Boris Brezillon <boris.brezillon@collabora.com>
13  *
14  * Copyright (C) 2016 Rockchip Electronics Co., Ltd.
15  *	Jeffy Chen <jeffy.chen@rock-chips.com>
16  */
17 
18 #include <linux/v4l2-common.h>
19 #include <media/v4l2-mem2mem.h>
20 
21 #include "rkvdec.h"
22 #include "rkvdec-hevc-common.h"
23 
24 /* Store the Short term ref pic set calculated values */
25 struct calculated_rps_st_set {
26 	u8 num_delta_pocs;
27 	u8 num_negative_pics;
28 	u8 num_positive_pics;
29 	u8 used_by_curr_pic_s0[16];
30 	u8 used_by_curr_pic_s1[16];
31 	s32 delta_poc_s0[16];
32 	s32 delta_poc_s1[16];
33 };
34 
compute_tiles_uniform(struct rkvdec_hevc_run * run,u16 log2_min_cb_size,u16 width,u16 height,s32 pic_in_cts_width,s32 pic_in_cts_height,u16 * column_width,u16 * row_height)35 void compute_tiles_uniform(struct rkvdec_hevc_run *run, u16 log2_min_cb_size,
36 			   u16 width, u16 height, s32 pic_in_cts_width,
37 			   s32 pic_in_cts_height, u16 *column_width, u16 *row_height)
38 {
39 	const struct v4l2_ctrl_hevc_pps *pps = run->pps;
40 	int i;
41 
42 	for (i = 0; i < pps->num_tile_columns_minus1 + 1; i++)
43 		column_width[i] = ((i + 1) * pic_in_cts_width) /
44 				  (pps->num_tile_columns_minus1 + 1) -
45 				  (i * pic_in_cts_width) /
46 				  (pps->num_tile_columns_minus1 + 1);
47 
48 	for (i = 0; i < pps->num_tile_rows_minus1 + 1; i++)
49 		row_height[i] = ((i + 1) * pic_in_cts_height) /
50 				(pps->num_tile_rows_minus1 + 1) -
51 				(i * pic_in_cts_height) /
52 				(pps->num_tile_rows_minus1 + 1);
53 }
54 
compute_tiles_non_uniform(struct rkvdec_hevc_run * run,u16 log2_min_cb_size,u16 width,u16 height,s32 pic_in_cts_width,s32 pic_in_cts_height,u16 * column_width,u16 * row_height)55 void compute_tiles_non_uniform(struct rkvdec_hevc_run *run, u16 log2_min_cb_size,
56 			       u16 width, u16 height, s32 pic_in_cts_width,
57 			       s32 pic_in_cts_height, u16 *column_width, u16 *row_height)
58 {
59 	const struct v4l2_ctrl_hevc_pps *pps = run->pps;
60 	s32 sum = 0;
61 	int i;
62 
63 	for (i = 0; i < pps->num_tile_columns_minus1; i++) {
64 		column_width[i] = pps->column_width_minus1[i] + 1;
65 		sum += column_width[i];
66 	}
67 	column_width[i] = pic_in_cts_width - sum;
68 
69 	sum = 0;
70 	for (i = 0; i < pps->num_tile_rows_minus1; i++) {
71 		row_height[i] = pps->row_height_minus1[i] + 1;
72 		sum += row_height[i];
73 	}
74 	row_height[i] = pic_in_cts_height - sum;
75 }
76 
set_ref_poc(struct rkvdec_rps_short_term_ref_set * set,int poc,int value,int flag)77 static void set_ref_poc(struct rkvdec_rps_short_term_ref_set *set, int poc, int value, int flag)
78 {
79 	switch (poc) {
80 	case 0:
81 		set->delta_poc0 = value;
82 		set->used_flag0 = flag;
83 		break;
84 	case 1:
85 		set->delta_poc1 = value;
86 		set->used_flag1 = flag;
87 		break;
88 	case 2:
89 		set->delta_poc2 = value;
90 		set->used_flag2 = flag;
91 		break;
92 	case 3:
93 		set->delta_poc3 = value;
94 		set->used_flag3 = flag;
95 		break;
96 	case 4:
97 		set->delta_poc4 = value;
98 		set->used_flag4 = flag;
99 		break;
100 	case 5:
101 		set->delta_poc5 = value;
102 		set->used_flag5 = flag;
103 		break;
104 	case 6:
105 		set->delta_poc6 = value;
106 		set->used_flag6 = flag;
107 		break;
108 	case 7:
109 		set->delta_poc7 = value;
110 		set->used_flag7 = flag;
111 		break;
112 	case 8:
113 		set->delta_poc8 = value;
114 		set->used_flag8 = flag;
115 		break;
116 	case 9:
117 		set->delta_poc9 = value;
118 		set->used_flag9 = flag;
119 		break;
120 	case 10:
121 		set->delta_poc10 = value;
122 		set->used_flag10 = flag;
123 		break;
124 	case 11:
125 		set->delta_poc11 = value;
126 		set->used_flag11 = flag;
127 		break;
128 	case 12:
129 		set->delta_poc12 = value;
130 		set->used_flag12 = flag;
131 		break;
132 	case 13:
133 		set->delta_poc13 = value;
134 		set->used_flag13 = flag;
135 		break;
136 	case 14:
137 		set->delta_poc14 = value;
138 		set->used_flag14 = flag;
139 		break;
140 	}
141 }
142 
assemble_scalingfactor0(struct rkvdec_ctx * ctx,u8 * output,const struct v4l2_ctrl_hevc_scaling_matrix * input)143 static void assemble_scalingfactor0(struct rkvdec_ctx *ctx, u8 *output,
144 				    const struct v4l2_ctrl_hevc_scaling_matrix *input)
145 {
146 	const struct rkvdec_variant *variant = ctx->dev->variant;
147 	int offset = 0;
148 
149 	variant->ops->flatten_matrices(output, (const u8 *)input->scaling_list_4x4, 6, 4);
150 	offset = 6 * 16 * sizeof(u8);
151 	variant->ops->flatten_matrices(output + offset, (const u8 *)input->scaling_list_8x8, 6, 8);
152 	offset += 6 * 64 * sizeof(u8);
153 	variant->ops->flatten_matrices(output + offset, (const u8 *)input->scaling_list_16x16,
154 				       6, 8);
155 	offset += 6 * 64 * sizeof(u8);
156 	/* Add a 128 byte padding with 0s between the two 32x32 matrices */
157 	variant->ops->flatten_matrices(output + offset, (const u8 *)input->scaling_list_32x32,
158 				       1, 8);
159 	offset += 64 * sizeof(u8);
160 	memset(output + offset, 0, 128);
161 	offset += 128 * sizeof(u8);
162 	variant->ops->flatten_matrices(output + offset,
163 				       (const u8 *)input->scaling_list_32x32 + (64 * sizeof(u8)),
164 				       1, 8);
165 	offset += 64 * sizeof(u8);
166 	memset(output + offset, 0, 128);
167 }
168 
169 /*
170  * Required layout:
171  * A = scaling_list_dc_coef_16x16
172  * B = scaling_list_dc_coef_32x32
173  * 0 = Padding
174  *
175  * A, A, A, A, A, A, B, 0, 0, B, 0, 0
176  */
assemble_scalingdc(u8 * output,const struct v4l2_ctrl_hevc_scaling_matrix * input)177 static void assemble_scalingdc(u8 *output, const struct v4l2_ctrl_hevc_scaling_matrix *input)
178 {
179 	u8 list_32x32[6] = {0};
180 
181 	memcpy(output, input->scaling_list_dc_coef_16x16, 6 * sizeof(u8));
182 	list_32x32[0] = input->scaling_list_dc_coef_32x32[0];
183 	list_32x32[3] = input->scaling_list_dc_coef_32x32[1];
184 	memcpy(output + 6 * sizeof(u8), list_32x32, 6 * sizeof(u8));
185 }
186 
translate_scaling_list(struct rkvdec_ctx * ctx,struct scaling_factor * output,const struct v4l2_ctrl_hevc_scaling_matrix * input)187 static void translate_scaling_list(struct rkvdec_ctx *ctx, struct scaling_factor *output,
188 				   const struct v4l2_ctrl_hevc_scaling_matrix *input)
189 {
190 	assemble_scalingfactor0(ctx, output->scalingfactor0, input);
191 	memcpy(output->scalingfactor1, (const u8 *)input->scaling_list_4x4, 96);
192 	assemble_scalingdc(output->scalingdc, input);
193 	memset(output->reserved, 0, 4 * sizeof(u8));
194 }
195 
rkvdec_hevc_assemble_hw_scaling_list(struct rkvdec_ctx * ctx,struct rkvdec_hevc_run * run,struct scaling_factor * scaling_factor,struct v4l2_ctrl_hevc_scaling_matrix * cache)196 void rkvdec_hevc_assemble_hw_scaling_list(struct rkvdec_ctx *ctx,
197 					  struct rkvdec_hevc_run *run,
198 					  struct scaling_factor *scaling_factor,
199 					  struct v4l2_ctrl_hevc_scaling_matrix *cache)
200 {
201 	const struct v4l2_ctrl_hevc_scaling_matrix *scaling = run->scaling_matrix;
202 
203 	if (!memcmp(cache, scaling,
204 		    sizeof(struct v4l2_ctrl_hevc_scaling_matrix)))
205 		return;
206 
207 	translate_scaling_list(ctx, scaling_factor, scaling);
208 
209 	memcpy(cache, scaling,
210 	       sizeof(struct v4l2_ctrl_hevc_scaling_matrix));
211 }
212 
rkvdec_hevc_assemble_hw_lt_rps(struct rkvdec_hevc_run * run,struct rkvdec_rps * rps)213 static void rkvdec_hevc_assemble_hw_lt_rps(struct rkvdec_hevc_run *run, struct rkvdec_rps *rps)
214 {
215 	const struct v4l2_ctrl_hevc_sps *sps = run->sps;
216 
217 	if (!run->ext_sps_lt_rps)
218 		return;
219 
220 	for (int i = 0; i < sps->num_long_term_ref_pics_sps; i++) {
221 		rps->refs[i].lt_ref_pic_poc_lsb =
222 			run->ext_sps_lt_rps[i].lt_ref_pic_poc_lsb_sps;
223 		rps->refs[i].used_by_curr_pic_lt_flag =
224 			!!(run->ext_sps_lt_rps[i].flags & V4L2_HEVC_EXT_SPS_LT_RPS_FLAG_USED_LT);
225 	}
226 }
227 
rkvdec_hevc_assemble_hw_st_rps(struct rkvdec_hevc_run * run,struct rkvdec_rps * rps,struct calculated_rps_st_set * calculated_rps_st_sets)228 static void rkvdec_hevc_assemble_hw_st_rps(struct rkvdec_hevc_run *run, struct rkvdec_rps *rps,
229 					   struct calculated_rps_st_set *calculated_rps_st_sets)
230 {
231 	const struct v4l2_ctrl_hevc_sps *sps = run->sps;
232 
233 	for (int i = 0; i < sps->num_short_term_ref_pic_sets; i++) {
234 		int poc = 0;
235 		int j = 0;
236 		const struct calculated_rps_st_set *set = &calculated_rps_st_sets[i];
237 
238 		rps->short_term_ref_sets[i].num_negative = set->num_negative_pics;
239 		rps->short_term_ref_sets[i].num_positive = set->num_positive_pics;
240 
241 		for (; j < set->num_negative_pics; j++) {
242 			set_ref_poc(&rps->short_term_ref_sets[i], j,
243 				    set->delta_poc_s0[j], set->used_by_curr_pic_s0[j]);
244 		}
245 		poc = j;
246 
247 		for (j = 0; j < set->num_positive_pics; j++) {
248 			set_ref_poc(&rps->short_term_ref_sets[i], poc + j,
249 				    set->delta_poc_s1[j], set->used_by_curr_pic_s1[j]);
250 		}
251 	}
252 }
253 
254 /*
255  * Compute the short term ref pic set parameters based on its reference short term ref pic
256  */
st_ref_pic_set_prediction(struct rkvdec_hevc_run * run,int idx,struct calculated_rps_st_set * calculated_rps_st_sets)257 static void st_ref_pic_set_prediction(struct rkvdec_hevc_run *run, int idx,
258 				      struct calculated_rps_st_set *calculated_rps_st_sets)
259 {
260 	const struct v4l2_ctrl_hevc_ext_sps_st_rps *rps_data = &run->ext_sps_st_rps[idx];
261 	struct calculated_rps_st_set *st_rps = &calculated_rps_st_sets[idx];
262 	struct calculated_rps_st_set *ref_rps;
263 	u8 st_rps_idx = idx;
264 	u8 ref_rps_idx = 0;
265 	s16 delta_rps = 0;
266 	u8 use_delta_flag[16] = { 0 };
267 	u8 used_by_curr_pic_flag[16] = { 0 };
268 	int i, j;
269 	int dPoc;
270 
271 	ref_rps_idx = st_rps_idx - (rps_data->delta_idx_minus1 + 1); /* 7-59 */
272 	delta_rps = (1 - 2 * rps_data->delta_rps_sign) *
273 		   (rps_data->abs_delta_rps_minus1 + 1); /* 7-60 */
274 
275 	ref_rps = &calculated_rps_st_sets[ref_rps_idx];
276 
277 	for (j = 0; j <= ref_rps->num_delta_pocs; j++) {
278 		used_by_curr_pic_flag[j] = !!(rps_data->used_by_curr_pic & (1 << j));
279 		use_delta_flag[j] = !!(rps_data->use_delta_flag & (1 << j));
280 	}
281 
282 	/* 7-61: calculate num_negative_pics, delta_poc_s0 and used_by_curr_pic_s0 */
283 	i = 0;
284 	for (j = (ref_rps->num_positive_pics - 1); j >= 0; j--) {
285 		dPoc = ref_rps->delta_poc_s1[j] + delta_rps;
286 		if (dPoc < 0 && use_delta_flag[ref_rps->num_negative_pics + j]) {
287 			st_rps->delta_poc_s0[i] = dPoc;
288 			st_rps->used_by_curr_pic_s0[i++] =
289 				used_by_curr_pic_flag[ref_rps->num_negative_pics + j];
290 		}
291 	}
292 	if (delta_rps < 0 && use_delta_flag[ref_rps->num_delta_pocs]) {
293 		st_rps->delta_poc_s0[i] = delta_rps;
294 		st_rps->used_by_curr_pic_s0[i++] = used_by_curr_pic_flag[ref_rps->num_delta_pocs];
295 	}
296 	for (j = 0; j < ref_rps->num_negative_pics; j++) {
297 		dPoc = ref_rps->delta_poc_s0[j] + delta_rps;
298 		if (dPoc < 0 && use_delta_flag[j]) {
299 			st_rps->delta_poc_s0[i] = dPoc;
300 			st_rps->used_by_curr_pic_s0[i++] = used_by_curr_pic_flag[j];
301 		}
302 	}
303 	st_rps->num_negative_pics = i;
304 
305 	/* 7-62: calculate num_positive_pics, delta_poc_s1 and used_by_curr_pic_s1 */
306 	i = 0;
307 	for (j = (ref_rps->num_negative_pics - 1); j >= 0; j--) {
308 		dPoc = ref_rps->delta_poc_s0[j] + delta_rps;
309 		if (dPoc > 0 && use_delta_flag[j]) {
310 			st_rps->delta_poc_s1[i] = dPoc;
311 			st_rps->used_by_curr_pic_s1[i++] = used_by_curr_pic_flag[j];
312 		}
313 	}
314 	if (delta_rps > 0 && use_delta_flag[ref_rps->num_delta_pocs]) {
315 		st_rps->delta_poc_s1[i] = delta_rps;
316 		st_rps->used_by_curr_pic_s1[i++] = used_by_curr_pic_flag[ref_rps->num_delta_pocs];
317 	}
318 	for (j = 0; j < ref_rps->num_positive_pics; j++) {
319 		dPoc = ref_rps->delta_poc_s1[j] + delta_rps;
320 		if (dPoc > 0 && use_delta_flag[ref_rps->num_negative_pics + j]) {
321 			st_rps->delta_poc_s1[i] = dPoc;
322 			st_rps->used_by_curr_pic_s1[i++] =
323 				used_by_curr_pic_flag[ref_rps->num_negative_pics + j];
324 		}
325 	}
326 	st_rps->num_positive_pics = i;
327 
328 	st_rps->num_delta_pocs = st_rps->num_positive_pics + st_rps->num_negative_pics;
329 }
330 
331 /*
332  * Compute the short term ref pic set parameters based on the control's data.
333  */
st_ref_pic_set_calculate(struct rkvdec_hevc_run * run,int idx,struct calculated_rps_st_set * calculated_rps_st_sets)334 static void st_ref_pic_set_calculate(struct rkvdec_hevc_run *run, int idx,
335 				     struct calculated_rps_st_set *calculated_rps_st_sets)
336 {
337 	const struct v4l2_ctrl_hevc_ext_sps_st_rps *rps_data = &run->ext_sps_st_rps[idx];
338 	struct calculated_rps_st_set *st_rps = &calculated_rps_st_sets[idx];
339 	int j, i = 0;
340 
341 	/* 7-63 */
342 	st_rps->num_negative_pics = rps_data->num_negative_pics;
343 	/* 7-64 */
344 	st_rps->num_positive_pics = rps_data->num_positive_pics;
345 
346 	for (i = 0; i < st_rps->num_negative_pics; i++) {
347 		/* 7-65 */
348 		st_rps->used_by_curr_pic_s0[i] = !!(rps_data->used_by_curr_pic & (1 << i));
349 
350 		if (i == 0) {
351 			/* 7-67 */
352 			st_rps->delta_poc_s0[i] = -(rps_data->delta_poc_s0_minus1[i] + 1);
353 		} else {
354 			/* 7-69 */
355 			st_rps->delta_poc_s0[i] =
356 				st_rps->delta_poc_s0[i - 1] -
357 				(rps_data->delta_poc_s0_minus1[i] + 1);
358 		}
359 	}
360 
361 	for (j = 0; j < st_rps->num_positive_pics; j++) {
362 		/* 7-66 */
363 		st_rps->used_by_curr_pic_s1[j] = !!(rps_data->used_by_curr_pic & (1 << (i + j)));
364 
365 		if (j == 0) {
366 			/* 7-68 */
367 			st_rps->delta_poc_s1[j] = rps_data->delta_poc_s1_minus1[j] + 1;
368 		} else {
369 			/* 7-70 */
370 			st_rps->delta_poc_s1[j] =
371 				st_rps->delta_poc_s1[j - 1] +
372 				(rps_data->delta_poc_s1_minus1[j] + 1);
373 		}
374 	}
375 
376 	/* 7-71 */
377 	st_rps->num_delta_pocs = st_rps->num_positive_pics + st_rps->num_negative_pics;
378 }
379 
rkvdec_hevc_prepare_hw_st_rps(struct rkvdec_hevc_run * run,struct rkvdec_rps * rps,struct v4l2_ctrl_hevc_ext_sps_st_rps * cache)380 static void rkvdec_hevc_prepare_hw_st_rps(struct rkvdec_hevc_run *run, struct rkvdec_rps *rps,
381 					  struct v4l2_ctrl_hevc_ext_sps_st_rps *cache)
382 {
383 	int idx;
384 
385 	if (!run->ext_sps_st_rps)
386 		return;
387 
388 	if (!memcmp(cache, run->ext_sps_st_rps, sizeof(struct v4l2_ctrl_hevc_ext_sps_st_rps)))
389 		return;
390 
391 	struct calculated_rps_st_set *calculated_rps_st_sets =
392 		kzalloc(sizeof(struct calculated_rps_st_set) *
393 			run->sps->num_short_term_ref_pic_sets, GFP_KERNEL);
394 
395 	for (idx = 0; idx < run->sps->num_short_term_ref_pic_sets; idx++) {
396 		const struct v4l2_ctrl_hevc_ext_sps_st_rps *rps_data = &run->ext_sps_st_rps[idx];
397 
398 		if (rps_data->flags & V4L2_HEVC_EXT_SPS_ST_RPS_FLAG_INTER_REF_PIC_SET_PRED)
399 			st_ref_pic_set_prediction(run, idx, calculated_rps_st_sets);
400 		else
401 			st_ref_pic_set_calculate(run, idx, calculated_rps_st_sets);
402 	}
403 
404 	rkvdec_hevc_assemble_hw_st_rps(run, rps, calculated_rps_st_sets);
405 
406 	kfree(calculated_rps_st_sets);
407 
408 	memcpy(cache, run->ext_sps_st_rps, sizeof(struct v4l2_ctrl_hevc_ext_sps_st_rps));
409 }
410 
rkvdec_hevc_assemble_hw_rps(struct rkvdec_hevc_run * run,struct rkvdec_rps * rps,struct v4l2_ctrl_hevc_ext_sps_st_rps * st_cache)411 void rkvdec_hevc_assemble_hw_rps(struct rkvdec_hevc_run *run, struct rkvdec_rps *rps,
412 				 struct v4l2_ctrl_hevc_ext_sps_st_rps *st_cache)
413 {
414 	rkvdec_hevc_prepare_hw_st_rps(run, rps, st_cache);
415 	rkvdec_hevc_assemble_hw_lt_rps(run, rps);
416 }
417 
418 struct vb2_buffer *
get_ref_buf(struct rkvdec_ctx * ctx,struct rkvdec_hevc_run * run,unsigned int dpb_idx)419 get_ref_buf(struct rkvdec_ctx *ctx, struct rkvdec_hevc_run *run,
420 	    unsigned int dpb_idx)
421 {
422 	struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
423 	const struct v4l2_ctrl_hevc_decode_params *decode_params = run->decode_params;
424 	const struct v4l2_hevc_dpb_entry *dpb = decode_params->dpb;
425 	struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q;
426 	struct vb2_buffer *buf = NULL;
427 
428 	if (dpb_idx < decode_params->num_active_dpb_entries)
429 		buf = vb2_find_buffer(cap_q, dpb[dpb_idx].timestamp);
430 
431 	/*
432 	 * If a DPB entry is unused or invalid, the address of current destination
433 	 * buffer is returned.
434 	 */
435 	if (!buf)
436 		return &run->base.bufs.dst->vb2_buf;
437 
438 	return buf;
439 }
440 
441 #define RKVDEC_HEVC_MAX_DEPTH_IN_BYTES		2
442 
rkvdec_hevc_adjust_fmt(struct rkvdec_ctx * ctx,struct v4l2_format * f)443 int rkvdec_hevc_adjust_fmt(struct rkvdec_ctx *ctx, struct v4l2_format *f)
444 {
445 	struct v4l2_pix_format_mplane *fmt = &f->fmt.pix_mp;
446 
447 	fmt->num_planes = 1;
448 	if (!fmt->plane_fmt[0].sizeimage)
449 		fmt->plane_fmt[0].sizeimage = fmt->width * fmt->height *
450 					      RKVDEC_HEVC_MAX_DEPTH_IN_BYTES;
451 	return 0;
452 }
453 
rkvdec_hevc_get_image_fmt(struct rkvdec_ctx * ctx,struct v4l2_ctrl * ctrl)454 enum rkvdec_image_fmt rkvdec_hevc_get_image_fmt(struct rkvdec_ctx *ctx,
455 						struct v4l2_ctrl *ctrl)
456 {
457 	const struct v4l2_ctrl_hevc_sps *sps = ctrl->p_new.p_hevc_sps;
458 
459 	if (ctrl->id != V4L2_CID_STATELESS_HEVC_SPS)
460 		return RKVDEC_IMG_FMT_ANY;
461 
462 	if (sps->bit_depth_luma_minus8 == 0) {
463 		if (sps->chroma_format_idc == 2)
464 			return RKVDEC_IMG_FMT_422_8BIT;
465 		else
466 			return RKVDEC_IMG_FMT_420_8BIT;
467 	} else if (sps->bit_depth_luma_minus8 == 2) {
468 		if (sps->chroma_format_idc == 2)
469 			return RKVDEC_IMG_FMT_422_10BIT;
470 		else
471 			return RKVDEC_IMG_FMT_420_10BIT;
472 	}
473 
474 	return RKVDEC_IMG_FMT_ANY;
475 }
476 
rkvdec_hevc_run_preamble(struct rkvdec_ctx * ctx,struct rkvdec_hevc_run * run)477 void rkvdec_hevc_run_preamble(struct rkvdec_ctx *ctx,
478 			      struct rkvdec_hevc_run *run)
479 {
480 	struct v4l2_ctrl *ctrl;
481 
482 	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
483 			      V4L2_CID_STATELESS_HEVC_DECODE_PARAMS);
484 	run->decode_params = ctrl ? ctrl->p_cur.p : NULL;
485 	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
486 			      V4L2_CID_STATELESS_HEVC_SLICE_PARAMS);
487 	run->slices_params = ctrl ? ctrl->p_cur.p : NULL;
488 	run->num_slices = ctrl ? ctrl->new_elems : 0;
489 	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
490 			      V4L2_CID_STATELESS_HEVC_SPS);
491 	run->sps = ctrl ? ctrl->p_cur.p : NULL;
492 	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
493 			      V4L2_CID_STATELESS_HEVC_PPS);
494 	run->pps = ctrl ? ctrl->p_cur.p : NULL;
495 	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
496 			      V4L2_CID_STATELESS_HEVC_SCALING_MATRIX);
497 	run->scaling_matrix = ctrl ? ctrl->p_cur.p : NULL;
498 
499 	if (ctx->has_sps_st_rps) {
500 		ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
501 				      V4L2_CID_STATELESS_HEVC_EXT_SPS_ST_RPS);
502 		run->ext_sps_st_rps = ctrl ? ctrl->p_cur.p : NULL;
503 	} else {
504 		run->ext_sps_st_rps = NULL;
505 	}
506 	if (ctx->has_sps_lt_rps) {
507 		ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
508 				      V4L2_CID_STATELESS_HEVC_EXT_SPS_LT_RPS);
509 		run->ext_sps_lt_rps = ctrl ? ctrl->p_cur.p : NULL;
510 	} else {
511 		run->ext_sps_lt_rps = NULL;
512 	}
513 
514 	rkvdec_run_preamble(ctx, &run->base);
515 }
516