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