1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
21
23
27 .queue_flags = VK_QUEUE_VIDEO_DECODE_BIT_KHR,
28 .decode_op = VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR,
29 .ext_props = {
30 .extensionName = VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_EXTENSION_NAME,
31 .specVersion = VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_SPEC_VERSION,
32 },
33 };
34
37
38 /* Current picture */
41
42 /* Picture refs */
46
47 /* Current picture (contd.) */
51
53
55 VkVideoReferenceSlotInfoKHR *ref_slot, /* Main structure */
56 VkVideoPictureResourceInfoKHR *
ref,
/* Goes in ^ */
57 VkVideoDecodeH264DpbSlotInfoKHR *vkh264_ref, /* Goes in ^ */
58 StdVideoDecodeH264ReferenceInfo *h264_ref, /* Goes in ^ */
60 int is_field, int picture_structure,
61 int dpb_slot_index)
62 {
67
70 if (err < 0)
71 return err;
72
73 *h264_ref = (StdVideoDecodeH264ReferenceInfo) {
76 .flags = (StdVideoDecodeH264ReferenceInfoFlags) {
77 .top_field_flag = is_field ? !!(picture_structure &
PICT_TOP_FIELD) : 0,
80 /*
81 * flags.is_non_existing is used to indicate whether the picture is marked as
82 * "non-existing" as defined in section 8.2.5.2 of the ITU-T H.264 Specification;
83 * 8.2.5.2 Decoding process for gaps in frame_num
84 * corresponds to the code in h264_slice.c:h264_field_start,
85 * which sets the invalid_gap flag when decoding.
86 */
88 },
89 };
90
91 *vkh264_ref = (VkVideoDecodeH264DpbSlotInfoKHR) {
92 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_DPB_SLOT_INFO_KHR,
93 .pStdReferenceInfo = h264_ref,
94 };
95
96 *
ref = (VkVideoPictureResourceInfoKHR) {
97 .sType = VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR,
98 .codedOffset = (VkOffset2D){ 0, 0 },
100 .baseArrayLayer =
ctx->common.layered_dpb ? dpb_slot_index : 0,
101 .imageViewBinding = vkpic->
view.
ref[0],
102 };
103
104 *ref_slot = (VkVideoReferenceSlotInfoKHR) {
105 .sType = VK_STRUCTURE_TYPE_VIDEO_REFERENCE_SLOT_INFO_KHR,
106 .pNext = vkh264_ref,
107 .slotIndex = dpb_slot_index,
108 .pPictureResource =
ref,
109 };
110
111 if (ref_src)
112 *ref_src = pic;
113
114 return 0;
115 }
116
118 {
120 case 10: return STD_VIDEO_H264_LEVEL_IDC_1_0;
121 case 11: return STD_VIDEO_H264_LEVEL_IDC_1_1;
122 case 12: return STD_VIDEO_H264_LEVEL_IDC_1_2;
123 case 13: return STD_VIDEO_H264_LEVEL_IDC_1_3;
124 case 20: return STD_VIDEO_H264_LEVEL_IDC_2_0;
125 case 21: return STD_VIDEO_H264_LEVEL_IDC_2_1;
126 case 22: return STD_VIDEO_H264_LEVEL_IDC_2_2;
127 case 30: return STD_VIDEO_H264_LEVEL_IDC_3_0;
128 case 31: return STD_VIDEO_H264_LEVEL_IDC_3_1;
129 case 32: return STD_VIDEO_H264_LEVEL_IDC_3_2;
130 case 40: return STD_VIDEO_H264_LEVEL_IDC_4_0;
131 case 41: return STD_VIDEO_H264_LEVEL_IDC_4_1;
132 case 42: return STD_VIDEO_H264_LEVEL_IDC_4_2;
133 case 50: return STD_VIDEO_H264_LEVEL_IDC_5_0;
134 case 51: return STD_VIDEO_H264_LEVEL_IDC_5_1;
135 case 52: return STD_VIDEO_H264_LEVEL_IDC_5_2;
136 case 60: return STD_VIDEO_H264_LEVEL_IDC_6_0;
137 case 61: return STD_VIDEO_H264_LEVEL_IDC_6_1;
138 default:
139 case 62: return STD_VIDEO_H264_LEVEL_IDC_6_2;
140 }
141 }
142
144 StdVideoH264ScalingLists *vksps_scaling,
145 StdVideoH264HrdParameters *vksps_vui_header,
146 StdVideoH264SequenceParameterSetVui *vksps_vui,
147 StdVideoH264SequenceParameterSet *vksps)
148 {
149 *vksps_scaling = (StdVideoH264ScalingLists) {
150 .scaling_list_present_mask =
sps->scaling_matrix_present_mask,
151 .use_default_scaling_matrix_mask = 0, /* We already fill in the default matrix */
152 };
153
154 for (
int i = 0;
i < STD_VIDEO_H264_SCALING_LIST_4X4_NUM_LISTS;
i++)
155 for (int j = 0; j < STD_VIDEO_H264_SCALING_LIST_4X4_NUM_ELEMENTS; j++)
157
158 for (
int i = 0;
i < STD_VIDEO_H264_SCALING_LIST_8X8_NUM_LISTS;
i++)
159 for (int j = 0; j < STD_VIDEO_H264_SCALING_LIST_8X8_NUM_ELEMENTS; j++)
160 vksps_scaling->ScalingList8x8[
i][j] =
162
163 *vksps_vui_header = (StdVideoH264HrdParameters) {
164 .cpb_cnt_minus1 =
sps->cpb_cnt - 1,
165 .bit_rate_scale =
sps->bit_rate_scale,
166 .initial_cpb_removal_delay_length_minus1 =
sps->initial_cpb_removal_delay_length - 1,
167 .cpb_removal_delay_length_minus1 =
sps->cpb_removal_delay_length - 1,
168 .dpb_output_delay_length_minus1 =
sps->dpb_output_delay_length - 1,
169 .time_offset_length =
sps->time_offset_length,
170 };
171
172 for (
int i = 0;
i <
sps->cpb_cnt;
i++) {
173 vksps_vui_header->bit_rate_value_minus1[
i] =
sps->bit_rate_value[
i] - 1;
174 vksps_vui_header->cpb_size_value_minus1[
i] =
sps->cpb_size_value[
i] - 1;
175 vksps_vui_header->cbr_flag[
i] = (
sps->cpr_flag >>
i) & 0x1;
176 }
177
178 *vksps_vui = (StdVideoH264SequenceParameterSetVui) {
179 .aspect_ratio_idc =
sps->vui.aspect_ratio_idc,
180 .sar_width =
sps->vui.sar.num,
181 .sar_height =
sps->vui.sar.den,
182 .video_format =
sps->vui.video_format,
183 .colour_primaries =
sps->vui.colour_primaries,
184 .transfer_characteristics =
sps->vui.transfer_characteristics,
185 .matrix_coefficients =
sps->vui.matrix_coeffs,
186 .num_units_in_tick =
sps->num_units_in_tick,
187 .time_scale =
sps->time_scale,
188 .pHrdParameters = vksps_vui_header,
189 .max_num_reorder_frames =
sps->num_reorder_frames,
190 .max_dec_frame_buffering =
sps->max_dec_frame_buffering,
191 .flags = (StdVideoH264SpsVuiFlags) {
192 .aspect_ratio_info_present_flag =
sps->vui.aspect_ratio_info_present_flag,
193 .overscan_info_present_flag =
sps->vui.overscan_info_present_flag,
194 .overscan_appropriate_flag =
sps->vui.overscan_appropriate_flag,
195 .video_signal_type_present_flag =
sps->vui.video_signal_type_present_flag,
196 .video_full_range_flag =
sps->vui.video_full_range_flag,
197 .color_description_present_flag =
sps->vui.colour_description_present_flag,
198 .chroma_loc_info_present_flag =
sps->vui.chroma_loc_info_present_flag,
199 .timing_info_present_flag =
sps->timing_info_present_flag,
200 .fixed_frame_rate_flag =
sps->fixed_frame_rate_flag,
201 .bitstream_restriction_flag =
sps->bitstream_restriction_flag,
202 .nal_hrd_parameters_present_flag =
sps->nal_hrd_parameters_present_flag,
203 .vcl_hrd_parameters_present_flag =
sps->vcl_hrd_parameters_present_flag,
204 },
205 };
206
207 *vksps = (StdVideoH264SequenceParameterSet) {
208 .profile_idc =
sps->profile_idc,
210 .seq_parameter_set_id =
sps->sps_id,
211 .chroma_format_idc =
sps->chroma_format_idc,
212 .bit_depth_luma_minus8 =
sps->bit_depth_luma - 8,
213 .bit_depth_chroma_minus8 =
sps->bit_depth_chroma - 8,
214 .log2_max_frame_num_minus4 =
sps->log2_max_frame_num - 4,
215 .pic_order_cnt_type =
sps->poc_type,
216 .log2_max_pic_order_cnt_lsb_minus4 =
sps->poc_type ? 0 :
sps->log2_max_poc_lsb - 4,
217 .offset_for_non_ref_pic =
sps->offset_for_non_ref_pic,
218 .offset_for_top_to_bottom_field =
sps->offset_for_top_to_bottom_field,
219 .num_ref_frames_in_pic_order_cnt_cycle =
sps->poc_cycle_length,
220 .max_num_ref_frames =
sps->ref_frame_count,
221 .pic_width_in_mbs_minus1 =
sps->mb_width - 1,
222 .pic_height_in_map_units_minus1 = (
sps->mb_height/(2 -
sps->frame_mbs_only_flag)) - 1,
223 .frame_crop_left_offset =
sps->crop_left,
224 .frame_crop_right_offset =
sps->crop_right,
225 .frame_crop_top_offset =
sps->crop_top,
226 .frame_crop_bottom_offset =
sps->crop_bottom,
227 .flags = (StdVideoH264SpsFlags) {
228 .constraint_set0_flag = (
sps->constraint_set_flags >> 0) & 0x1,
229 .constraint_set1_flag = (
sps->constraint_set_flags >> 1) & 0x1,
230 .constraint_set2_flag = (
sps->constraint_set_flags >> 2) & 0x1,
231 .constraint_set3_flag = (
sps->constraint_set_flags >> 3) & 0x1,
232 .constraint_set4_flag = (
sps->constraint_set_flags >> 4) & 0x1,
233 .constraint_set5_flag = (
sps->constraint_set_flags >> 5) & 0x1,
234 .direct_8x8_inference_flag =
sps->direct_8x8_inference_flag,
235 .mb_adaptive_frame_field_flag =
sps->mb_aff,
236 .frame_mbs_only_flag =
sps->frame_mbs_only_flag,
237 .delta_pic_order_always_zero_flag =
sps->delta_pic_order_always_zero_flag,
238 .separate_colour_plane_flag =
sps->residual_color_transform_flag,
239 .gaps_in_frame_num_value_allowed_flag =
sps->gaps_in_frame_num_allowed_flag,
240 .qpprime_y_zero_transform_bypass_flag =
sps->transform_bypass,
241 .frame_cropping_flag =
sps->crop,
242 .seq_scaling_matrix_present_flag =
sps->scaling_matrix_present,
243 .vui_parameters_present_flag =
sps->vui_parameters_present_flag,
244 },
245 .pOffsetForRefFrame =
sps->offset_for_ref_frame,
246 .pScalingLists = vksps_scaling,
247 .pSequenceParameterSetVui = vksps_vui,
248 };
249 }
250
252 StdVideoH264ScalingLists *vkpps_scaling,
253 StdVideoH264PictureParameterSet *vkpps)
254 {
255 *vkpps_scaling = (StdVideoH264ScalingLists) {
256 .scaling_list_present_mask =
pps->pic_scaling_matrix_present_mask,
257 .use_default_scaling_matrix_mask = 0, /* We already fill in the default matrix */
258 };
259
260 for (
int i = 0;
i < STD_VIDEO_H264_SCALING_LIST_4X4_NUM_LISTS;
i++)
261 for (int j = 0; j < STD_VIDEO_H264_SCALING_LIST_4X4_NUM_ELEMENTS; j++)
263
264 for (
int i = 0;
i < STD_VIDEO_H264_SCALING_LIST_8X8_NUM_LISTS;
i++)
265 for (int j = 0; j < STD_VIDEO_H264_SCALING_LIST_8X8_NUM_ELEMENTS; j++)
266 vkpps_scaling->ScalingList8x8[
i][j] =
268
269 *vkpps = (StdVideoH264PictureParameterSet) {
270 .seq_parameter_set_id =
pps->sps_id,
271 .pic_parameter_set_id =
pps->pps_id,
272 .num_ref_idx_l0_default_active_minus1 =
pps->ref_count[0] - 1,
273 .num_ref_idx_l1_default_active_minus1 =
pps->ref_count[1] - 1,
274 .weighted_bipred_idc =
pps->weighted_bipred_idc,
275 .pic_init_qp_minus26 =
pps->init_qp - 26,
276 .pic_init_qs_minus26 =
pps->init_qs - 26,
277 .chroma_qp_index_offset =
pps->chroma_qp_index_offset[0],
278 .second_chroma_qp_index_offset =
pps->chroma_qp_index_offset[1],
279 .flags = (StdVideoH264PpsFlags) {
280 .transform_8x8_mode_flag =
pps->transform_8x8_mode,
281 .redundant_pic_cnt_present_flag =
pps->redundant_pic_cnt_present,
282 .constrained_intra_pred_flag =
pps->constrained_intra_pred,
283 .deblocking_filter_control_present_flag =
pps->deblocking_filter_parameters_present,
284 .weighted_pred_flag =
pps->weighted_pred,
285 .bottom_field_pic_order_in_frame_present_flag =
pps->pic_order_present,
286 .entropy_coding_mode_flag =
pps->cabac,
287 .pic_scaling_matrix_present_flag =
pps->pic_scaling_matrix_present_flag,
288 },
289 .pScalingLists = vkpps_scaling,
290 };
291 }
292
294 {
295 int err;
299
300 /* SPS */
303 StdVideoH264SequenceParameterSetVui vksps_vui[
MAX_SPS_COUNT];
305
306 /* PPS */
309
310 VkVideoDecodeH264SessionParametersAddInfoKHR h264_params_info = {
311 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_KHR,
312 .pStdSPSs = vksps,
313 .stdSPSCount = 0,
314 .pStdPPSs = vkpps,
315 .stdPPSCount = 0,
316 };
317 VkVideoDecodeH264SessionParametersCreateInfoKHR h264_params = {
318 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_KHR,
319 .pParametersAddInfo = &h264_params_info,
320 };
321 VkVideoSessionParametersCreateInfoKHR session_params_create = {
322 .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR,
323 .pNext = &h264_params,
324 .videoSession =
ctx->common.session,
325 .videoSessionParametersTemplate = VK_NULL_HANDLE,
326 };
327
328 /* SPS list */
330 if (
h->ps.sps_list[
i]) {
331 const SPS *sps_l =
h->ps.sps_list[
i];
332 int idx = h264_params_info.stdSPSCount;
333 set_sps(sps_l, &vksps_scaling[idx], &vksps_vui_header[idx], &vksps_vui[idx], &vksps[idx]);
334 h264_params_info.stdSPSCount++;
335 }
336 }
337
338 /* PPS list */
340 if (
h->ps.pps_list[
i]) {
341 const PPS *pps_l =
h->ps.pps_list[
i];
342 int idx = h264_params_info.stdPPSCount;
343 set_pps(pps_l, pps_l->
sps, &vkpps_scaling[idx], &vkpps[idx]);
344 h264_params_info.stdPPSCount++;
345 }
346 }
347
348 h264_params.maxStdSPSCount = h264_params_info.stdSPSCount;
349 h264_params.maxStdPPSCount = h264_params_info.stdPPSCount;
350
352 if (err < 0)
353 return err;
354
356 h264_params_info.stdSPSCount, h264_params_info.stdPPSCount);
357
358 return 0;
359 }
360
365 {
366 int err;
367 int dpb_slot_index = 0;
369
373
374 /* Fill in main slot */
375 dpb_slot_index = 0;
377 if (pic == &
h->DPB[slot]) {
378 dpb_slot_index = slot;
379 break;
380 }
381 }
382
385 h->DPB[dpb_slot_index].field_picture,
386 h->DPB[dpb_slot_index].reference,
387 dpb_slot_index);
388 if (err < 0)
389 return err;
390
391 /* Fill in short-term references */
392 for (
int i = 0;
i <
h->short_ref_count;
i++) {
393 dpb_slot_index = 0;
395 if (
h->short_ref[
i] == &
h->DPB[slot]) {
396 dpb_slot_index = slot;
397 break;
398 }
399 }
403 h->DPB[dpb_slot_index].field_picture,
404 h->DPB[dpb_slot_index].reference,
405 dpb_slot_index);
406 if (err < 0)
407 return err;
408 }
409
410 /* Fill in long-term refs */
412 i < h->short_ref_count +
h->long_ref_count;
r++) {
414 continue;
415
416 dpb_slot_index = 0;
417 for (unsigned slot = 0; slot < 16; slot++) {
418 if (
h->long_ref[
r] == &
h->DPB[slot]) {
419 dpb_slot_index = slot;
420 break;
421 }
422 }
426 h->DPB[dpb_slot_index].field_picture,
427 h->DPB[dpb_slot_index].reference,
428 dpb_slot_index);
429 if (err < 0)
430 return err;
432 }
433
434 hp->
h264pic = (StdVideoDecodeH264PictureInfo) {
435 .seq_parameter_set_id = pic->
pps->
sps_id,
436 .pic_parameter_set_id = pic->
pps->
pps_id,
437 .frame_num = 0, /* Set later */
438 .idr_pic_id = 0, /* Set later */
441 .flags = (StdVideoDecodeH264PictureInfoFlags) {
443 .is_intra = 1, /* Set later */
444 .IdrPicFlag =
h->picture_idr,
445 .bottom_field_flag =
h->picture_structure !=
PICT_FRAME &&
447 .is_reference =
h->nal_ref_idc != 0,
449 },
450 };
451
453 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PICTURE_INFO_KHR,
454 .pStdPictureInfo = &hp->
h264pic,
455 };
456
458 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_INFO_KHR,
460 .flags = 0x0,
461 .pSetupReferenceSlot = &vp->
ref_slot,
462 .referenceSlotCount =
h->short_ref_count +
h->long_ref_count,
464 .dstPictureResource = (VkVideoPictureResourceInfoKHR) {
465 .sType = VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR,
466 .codedOffset = (VkOffset2D){ 0, 0 },
467 .codedExtent = (VkExtent2D){ pic->
f->
width, pic->
f->
height },
468 .baseArrayLayer = 0,
469 .imageViewBinding = vp->
view.
out[0],
470 },
471 };
472
473 return 0;
474 }
475
479 {
484
488 if (err < 0)
489 return err;
490
493
494 /* Frame is only intra of all slices are marked as intra */
496 hp->
h264pic.flags.is_intra = 0;
497
498 return 0;
499 }
500
502 {
506
512
513 #ifdef VK_KHR_video_maintenance2
514 StdVideoH264ScalingLists vksps_scaling;
515 StdVideoH264HrdParameters vksps_vui_header;
516 StdVideoH264SequenceParameterSetVui vksps_vui;
517 StdVideoH264SequenceParameterSet vksps;
518 StdVideoH264ScalingLists vkpps_scaling;
519 StdVideoH264PictureParameterSet vkpps;
520 VkVideoDecodeH264InlineSessionParametersInfoKHR h264_params;
521
524 &vksps_vui_header, &vksps_vui, &vksps);
525 set_pps(
h->ps.pps,
h->ps.sps, &vkpps_scaling, &vkpps);
526 h264_params = (VkVideoDecodeH264InlineSessionParametersInfoKHR) {
527 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_INLINE_SESSION_PARAMETERS_INFO_KHR,
528 .pStdSPS = &vksps,
529 .pStdPPS = &vkpps,
530 };
532 }
533 #endif
534
536 return 0;
537
540
544 if (err < 0)
545 return err;
546
549 }
550
554
557 }
558
561
563 }
564
566 {
569
570 /* Free frame resources, this also destroys the session parameters. */
572 }
573
575 .
p.
name =
"h264_vulkan",
592 };