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 &params->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(&params->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, &params->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(&params->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(&params->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