1 /*
2 * Copyright © 2021 Red Hat
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include "vk_video.h"
25 #include "vk_util.h"
26 #include "vk_log.h"
27 #include "vk_alloc.h"
28 #include "vk_device.h"
29 #include "util/vl_rbsp.h"
30
31 VkResult
vk_video_session_init(struct vk_device * device,struct vk_video_session * vid,const VkVideoSessionCreateInfoKHR * create_info)32 vk_video_session_init(struct vk_device *device,
33 struct vk_video_session *vid,
34 const VkVideoSessionCreateInfoKHR *create_info)
35 {
36 vk_object_base_init(device, &vid->base, VK_OBJECT_TYPE_VIDEO_SESSION_KHR);
37
38 vid->op = create_info->pVideoProfile->videoCodecOperation;
39 vid->max_coded = create_info->maxCodedExtent;
40 vid->picture_format = create_info->pictureFormat;
41 vid->ref_format = create_info->referencePictureFormat;
42 vid->max_dpb_slots = create_info->maxDpbSlots;
43 vid->max_active_ref_pics = create_info->maxActiveReferencePictures;
44
45 switch (vid->op) {
46 case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR: {
47 const struct VkVideoDecodeH264ProfileInfoKHR *h264_profile =
48 vk_find_struct_const(create_info->pVideoProfile->pNext,
49 VIDEO_DECODE_H264_PROFILE_INFO_KHR);
50 vid->h264.profile_idc = h264_profile->stdProfileIdc;
51 break;
52 }
53 case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR: {
54 const struct VkVideoDecodeH265ProfileInfoKHR *h265_profile =
55 vk_find_struct_const(create_info->pVideoProfile->pNext,
56 VIDEO_DECODE_H265_PROFILE_INFO_KHR);
57 vid->h265.profile_idc = h265_profile->stdProfileIdc;
58 break;
59 }
60 default:
61 return VK_ERROR_FEATURE_NOT_PRESENT;
62 }
63
64 return VK_SUCCESS;
65 }
66
67 #define FIND(PARAMSET, SS, SET, ID) \
68 static PARAMSET *find_##SS##_##SET(const struct vk_video_session_parameters *params, uint32_t id) { \
69 for (unsigned i = 0; i < params->SS.SET##_count; i++) { \
70 if (params->SS.SET[i].ID == id) \
71 return ¶ms->SS.SET[i]; \
72 } \
73 return NULL; \
74 } \
75 \
76 static void add_##SS##_##SET(struct vk_video_session_parameters *params, \
77 const PARAMSET *new_set, bool noreplace) { \
78 PARAMSET *set = find_##SS##_##SET(params, new_set->ID); \
79 if (set) { \
80 if (noreplace) \
81 return; \
82 *set = *new_set; \
83 } else \
84 params->SS.SET[params->SS.SET##_count++] = *new_set; \
85 } \
86 \
87 static VkResult update_##SS##_##SET(struct vk_video_session_parameters *params, \
88 uint32_t count, const PARAMSET *updates) { \
89 if (params->SS.SET##_count + count >= params->SS.max_##SET##_count) \
90 return VK_ERROR_TOO_MANY_OBJECTS; \
91 typed_memcpy(¶ms->SS.SET[params->SS.SET##_count], updates, count); \
92 params->SS.SET##_count += count; \
93 return VK_SUCCESS; \
94 }
95
FIND(StdVideoH264SequenceParameterSet,h264_dec,std_sps,seq_parameter_set_id)96 FIND(StdVideoH264SequenceParameterSet, h264_dec, std_sps, seq_parameter_set_id)
97 FIND(StdVideoH264PictureParameterSet, h264_dec, std_pps, pic_parameter_set_id)
98 FIND(StdVideoH265VideoParameterSet, h265_dec, std_vps, vps_video_parameter_set_id)
99 FIND(StdVideoH265SequenceParameterSet, h265_dec, std_sps, sps_seq_parameter_set_id)
100 FIND(StdVideoH265PictureParameterSet, h265_dec, std_pps, pps_pic_parameter_set_id)
101
102 static void
103 init_add_h264_session_parameters(struct vk_video_session_parameters *params,
104 const struct VkVideoDecodeH264SessionParametersAddInfoKHR *h264_add,
105 const struct vk_video_session_parameters *templ)
106 {
107 unsigned i;
108
109 if (h264_add) {
110 for (i = 0; i < h264_add->stdSPSCount; i++) {
111 add_h264_dec_std_sps(params, &h264_add->pStdSPSs[i], false);
112 }
113 }
114 if (templ) {
115 for (i = 0; i < templ->h264_dec.std_sps_count; i++) {
116 add_h264_dec_std_sps(params, &templ->h264_dec.std_sps[i], true);
117 }
118 }
119
120 if (h264_add) {
121 for (i = 0; i < h264_add->stdPPSCount; i++) {
122 add_h264_dec_std_pps(params, &h264_add->pStdPPSs[i], false);
123 }
124 }
125 if (templ) {
126 for (i = 0; i < templ->h264_dec.std_pps_count; i++) {
127 add_h264_dec_std_pps(params, &templ->h264_dec.std_pps[i], true);
128 }
129 }
130 }
131
132 static void
init_add_h265_session_parameters(struct vk_video_session_parameters * params,const struct VkVideoDecodeH265SessionParametersAddInfoKHR * h265_add,const struct vk_video_session_parameters * templ)133 init_add_h265_session_parameters(struct vk_video_session_parameters *params,
134 const struct VkVideoDecodeH265SessionParametersAddInfoKHR *h265_add,
135 const struct vk_video_session_parameters *templ)
136 {
137 unsigned i;
138
139 if (h265_add) {
140 for (i = 0; i < h265_add->stdVPSCount; i++) {
141 add_h265_dec_std_vps(params, &h265_add->pStdVPSs[i], false);
142 }
143 }
144 if (templ) {
145 for (i = 0; i < templ->h265_dec.std_vps_count; i++) {
146 add_h265_dec_std_vps(params, &templ->h265_dec.std_vps[i], true);
147 }
148 }
149 if (h265_add) {
150 for (i = 0; i < h265_add->stdSPSCount; i++) {
151 add_h265_dec_std_sps(params, &h265_add->pStdSPSs[i], false);
152 }
153 }
154 if (templ) {
155 for (i = 0; i < templ->h265_dec.std_sps_count; i++) {
156 add_h265_dec_std_sps(params, &templ->h265_dec.std_sps[i], true);
157 }
158 }
159
160 if (h265_add) {
161 for (i = 0; i < h265_add->stdPPSCount; i++) {
162 add_h265_dec_std_pps(params, &h265_add->pStdPPSs[i], false);
163 }
164 }
165 if (templ) {
166 for (i = 0; i < templ->h265_dec.std_pps_count; i++) {
167 add_h265_dec_std_pps(params, &templ->h265_dec.std_pps[i], true);
168 }
169 }
170 }
171
172 VkResult
vk_video_session_parameters_init(struct vk_device * device,struct vk_video_session_parameters * params,const struct vk_video_session * vid,const struct vk_video_session_parameters * templ,const VkVideoSessionParametersCreateInfoKHR * create_info)173 vk_video_session_parameters_init(struct vk_device *device,
174 struct vk_video_session_parameters *params,
175 const struct vk_video_session *vid,
176 const struct vk_video_session_parameters *templ,
177 const VkVideoSessionParametersCreateInfoKHR *create_info)
178 {
179 memset(params, 0, sizeof(*params));
180 vk_object_base_init(device, ¶ms->base, VK_OBJECT_TYPE_VIDEO_SESSION_PARAMETERS_KHR);
181
182 params->op = vid->op;
183
184 switch (vid->op) {
185 case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR: {
186 const struct VkVideoDecodeH264SessionParametersCreateInfoKHR *h264_create =
187 vk_find_struct_const(create_info->pNext, VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_KHR);
188
189 params->h264_dec.max_std_sps_count = h264_create->maxStdSPSCount;
190 params->h264_dec.max_std_pps_count = h264_create->maxStdPPSCount;
191
192 uint32_t sps_size = params->h264_dec.max_std_sps_count * sizeof(StdVideoH264SequenceParameterSet);
193 uint32_t pps_size = params->h264_dec.max_std_pps_count * sizeof(StdVideoH264PictureParameterSet);
194
195 params->h264_dec.std_sps = vk_alloc(&device->alloc, sps_size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
196 params->h264_dec.std_pps = vk_alloc(&device->alloc, pps_size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
197 if (!params->h264_dec.std_sps || !params->h264_dec.std_pps) {
198 vk_free(&device->alloc, params->h264_dec.std_sps);
199 vk_free(&device->alloc, params->h264_dec.std_pps);
200 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
201 }
202
203 init_add_h264_session_parameters(params, h264_create->pParametersAddInfo, templ);
204 break;
205 }
206 case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR: {
207 const struct VkVideoDecodeH265SessionParametersCreateInfoKHR *h265_create =
208 vk_find_struct_const(create_info->pNext, VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_KHR);
209
210 params->h265_dec.max_std_vps_count = h265_create->maxStdVPSCount;
211 params->h265_dec.max_std_sps_count = h265_create->maxStdSPSCount;
212 params->h265_dec.max_std_pps_count = h265_create->maxStdPPSCount;
213
214 uint32_t vps_size = params->h265_dec.max_std_vps_count * sizeof(StdVideoH265VideoParameterSet);
215 uint32_t sps_size = params->h265_dec.max_std_sps_count * sizeof(StdVideoH265SequenceParameterSet);
216 uint32_t pps_size = params->h265_dec.max_std_pps_count * sizeof(StdVideoH265PictureParameterSet);
217
218 params->h265_dec.std_vps = vk_alloc(&device->alloc, vps_size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
219 params->h265_dec.std_sps = vk_alloc(&device->alloc, sps_size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
220 params->h265_dec.std_pps = vk_alloc(&device->alloc, pps_size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
221 if (!params->h265_dec.std_sps || !params->h265_dec.std_pps || !params->h265_dec.std_vps) {
222 vk_free(&device->alloc, params->h265_dec.std_vps);
223 vk_free(&device->alloc, params->h265_dec.std_sps);
224 vk_free(&device->alloc, params->h265_dec.std_pps);
225 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
226 }
227
228 init_add_h265_session_parameters(params, h265_create->pParametersAddInfo, templ);
229 break;
230 }
231 default:
232 unreachable("Unsupported video codec operation");
233 break;
234 }
235 return VK_SUCCESS;
236 }
237
238 void
vk_video_session_parameters_finish(struct vk_device * device,struct vk_video_session_parameters * params)239 vk_video_session_parameters_finish(struct vk_device *device,
240 struct vk_video_session_parameters *params)
241 {
242 switch (params->op) {
243 case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR:
244 vk_free(&device->alloc, params->h264_dec.std_sps);
245 vk_free(&device->alloc, params->h264_dec.std_pps);
246 break;
247 case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR:
248 vk_free(&device->alloc, params->h265_dec.std_vps);
249 vk_free(&device->alloc, params->h265_dec.std_sps);
250 vk_free(&device->alloc, params->h265_dec.std_pps);
251 break;
252 default:
253 break;
254 }
255 vk_object_base_finish(¶ms->base);
256 }
257
258 static VkResult
update_sps(struct vk_video_session_parameters * params,uint32_t count,const StdVideoH264SequenceParameterSet * adds)259 update_sps(struct vk_video_session_parameters *params,
260 uint32_t count, const StdVideoH264SequenceParameterSet *adds)
261 {
262 if (params->h264_dec.std_sps_count + count >= params->h264_dec.max_std_sps_count)
263 return VK_ERROR_TOO_MANY_OBJECTS;
264
265 typed_memcpy(¶ms->h264_dec.std_sps[params->h264_dec.std_sps_count], adds, count);
266 params->h264_dec.std_sps_count += count;
267 return VK_SUCCESS;
268 }
269
270 static VkResult
update_h264_session_parameters(struct vk_video_session_parameters * params,const struct VkVideoDecodeH264SessionParametersAddInfoKHR * h264_add)271 update_h264_session_parameters(struct vk_video_session_parameters *params,
272 const struct VkVideoDecodeH264SessionParametersAddInfoKHR *h264_add)
273 {
274 VkResult result = VK_SUCCESS;
275
276 result = update_h264_dec_std_sps(params, h264_add->stdSPSCount, h264_add->pStdSPSs);
277 if (result != VK_SUCCESS)
278 return result;
279
280 result = update_h264_dec_std_pps(params, h264_add->stdPPSCount, h264_add->pStdPPSs);
281 return result;
282 }
283
284 static VkResult
update_h265_session_parameters(struct vk_video_session_parameters * params,const struct VkVideoDecodeH265SessionParametersAddInfoKHR * h265_add)285 update_h265_session_parameters(struct vk_video_session_parameters *params,
286 const struct VkVideoDecodeH265SessionParametersAddInfoKHR *h265_add)
287 {
288 VkResult result = VK_SUCCESS;
289 result = update_h265_dec_std_vps(params, h265_add->stdVPSCount, h265_add->pStdVPSs);
290 if (result != VK_SUCCESS)
291 return result;
292
293 result = update_h265_dec_std_sps(params, h265_add->stdSPSCount, h265_add->pStdSPSs);
294 if (result != VK_SUCCESS)
295 return result;
296
297 result = update_h265_dec_std_pps(params, h265_add->stdPPSCount, h265_add->pStdPPSs);
298 return result;
299 }
300
301 VkResult
vk_video_session_parameters_update(struct vk_video_session_parameters * params,const VkVideoSessionParametersUpdateInfoKHR * update)302 vk_video_session_parameters_update(struct vk_video_session_parameters *params,
303 const VkVideoSessionParametersUpdateInfoKHR *update)
304 {
305 /* 39.6.5. Decoder Parameter Sets -
306 * "The provided H.264 SPS/PPS parameters must be within the limits specified during decoder
307 * creation for the decoder specified in VkVideoSessionParametersCreateInfoKHR."
308 */
309
310 /*
311 * There is no need to deduplicate here.
312 * videoSessionParameters must not already contain a StdVideoH264PictureParameterSet entry with
313 * both seq_parameter_set_id and pic_parameter_set_id matching any of the elements of
314 * VkVideoDecodeH264SessionParametersAddInfoKHR::pStdPPS
315 */
316 VkResult result = VK_SUCCESS;
317
318 switch (params->op) {
319 case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR: {
320 const struct VkVideoDecodeH264SessionParametersAddInfoKHR *h264_add =
321 vk_find_struct_const(update->pNext, VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_KHR);
322 return update_h264_session_parameters(params, h264_add);
323 }
324 case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR: {
325 const struct VkVideoDecodeH265SessionParametersAddInfoKHR *h265_add =
326 vk_find_struct_const(update->pNext, VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_KHR);
327
328 return update_h265_session_parameters(params, h265_add);
329 }
330 default:
331 unreachable("Unknown codec\n");
332 }
333 return result;
334 }
335
336 const uint8_t h264_scaling_list_default_4x4_intra[] =
337 {
338 /* Table 7-3 - Default_4x4_Intra */
339 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42
340 };
341
342 const uint8_t h264_scaling_list_default_4x4_inter[] =
343 {
344 /* Table 7-3 - Default_4x4_Inter */
345 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34
346 };
347
348 const uint8_t h264_scaling_list_default_8x8_intra[] =
349 {
350 /* Table 7-4 - Default_8x8_Intra */
351 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23,
352 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27,
353 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31,
354 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42,
355 };
356
357 const uint8_t h264_scaling_list_default_8x8_inter[] =
358 {
359 /* Table 7-4 - Default_8x8_Inter */
360 9 , 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21,
361 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24,
362 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27,
363 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35,
364 };
365
366 void
vk_video_derive_h264_scaling_list(const StdVideoH264SequenceParameterSet * sps,const StdVideoH264PictureParameterSet * pps,StdVideoH264ScalingLists * list)367 vk_video_derive_h264_scaling_list(const StdVideoH264SequenceParameterSet *sps,
368 const StdVideoH264PictureParameterSet *pps,
369 StdVideoH264ScalingLists *list)
370 {
371 StdVideoH264ScalingLists temp;
372
373 /* derive SPS scaling list first, because PPS may depend on it in fall-back
374 * rule B */
375 if (sps->flags.seq_scaling_matrix_present_flag)
376 {
377 for (int i = 0; i < STD_VIDEO_H264_SCALING_LIST_4X4_NUM_LISTS; i++)
378 {
379 if (sps->pScalingLists->scaling_list_present_mask & (1 << i))
380 memcpy(temp.ScalingList4x4[i],
381 pps->pScalingLists->ScalingList4x4[i],
382 STD_VIDEO_H264_SCALING_LIST_4X4_NUM_ELEMENTS);
383 else /* fall-back rule A */
384 {
385 if (i == 0)
386 memcpy(temp.ScalingList4x4[i],
387 h264_scaling_list_default_4x4_intra,
388 STD_VIDEO_H264_SCALING_LIST_4X4_NUM_ELEMENTS);
389 else if (i == 3)
390 memcpy(temp.ScalingList4x4[i],
391 h264_scaling_list_default_4x4_inter,
392 STD_VIDEO_H264_SCALING_LIST_4X4_NUM_ELEMENTS);
393 else
394 memcpy(temp.ScalingList4x4[i],
395 temp.ScalingList4x4[i - 1],
396 STD_VIDEO_H264_SCALING_LIST_4X4_NUM_ELEMENTS);
397 }
398 }
399
400 for (int j = 0; j < STD_VIDEO_H264_SCALING_LIST_8X8_NUM_LISTS; j++)
401 {
402 int i = j + STD_VIDEO_H264_SCALING_LIST_4X4_NUM_LISTS;
403 if (sps->pScalingLists->scaling_list_present_mask & (1 << i))
404 memcpy(temp.ScalingList8x8[j], pps->pScalingLists->ScalingList8x8[j],
405 STD_VIDEO_H264_SCALING_LIST_8X8_NUM_ELEMENTS);
406 else /* fall-back rule A */
407 {
408 if (i == 6)
409 memcpy(temp.ScalingList8x8[j],
410 h264_scaling_list_default_8x8_intra,
411 STD_VIDEO_H264_SCALING_LIST_8X8_NUM_ELEMENTS);
412 else if (i == 7)
413 memcpy(temp.ScalingList8x8[j],
414 h264_scaling_list_default_8x8_inter,
415 STD_VIDEO_H264_SCALING_LIST_8X8_NUM_ELEMENTS);
416 else
417 memcpy(temp.ScalingList8x8[j], temp.ScalingList8x8[j - 2],
418 STD_VIDEO_H264_SCALING_LIST_8X8_NUM_ELEMENTS);
419 }
420 }
421 }
422 else
423 {
424 memset(temp.ScalingList4x4, 0x10,
425 STD_VIDEO_H264_SCALING_LIST_4X4_NUM_LISTS *
426 STD_VIDEO_H264_SCALING_LIST_4X4_NUM_ELEMENTS);
427 memset(temp.ScalingList8x8, 0x10,
428 STD_VIDEO_H264_SCALING_LIST_8X8_NUM_LISTS *
429 STD_VIDEO_H264_SCALING_LIST_8X8_NUM_ELEMENTS);
430 }
431
432 if (pps->flags.pic_scaling_matrix_present_flag)
433 {
434 for (int i = 0; i < STD_VIDEO_H264_SCALING_LIST_4X4_NUM_LISTS; i++)
435 {
436 if (pps->pScalingLists->scaling_list_present_mask & (1 << i))
437 memcpy(list->ScalingList4x4[i], pps->pScalingLists->ScalingList4x4[i],
438 STD_VIDEO_H264_SCALING_LIST_4X4_NUM_ELEMENTS);
439 else if (sps->flags.seq_scaling_matrix_present_flag) /* fall-back rule B */
440 {
441 if (i == 0 || i == 3)
442 memcpy(list->ScalingList4x4[i], temp.ScalingList4x4[i],
443 STD_VIDEO_H264_SCALING_LIST_4X4_NUM_ELEMENTS);
444 else
445 memcpy(list->ScalingList4x4[i], list->ScalingList4x4[i - 1],
446 STD_VIDEO_H264_SCALING_LIST_4X4_NUM_ELEMENTS);
447 }
448 else /* fall-back rule A */
449 {
450 if (i == 0)
451 memcpy(list->ScalingList4x4[i],
452 h264_scaling_list_default_4x4_intra,
453 STD_VIDEO_H264_SCALING_LIST_4X4_NUM_ELEMENTS);
454 else if (i == 3)
455 memcpy(list->ScalingList4x4[i],
456 h264_scaling_list_default_4x4_inter,
457 STD_VIDEO_H264_SCALING_LIST_4X4_NUM_ELEMENTS);
458 else
459 memcpy(list->ScalingList4x4[i],
460 list->ScalingList4x4[i - 1],
461 STD_VIDEO_H264_SCALING_LIST_4X4_NUM_ELEMENTS);
462 }
463 }
464
465 for (int j = 0; j < STD_VIDEO_H264_SCALING_LIST_8X8_NUM_LISTS; j++)
466 {
467 int i = j + STD_VIDEO_H264_SCALING_LIST_4X4_NUM_LISTS;
468 if (pps->pScalingLists->scaling_list_present_mask & (1 << i))
469 memcpy(list->ScalingList8x8[j], pps->pScalingLists->ScalingList8x8[j],
470 STD_VIDEO_H264_SCALING_LIST_8X8_NUM_ELEMENTS);
471 else if (sps->flags.seq_scaling_matrix_present_flag) /* fall-back rule B */
472 {
473 if (i == 6 || i == 7)
474 memcpy(list->ScalingList8x8[j], temp.ScalingList8x8[j],
475 STD_VIDEO_H264_SCALING_LIST_8X8_NUM_ELEMENTS);
476 else
477 memcpy(list->ScalingList8x8[j], list->ScalingList8x8[j - 2],
478 STD_VIDEO_H264_SCALING_LIST_8X8_NUM_ELEMENTS);
479 }
480 else /* fall-back rule A */
481 {
482 if (i == 6)
483 memcpy(list->ScalingList8x8[j],
484 h264_scaling_list_default_8x8_intra,
485 STD_VIDEO_H264_SCALING_LIST_8X8_NUM_ELEMENTS);
486 else if (i == 7)
487 memcpy(list->ScalingList8x8[j],
488 h264_scaling_list_default_8x8_inter,
489 STD_VIDEO_H264_SCALING_LIST_8X8_NUM_ELEMENTS);
490 else
491 memcpy(list->ScalingList8x8[j], list->ScalingList8x8[j - 2],
492 STD_VIDEO_H264_SCALING_LIST_8X8_NUM_ELEMENTS);
493 }
494 }
495 }
496 else
497 {
498 memcpy(list->ScalingList4x4, temp.ScalingList4x4,
499 STD_VIDEO_H264_SCALING_LIST_4X4_NUM_LISTS *
500 STD_VIDEO_H264_SCALING_LIST_4X4_NUM_ELEMENTS);
501 memcpy(list->ScalingList8x8, temp.ScalingList8x8,
502 STD_VIDEO_H264_SCALING_LIST_8X8_NUM_LISTS *
503 STD_VIDEO_H264_SCALING_LIST_8X8_NUM_ELEMENTS);
504 }
505 }
506
507 const StdVideoH264SequenceParameterSet *
vk_video_find_h264_dec_std_sps(const struct vk_video_session_parameters * params,uint32_t id)508 vk_video_find_h264_dec_std_sps(const struct vk_video_session_parameters *params,
509 uint32_t id)
510 {
511 return find_h264_dec_std_sps(params, id);
512 }
513
514 const StdVideoH264PictureParameterSet *
vk_video_find_h264_dec_std_pps(const struct vk_video_session_parameters * params,uint32_t id)515 vk_video_find_h264_dec_std_pps(const struct vk_video_session_parameters *params,
516 uint32_t id)
517 {
518 return find_h264_dec_std_pps(params, id);
519 }
520
521 const StdVideoH265VideoParameterSet *
vk_video_find_h265_dec_std_vps(const struct vk_video_session_parameters * params,uint32_t id)522 vk_video_find_h265_dec_std_vps(const struct vk_video_session_parameters *params,
523 uint32_t id)
524 {
525 return find_h265_dec_std_vps(params, id);
526 }
527
528 const StdVideoH265SequenceParameterSet *
vk_video_find_h265_dec_std_sps(const struct vk_video_session_parameters * params,uint32_t id)529 vk_video_find_h265_dec_std_sps(const struct vk_video_session_parameters *params,
530 uint32_t id)
531 {
532 return find_h265_dec_std_sps(params, id);
533 }
534
535 const StdVideoH265PictureParameterSet *
vk_video_find_h265_dec_std_pps(const struct vk_video_session_parameters * params,uint32_t id)536 vk_video_find_h265_dec_std_pps(const struct vk_video_session_parameters *params,
537 uint32_t id)
538 {
539 return find_h265_dec_std_pps(params, id);
540 }
541
542 int
vk_video_h265_poc_by_slot(const struct VkVideoDecodeInfoKHR * frame_info,int slot)543 vk_video_h265_poc_by_slot(const struct VkVideoDecodeInfoKHR *frame_info, int slot)
544 {
545 for (unsigned i = 0; i < frame_info->referenceSlotCount; i++) {
546 const VkVideoDecodeH265DpbSlotInfoKHR *dpb_slot_info =
547 vk_find_struct_const(frame_info->pReferenceSlots[i].pNext, VIDEO_DECODE_H265_DPB_SLOT_INFO_KHR);
548 if (frame_info->pReferenceSlots[i].slotIndex == slot)
549 return dpb_slot_info->pStdReferenceInfo->PicOrderCntVal;
550 }
551
552 assert(0);
553
554 return 0;
555 }
556
557 void
vk_fill_video_h265_reference_info(const VkVideoDecodeInfoKHR * frame_info,const struct VkVideoDecodeH265PictureInfoKHR * pic,const struct vk_video_h265_slice_params * slice_params,struct vk_video_h265_reference ref_slots[][8])558 vk_fill_video_h265_reference_info(const VkVideoDecodeInfoKHR *frame_info,
559 const struct VkVideoDecodeH265PictureInfoKHR *pic,
560 const struct vk_video_h265_slice_params *slice_params,
561 struct vk_video_h265_reference ref_slots[][8])
562 {
563 uint8_t list_cnt = slice_params->slice_type == STD_VIDEO_H265_SLICE_TYPE_B ? 2 : 1;
564 uint8_t list_idx;
565 int i, j;
566
567 for (list_idx = 0; list_idx < list_cnt; list_idx++) {
568 /* The order is
569 * L0: Short term current before set - Short term current after set - long term current
570 * L1: Short term current after set - short term current before set - long term current
571 */
572 const uint8_t *rps[3] = {
573 list_idx ? pic->pStdPictureInfo->RefPicSetStCurrAfter : pic->pStdPictureInfo->RefPicSetStCurrBefore,
574 list_idx ? pic->pStdPictureInfo->RefPicSetStCurrBefore : pic->pStdPictureInfo->RefPicSetStCurrAfter,
575 pic->pStdPictureInfo->RefPicSetLtCurr
576 };
577
578 uint8_t ref_idx = 0;
579 for (i = 0; i < 3; i++) {
580 const uint8_t *cur_rps = rps[i];
581
582 for (j = 0; (cur_rps[j] != 0xff) && ((j + ref_idx) < 8); j++) {
583 ref_slots[list_idx][j + ref_idx].slot_index = cur_rps[j];
584 ref_slots[list_idx][j + ref_idx].pic_order_cnt = vk_video_h265_poc_by_slot(frame_info, cur_rps[j]);
585 }
586 ref_idx += j;
587 }
588
589 /* TODO: should handle cases where rpl_modification_flag is true. */
590 assert(!slice_params->rpl_modification_flag[0] && !slice_params->rpl_modification_flag[1]);
591 }
592 }
593
594 static void
h265_pred_weight_table(struct vk_video_h265_slice_params * params,struct vl_rbsp * rbsp,const StdVideoH265SequenceParameterSet * sps,StdVideoH265SliceType slice_type)595 h265_pred_weight_table(struct vk_video_h265_slice_params *params,
596 struct vl_rbsp *rbsp,
597 const StdVideoH265SequenceParameterSet *sps,
598 StdVideoH265SliceType slice_type)
599 {
600 unsigned chroma_array_type = sps->flags.separate_colour_plane_flag ? 0 : sps->chroma_format_idc;
601 unsigned i, j;
602
603 params->luma_log2_weight_denom = vl_rbsp_ue(rbsp);
604
605 assert(params->luma_log2_weight_denom >= 0 && params->luma_log2_weight_denom < 8);
606
607 if (chroma_array_type != 0) {
608 params->chroma_log2_weight_denom = params->luma_log2_weight_denom + vl_rbsp_se(rbsp);
609 assert(params->chroma_log2_weight_denom >= 0 && params->chroma_log2_weight_denom < 8);
610 }
611
612 for (i = 0; i < params->num_ref_idx_l0_active; ++i) {
613 params->luma_weight_l0_flag[i] = vl_rbsp_u(rbsp, 1);
614 if (!params->luma_weight_l0_flag[i]) {
615 params->luma_weight_l0[i] = 1 << params->luma_log2_weight_denom;
616 params->luma_offset_l0[i] = 0;
617 }
618 }
619
620 for (i = 0; i < params->num_ref_idx_l0_active; ++i) {
621 if (chroma_array_type == 0) {
622 params->chroma_weight_l0_flag[i] = 0;
623 } else {
624 params->chroma_weight_l0_flag[i] = vl_rbsp_u(rbsp, 1);
625 }
626 }
627
628 for (i = 0; i < params->num_ref_idx_l0_active; ++i) {
629 if (params->luma_weight_l0_flag[i]) {
630 params->delta_luma_weight_l0[i] = vl_rbsp_se(rbsp);
631 params->luma_weight_l0[i] = (1 << params->luma_log2_weight_denom) + params->delta_luma_weight_l0[i];
632 params->luma_offset_l0[i] = vl_rbsp_se(rbsp);
633 }
634
635 if (params->chroma_weight_l0_flag[i]) {
636 for (j = 0; j < 2; j++) {
637 params->delta_chroma_weight_l0[i][j] = vl_rbsp_se(rbsp);
638 params->delta_chroma_offset_l0[i][j] = vl_rbsp_se(rbsp);
639
640 params->chroma_weight_l0[i][j] =
641 (1 << params->chroma_log2_weight_denom) + params->delta_chroma_weight_l0[i][j];
642 params->chroma_offset_l0[i][j] = CLAMP(params->delta_chroma_offset_l0[i][j] -
643 ((128 * params->chroma_weight_l0[i][j]) >> params->chroma_log2_weight_denom) + 128, -128, 127);
644 }
645 } else {
646 for (j = 0; j < 2; j++) {
647 params->chroma_weight_l0[i][j] = 1 << params->chroma_log2_weight_denom;
648 params->chroma_offset_l0[i][j] = 0;
649 }
650 }
651 }
652
653 if (slice_type == STD_VIDEO_H265_SLICE_TYPE_B) {
654 for (i = 0; i < params->num_ref_idx_l1_active; ++i) {
655 params->luma_weight_l1_flag[i] = vl_rbsp_u(rbsp, 1);
656 if (!params->luma_weight_l1_flag[i]) {
657 params->luma_weight_l1[i] = 1 << params->luma_log2_weight_denom;
658 params->luma_offset_l1[i] = 0;
659 }
660 }
661
662 for (i = 0; i < params->num_ref_idx_l1_active; ++i) {
663 if (chroma_array_type == 0) {
664 params->chroma_weight_l1_flag[i] = 0;
665 } else {
666 params->chroma_weight_l1_flag[i] = vl_rbsp_u(rbsp, 1);
667 }
668 }
669
670 for (i = 0; i < params->num_ref_idx_l1_active; ++i) {
671 if (params->luma_weight_l1_flag[i]) {
672 params->delta_luma_weight_l1[i] = vl_rbsp_se(rbsp);
673 params->luma_weight_l1[i] =
674 (1 << params->luma_log2_weight_denom) + params->delta_luma_weight_l1[i];
675 params->luma_offset_l1[i] = vl_rbsp_se(rbsp);
676 }
677
678 if (params->chroma_weight_l1_flag[i]) {
679 for (j = 0; j < 2; j++) {
680 params->delta_chroma_weight_l1[i][j] = vl_rbsp_se(rbsp);
681 params->delta_chroma_offset_l1[i][j] = vl_rbsp_se(rbsp);
682
683 params->chroma_weight_l1[i][j] =
684 (1 << params->chroma_log2_weight_denom) + params->delta_chroma_weight_l1[i][j];
685 params->chroma_offset_l1[i][j] = CLAMP(params->delta_chroma_offset_l1[i][j] -
686 ((128 * params->chroma_weight_l1[i][j]) >> params->chroma_log2_weight_denom) + 128, -128, 127);
687 }
688 } else {
689 for (j = 0; j < 2; j++) {
690 params->chroma_weight_l1[i][j] = 1 << params->chroma_log2_weight_denom;
691 params->chroma_offset_l1[i][j] = 0;
692 }
693 }
694 }
695 }
696 }
697
698 void
vk_video_parse_h265_slice_header(const struct VkVideoDecodeInfoKHR * frame_info,const VkVideoDecodeH265PictureInfoKHR * pic_info,const StdVideoH265SequenceParameterSet * sps,const StdVideoH265PictureParameterSet * pps,void * slice_data,uint32_t slice_size,struct vk_video_h265_slice_params * params)699 vk_video_parse_h265_slice_header(const struct VkVideoDecodeInfoKHR *frame_info,
700 const VkVideoDecodeH265PictureInfoKHR *pic_info,
701 const StdVideoH265SequenceParameterSet *sps,
702 const StdVideoH265PictureParameterSet *pps,
703 void *slice_data,
704 uint32_t slice_size,
705 struct vk_video_h265_slice_params *params)
706 {
707 struct vl_vlc vlc;
708 const void *slice_headers[1] = { slice_data };
709 vl_vlc_init(&vlc, 1, slice_headers, &slice_size);
710
711 assert(vl_vlc_peekbits(&vlc, 24) == 0x000001);
712
713 vl_vlc_eatbits(&vlc, 24);
714
715 /* forbidden_zero_bit */
716 vl_vlc_eatbits(&vlc, 1);
717
718 if (vl_vlc_valid_bits(&vlc) < 15)
719 vl_vlc_fillbits(&vlc);
720
721 vl_vlc_get_uimsbf(&vlc, 6); /* nal_unit_type */
722 vl_vlc_get_uimsbf(&vlc, 6); /* nuh_layer_id */
723 vl_vlc_get_uimsbf(&vlc, 3); /* nuh_temporal_id_plus1 */
724
725 struct vl_rbsp rbsp;
726 vl_rbsp_init(&rbsp, &vlc, 128);
727
728 memset(params, 0, sizeof(*params));
729
730 params->slice_size = slice_size;
731 params->first_slice_segment_in_pic_flag = vl_rbsp_u(&rbsp, 1);
732
733 /* no_output_of_prior_pics_flag */
734 if (pic_info->pStdPictureInfo->flags.IrapPicFlag)
735 vl_rbsp_u(&rbsp, 1);
736
737 /* pps id */
738 vl_rbsp_ue(&rbsp);
739
740 if (!params->first_slice_segment_in_pic_flag) {
741 int size, num;
742 int bits_slice_segment_address = 0;
743
744 if (pps->flags.dependent_slice_segments_enabled_flag)
745 params->dependent_slice_segment = vl_rbsp_u(&rbsp, 1);
746
747 size = 1 << (sps->log2_min_luma_coding_block_size_minus3 + 3 +
748 sps->log2_diff_max_min_luma_coding_block_size);
749
750 num = ((sps->pic_width_in_luma_samples + size - 1) / size) *
751 ((sps->pic_height_in_luma_samples + size - 1) / size);
752
753 while (num > (1 << bits_slice_segment_address))
754 bits_slice_segment_address++;
755
756 /* slice_segment_address */
757 params->slice_segment_address = vl_rbsp_u(&rbsp, bits_slice_segment_address);
758 }
759
760 if (params->dependent_slice_segment)
761 return;
762
763 for (unsigned i = 0; i < pps->num_extra_slice_header_bits; ++i)
764 /* slice_reserved_flag */
765 vl_rbsp_u(&rbsp, 1);
766
767 /* slice_type */
768 params->slice_type = vl_rbsp_ue(&rbsp);
769
770 if (pps->flags.output_flag_present_flag)
771 /* pic output flag */
772 vl_rbsp_u(&rbsp, 1);
773
774 if (sps->flags.separate_colour_plane_flag)
775 /* colour_plane_id */
776 vl_rbsp_u(&rbsp, 2);
777
778 if (!pic_info->pStdPictureInfo->flags.IdrPicFlag) {
779 /* slice_pic_order_cnt_lsb */
780 params->pic_order_cnt_lsb =
781 vl_rbsp_u(&rbsp, sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
782
783 /* short_term_ref_pic_set_sps_flag */
784 if (!vl_rbsp_u(&rbsp, 1)) {
785 uint8_t rps_predict = 0;
786
787 if (sps->num_short_term_ref_pic_sets)
788 rps_predict = vl_rbsp_u(&rbsp, 1);
789
790 if (rps_predict) {
791 /* delta_idx */
792 vl_rbsp_ue(&rbsp);
793 /* delta_rps_sign */
794 vl_rbsp_u(&rbsp, 1);
795 /* abs_delta_rps */
796 vl_rbsp_ue(&rbsp);
797
798 for (int i = 0 ; i <= pic_info->pStdPictureInfo->NumDeltaPocsOfRefRpsIdx; i++) {
799 uint8_t used = vl_rbsp_u(&rbsp, 1);
800 if (!used)
801 vl_rbsp_u(&rbsp, 1);
802 }
803 } else {
804 /* num_negative_pics */
805 unsigned num_neg_pics = vl_rbsp_ue(&rbsp);
806 /* num_positive_pics */
807 unsigned num_pos_pics = vl_rbsp_ue(&rbsp);
808
809 for(unsigned i = 0 ; i < num_neg_pics; ++i) {
810 /* delta_poc_s0_minus1 */
811 vl_rbsp_ue(&rbsp);
812 /* used_by_curr_pic_s0_flag */
813 vl_rbsp_u(&rbsp, 1);
814 }
815
816 for(unsigned i = 0; i < num_pos_pics; ++i) {
817 /* delta_poc_s1_minus1 */
818 vl_rbsp_ue(&rbsp);
819 /* used_by_curr_pic_s0_flag */
820 vl_rbsp_u(&rbsp, 1);
821 }
822 }
823
824 } else {
825 unsigned num_st_rps = sps->num_short_term_ref_pic_sets;
826
827 int numbits = util_logbase2_ceil(num_st_rps);
828 if (numbits > 0)
829 /* short_term_ref_pic_set_idx */
830 vl_rbsp_u(&rbsp, numbits);
831 }
832
833 if (sps->flags.long_term_ref_pics_present_flag) {
834 unsigned num_lt_sps = 0;
835
836 if (sps->num_long_term_ref_pics_sps > 0)
837 num_lt_sps = vl_rbsp_ue(&rbsp);
838
839 unsigned num_lt_pics = vl_rbsp_ue(&rbsp);
840 unsigned num_refs = num_lt_pics + num_lt_sps;
841
842 for (unsigned i = 0; i < num_refs; i++) {
843 if (i < num_lt_sps) {
844 if (sps->num_long_term_ref_pics_sps > 1)
845 /* lt_idx_sps */
846 vl_rbsp_u(&rbsp,
847 util_logbase2_ceil(sps->num_long_term_ref_pics_sps));
848 } else {
849 /* poc_lsb_lt */
850 vl_rbsp_u(&rbsp, sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
851 /* used_by_curr_pic_lt_flag */
852 vl_rbsp_u(&rbsp, 1);
853 }
854
855 /* poc_msb_present */
856 if (vl_rbsp_u(&rbsp, 1)) {
857 /* delta_poc_msb_cycle_lt */
858 vl_rbsp_ue(&rbsp);
859 }
860 }
861 }
862
863 if (sps->flags.sps_temporal_mvp_enabled_flag)
864 params->temporal_mvp_enable = vl_rbsp_u(&rbsp, 1);
865 }
866
867 if (sps->flags.sample_adaptive_offset_enabled_flag) {
868 params->sao_luma_flag = vl_rbsp_u(&rbsp, 1);
869 if (sps->chroma_format_idc)
870 params->sao_chroma_flag = vl_rbsp_u(&rbsp, 1);
871 }
872
873 params->max_num_merge_cand = 5;
874
875 if (params->slice_type != STD_VIDEO_H265_SLICE_TYPE_I) {
876
877 params->num_ref_idx_l0_active = pps->num_ref_idx_l0_default_active_minus1 + 1;
878
879 if (params->slice_type == STD_VIDEO_H265_SLICE_TYPE_B)
880 params->num_ref_idx_l1_active = pps->num_ref_idx_l1_default_active_minus1 + 1;
881 else
882 params->num_ref_idx_l1_active = 0;
883
884 /* num_ref_idx_active_override_flag */
885 if (vl_rbsp_u(&rbsp, 1)) {
886 params->num_ref_idx_l0_active = vl_rbsp_ue(&rbsp) + 1;
887 if (params->slice_type == STD_VIDEO_H265_SLICE_TYPE_B)
888 params->num_ref_idx_l1_active = vl_rbsp_ue(&rbsp) + 1;
889 }
890
891 if (pps->flags.lists_modification_present_flag) {
892 params->rpl_modification_flag[0] = vl_rbsp_u(&rbsp, 1);
893 if (params->rpl_modification_flag[0]) {
894 for (int i = 0; i < params->num_ref_idx_l0_active; i++) {
895 /* list_entry_l0 */
896 vl_rbsp_u(&rbsp,
897 util_logbase2_ceil(params->num_ref_idx_l0_active + params->num_ref_idx_l1_active));
898 }
899 }
900
901 if (params->slice_type == STD_VIDEO_H265_SLICE_TYPE_B) {
902 params->rpl_modification_flag[1] = vl_rbsp_u(&rbsp, 1);
903 if (params->rpl_modification_flag[1]) {
904 for (int i = 0; i < params->num_ref_idx_l1_active; i++) {
905 /* list_entry_l1 */
906 vl_rbsp_u(&rbsp,
907 util_logbase2_ceil(params->num_ref_idx_l0_active + params->num_ref_idx_l1_active));
908 }
909 }
910 }
911 }
912
913 if (params->slice_type == STD_VIDEO_H265_SLICE_TYPE_B)
914 params->mvd_l1_zero_flag = vl_rbsp_u(&rbsp, 1);
915
916 if (pps->flags.cabac_init_present_flag)
917 /* cabac_init_flag */
918 params->cabac_init_idc = vl_rbsp_u(&rbsp, 1);
919
920 if (params->temporal_mvp_enable) {
921 if (params->slice_type == STD_VIDEO_H265_SLICE_TYPE_B)
922 params->collocated_list = !vl_rbsp_u(&rbsp, 1);
923
924 if (params->collocated_list == 0) {
925 if (params->num_ref_idx_l0_active > 1)
926 params->collocated_ref_idx = vl_rbsp_ue(&rbsp);
927 } else if (params->collocated_list == 1) {
928 if (params->num_ref_idx_l1_active > 1)
929 params->collocated_ref_idx = vl_rbsp_ue(&rbsp);
930 }
931 }
932
933 if ((pps->flags.weighted_pred_flag && params->slice_type == STD_VIDEO_H265_SLICE_TYPE_P) ||
934 (pps->flags.weighted_bipred_flag && params->slice_type == STD_VIDEO_H265_SLICE_TYPE_B)) {
935 h265_pred_weight_table(params, &rbsp, sps, params->slice_type);
936 }
937
938 params->max_num_merge_cand -= vl_rbsp_ue(&rbsp);
939 }
940
941 params->slice_qp_delta = vl_rbsp_se(&rbsp);
942
943 if (pps->flags.pps_slice_chroma_qp_offsets_present_flag) {
944 params->slice_cb_qp_offset = vl_rbsp_se(&rbsp);
945 params->slice_cr_qp_offset = vl_rbsp_se(&rbsp);
946 }
947
948 if (pps->flags.chroma_qp_offset_list_enabled_flag)
949 /* cu_chroma_qp_offset_enabled_flag */
950 vl_rbsp_u(&rbsp, 1);
951
952 if (pps->flags.deblocking_filter_control_present_flag) {
953 if (pps->flags.deblocking_filter_override_enabled_flag) {
954 /* deblocking_filter_override_flag */
955 if (vl_rbsp_u(&rbsp, 1)) {
956 params->disable_deblocking_filter_idc = vl_rbsp_u(&rbsp, 1);
957
958 if (!params->disable_deblocking_filter_idc) {
959 params->beta_offset_div2 = vl_rbsp_se(&rbsp);
960 params->tc_offset_div2 = vl_rbsp_se(&rbsp);
961 }
962 } else {
963 params->disable_deblocking_filter_idc =
964 pps->flags.pps_deblocking_filter_disabled_flag;
965 }
966 }
967 }
968
969 if (pps->flags.pps_loop_filter_across_slices_enabled_flag &&
970 (params->sao_luma_flag || params->sao_chroma_flag ||
971 !params->disable_deblocking_filter_idc))
972 params->loop_filter_across_slices_enable = vl_rbsp_u(&rbsp, 1);
973
974 if (pps->flags.tiles_enabled_flag || pps->flags.entropy_coding_sync_enabled_flag) {
975 unsigned num_entry_points_offsets = vl_rbsp_ue(&rbsp);
976
977 if (num_entry_points_offsets > 0) {
978 unsigned offset_len = vl_rbsp_ue(&rbsp) + 1;
979 for (unsigned i = 0; i < num_entry_points_offsets; i++) {
980 /* entry_point_offset_minus1 */
981 vl_rbsp_u(&rbsp, offset_len);
982 }
983 }
984 }
985
986 if (pps->flags.pps_extension_present_flag) {
987 unsigned length = vl_rbsp_ue(&rbsp);
988 for (unsigned i = 0; i < length; i++)
989 /* slice_reserved_undetermined_flag */
990 vl_rbsp_u(&rbsp, 1);
991 }
992
993 unsigned header_bits =
994 (slice_size * 8 - 24 /* start code */) - vl_vlc_bits_left(&rbsp.nal) - rbsp.removed;
995 params->slice_data_bytes_offset = (header_bits + 8) / 8;
996 }
997
998 void
vk_video_get_profile_alignments(const VkVideoProfileListInfoKHR * profile_list,uint32_t * width_align_out,uint32_t * height_align_out)999 vk_video_get_profile_alignments(const VkVideoProfileListInfoKHR *profile_list,
1000 uint32_t *width_align_out, uint32_t *height_align_out)
1001 {
1002 uint32_t width_align = 1, height_align = 1;
1003 for (unsigned i = 0; i < profile_list->profileCount; i++) {
1004 if (profile_list->pProfiles[i].videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) {
1005 width_align = MAX2(width_align, VK_VIDEO_H264_MACROBLOCK_WIDTH);
1006 height_align = MAX2(height_align, VK_VIDEO_H264_MACROBLOCK_HEIGHT);
1007 }
1008 if (profile_list->pProfiles[i].videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR) {
1009 width_align = MAX2(width_align, VK_VIDEO_H265_CTU_MAX_WIDTH);
1010 height_align = MAX2(height_align, VK_VIDEO_H265_CTU_MAX_HEIGHT);
1011 }
1012 }
1013 *width_align_out = width_align;
1014 *height_align_out = height_align;
1015 }
1016