History

lavc: add hevc_vulkan hardware encoder

This commit adds a Vulkan hardware HEVC encoder, with full support of the spec - I, P, and B-frames.

Lynne committed 2 years ago

Commit 4b4f0b61 parent b4283f97 files · +1860 −22Browse files

Unified · Split

7 files
  1. configure +1 −0
  2. libavcodec/Makefile +3 −0
  3. libavcodec/allcodecs.c +1 −0
  4. libavcodec/vulkan_encode_h265.c +1810 −0
  5. libavcodec/vulkan_hevc.c +3 −22
  6. libavcodec/vulkan_video.c +39 −0
  7. libavcodec/vulkan_video.h +3 −0
configure+1−0
@@ -3388,6 +3388,7 @@ hevc_rkmpp_decoder_deps="rkmpp" · 3387 unmodified lines
3388hevc_rkmpp_decoder_select="hevc_mp4toannexb_bsf"3388hevc_rkmpp_decoder_select="hevc_mp4toannexb_bsf"
3389hevc_vaapi_encoder_deps="VAEncPictureParameterBufferHEVC"3389hevc_vaapi_encoder_deps="VAEncPictureParameterBufferHEVC"
3390hevc_vaapi_encoder_select="atsc_a53 cbs_h265 vaapi_encode"3390hevc_vaapi_encoder_select="atsc_a53 cbs_h265 vaapi_encode"
3391hevc_vulkan_encoder_select="atsc_a53 cbs_h265 vulkan_encode"
3391hevc_v4l2m2m_decoder_deps="v4l2_m2m hevc_v4l2_m2m"3392hevc_v4l2m2m_decoder_deps="v4l2_m2m hevc_v4l2_m2m"
3392hevc_v4l2m2m_decoder_select="hevc_mp4toannexb_bsf"3393hevc_v4l2m2m_decoder_select="hevc_mp4toannexb_bsf"
3393hevc_v4l2m2m_encoder_deps="v4l2_m2m hevc_v4l2_m2m"3394hevc_v4l2m2m_encoder_deps="v4l2_m2m hevc_v4l2_m2m"
libavcodec/Makefile+3−0
@@ -452,6 +452,9 @@ OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc/ps_enc.o · 451 unmodified lines
452OBJS-$(CONFIG_HEVC_RKMPP_DECODER) += rkmppdec.o452OBJS-$(CONFIG_HEVC_RKMPP_DECODER) += rkmppdec.o
453OBJS-$(CONFIG_HEVC_VAAPI_ENCODER) += vaapi_encode_h265.o h265_profile_level.o \453OBJS-$(CONFIG_HEVC_VAAPI_ENCODER) += vaapi_encode_h265.o h265_profile_level.o \
454 h2645data.o hw_base_encode_h265.o454 h2645data.o hw_base_encode_h265.o
455OBJS-$(CONFIG_HEVC_VULKAN_ENCODER) += vulkan_encode.o vulkan_encode_h265.o \
456 hw_base_encode.o hw_base_encode_h265.o \
457 h265_profile_level.o h2645data.o
455OBJS-$(CONFIG_HEVC_V4L2M2M_DECODER) += v4l2_m2m_dec.o458OBJS-$(CONFIG_HEVC_V4L2M2M_DECODER) += v4l2_m2m_dec.o
456OBJS-$(CONFIG_HEVC_V4L2M2M_ENCODER) += v4l2_m2m_enc.o459OBJS-$(CONFIG_HEVC_V4L2M2M_ENCODER) += v4l2_m2m_enc.o
457OBJS-$(CONFIG_HEVC_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o460OBJS-$(CONFIG_HEVC_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o
libavcodec/allcodecs.c+1−0
@@ -862,6 +862,7 @@ extern const FFCodec ff_hevc_qsv_encoder; · 861 unmodified lines
862extern const FFCodec ff_hevc_v4l2m2m_encoder;862extern const FFCodec ff_hevc_v4l2m2m_encoder;
863extern const FFCodec ff_hevc_vaapi_encoder;863extern const FFCodec ff_hevc_vaapi_encoder;
864extern const FFCodec ff_hevc_videotoolbox_encoder;864extern const FFCodec ff_hevc_videotoolbox_encoder;
865extern const FFCodec ff_hevc_vulkan_encoder;
865extern const FFCodec ff_libkvazaar_encoder;866extern const FFCodec ff_libkvazaar_encoder;
866extern const FFCodec ff_mjpeg_cuvid_decoder;867extern const FFCodec ff_mjpeg_cuvid_decoder;
867extern const FFCodec ff_mjpeg_qsv_encoder;868extern const FFCodec ff_mjpeg_qsv_encoder;
libavcodec/vulkan_encode_h265.c+1810−0
@@ -0,0 +1,1810 @@
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
19#include "libavutil/opt.h"
20#include "libavutil/mem.h"
21
22#include "cbs.h"
23#include "cbs_h265.h"
24#include "atsc_a53.h"
25#include "libavutil/mastering_display_metadata.h"
26
27#include "codec_internal.h"
28#include "version.h"
29#include "hw_base_encode_h265.h"
30
31#include "vulkan_encode.h"
32
33enum UnitElems {
34 UNIT_AUD = 1 << 0,
35 UNIT_SEI_MASTERING_DISPLAY = 1 << 1,
36 UNIT_SEI_CONTENT_LIGHT_LEVEL = 1 << 2,
37 UNIT_SEI_A53_CC = 1 << 3,
38};
39
40const FFVulkanEncodeDescriptor ff_vk_enc_h265_desc = {
41 .codec_id = AV_CODEC_ID_H265,
42 .encode_extension = FF_VK_EXT_VIDEO_ENCODE_H265,
43 .encode_op = VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR,
44 .ext_props = {
45 .extensionName = VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_EXTENSION_NAME,
46 .specVersion = VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_SPEC_VERSION,
47 },
48};
49
50typedef struct VulkanEncodeH265Picture {
51 int frame_num;
52 int64_t last_idr_frame;
53 uint16_t idr_pic_id;
54 int primary_pic_type;
55 int slice_type;
56 int pic_order_cnt;
57 int pic_type;
58
59 enum UnitElems units_needed;
60
61 VkVideoEncodeH265RateControlInfoKHR vkrc_info;
62 VkVideoEncodeH265RateControlLayerInfoKHR vkrc_layer_info;
63
64 StdVideoEncodeH265PictureInfo h265pic_info;
65 VkVideoEncodeH265PictureInfoKHR vkh265pic_info;
66
67 StdVideoEncodeH265WeightTable slice_wt;
68 StdVideoEncodeH265SliceSegmentHeader slice_hdr;
69 VkVideoEncodeH265NaluSliceSegmentInfoKHR vkslice;
70
71 StdVideoEncodeH265ReferenceInfo h265dpb_info;
72 VkVideoEncodeH265DpbSlotInfoKHR vkh265dpb_info;
73
74 StdVideoEncodeH265ReferenceListsInfo ref_list_info;
75 StdVideoEncodeH265LongTermRefPics l_rps;
76 StdVideoH265ShortTermRefPicSet s_rps;
77} VulkanEncodeH265Picture;
78
79typedef struct VulkanEncodeH265Context {
80 FFVulkanEncodeContext common;
81
82 FFHWBaseEncodeH265 units;
83 FFHWBaseEncodeH265Opts unit_opts;
84
85 enum UnitElems unit_elems;
86
87 uint8_t fixed_qp_idr;
88 uint8_t fixed_qp_p;
89 uint8_t fixed_qp_b;
90
91 uint64_t hrd_buffer_size;
92 uint64_t initial_buffer_fullness;
93
94 VkVideoEncodeH265ProfileInfoKHR profile;
95
96 VkVideoEncodeH265CapabilitiesKHR caps;
97 VkVideoEncodeH265QualityLevelPropertiesKHR quality_props;
98
99 CodedBitstreamContext *cbs;
100 CodedBitstreamFragment current_access_unit;
101
102 H265RawAUD raw_aud;
103
104 SEIRawMasteringDisplayColourVolume sei_mastering_display;
105 SEIRawContentLightLevelInfo sei_content_light_level;
106 SEIRawUserDataRegistered sei_a53cc;
107 void *sei_a53cc_data;
108} VulkanEncodeH265Context;
109
110static int init_pic_rc(AVCodecContext *avctx, FFHWBaseEncodePicture *pic,
111 VkVideoEncodeRateControlInfoKHR *rc_info,
112 VkVideoEncodeRateControlLayerInfoKHR *rc_layer)
113{
114 VulkanEncodeH265Context *enc = avctx->priv_data;
115 FFVulkanEncodeContext *ctx = &enc->common;
116 VulkanEncodeH265Picture *hp = pic->codec_priv;
117
118 hp->vkrc_info = (VkVideoEncodeH265RateControlInfoKHR) {
119 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_RATE_CONTROL_INFO_KHR,
120 .flags = VK_VIDEO_ENCODE_H265_RATE_CONTROL_REFERENCE_PATTERN_FLAT_BIT_KHR |
121 VK_VIDEO_ENCODE_H265_RATE_CONTROL_REGULAR_GOP_BIT_KHR,
122 .idrPeriod = ctx->base.gop_size,
123 .gopFrameCount = ctx->base.gop_size,
124 .consecutiveBFrameCount = FFMAX(ctx->base.b_per_p - 1, 0),
125 .subLayerCount = 0,
126 };
127
128 rc_info->pNext = &hp->vkrc_info;
129 rc_info->virtualBufferSizeInMs = 1000;
130 rc_info->initialVirtualBufferSizeInMs = 500;
131
132 if (rc_info->rateControlMode > VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR) {
133 hp->vkrc_layer_info = (VkVideoEncodeH265RateControlLayerInfoKHR) {
134 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_RATE_CONTROL_LAYER_INFO_KHR,
135
136 .useMinQp = avctx->qmin > 0,
137 .minQp.qpI = avctx->qmin > 0 ? avctx->qmin : 0,
138 .minQp.qpP = avctx->qmin > 0 ? avctx->qmin : 0,
139 .minQp.qpB = avctx->qmin > 0 ? avctx->qmin : 0,
140
141 .useMaxQp = avctx->qmax > 0,
142 .maxQp.qpI = avctx->qmax > 0 ? avctx->qmax : 0,
143 .maxQp.qpP = avctx->qmax > 0 ? avctx->qmax : 0,
144 .maxQp.qpB = avctx->qmax > 0 ? avctx->qmax : 0,
145
146 .useMaxFrameSize = 0,
147 };
148 rc_layer->pNext = &hp->vkrc_layer_info;
149 hp->vkrc_info.subLayerCount = 1;
150 }
151
152 return 0;
153}
154
155static int vk_enc_h265_update_pic_info(AVCodecContext *avctx,
156 FFHWBaseEncodePicture *pic)
157{
158 VulkanEncodeH265Context *enc = avctx->priv_data;
159 VulkanEncodeH265Picture *hp = pic->codec_priv;
160 FFHWBaseEncodePicture *prev = pic->prev;
161 VulkanEncodeH265Picture *hprev = prev ? prev->codec_priv : NULL;
162
163 if (pic->type == FF_HW_PICTURE_TYPE_IDR) {
164 av_assert0(pic->display_order == pic->encode_order);
165
166 hp->last_idr_frame = pic->display_order;
167
168 hp->slice_type = STD_VIDEO_H265_SLICE_TYPE_I;
169 hp->pic_type = STD_VIDEO_H265_PICTURE_TYPE_IDR;
170 } else {
171 av_assert0(prev);
172 hp->last_idr_frame = hprev->last_idr_frame;
173
174 if (pic->type == FF_HW_PICTURE_TYPE_I) {
175 hp->slice_type = STD_VIDEO_H265_SLICE_TYPE_I;
176 hp->pic_type = STD_VIDEO_H265_PICTURE_TYPE_I;
177 } else if (pic->type == FF_HW_PICTURE_TYPE_P) {
178 av_assert0(pic->refs[0]);
179 hp->slice_type = STD_VIDEO_H265_SLICE_TYPE_P;
180 hp->pic_type = STD_VIDEO_H265_PICTURE_TYPE_P;
181 } else {
182 FFHWBaseEncodePicture *irap_ref;
183 av_assert0(pic->refs[0][0] && pic->refs[1][0]);
184 for (irap_ref = pic; irap_ref; irap_ref = irap_ref->refs[1][0]) {
185 if (irap_ref->type == FF_HW_PICTURE_TYPE_I)
186 break;
187 }
188 hp->slice_type = STD_VIDEO_H265_SLICE_TYPE_B;
189 hp->pic_type = STD_VIDEO_H265_PICTURE_TYPE_B;
190 }
191 }
192 hp->pic_order_cnt = pic->display_order - hp->last_idr_frame;
193
194 hp->units_needed = 0;
195
196 if (enc->unit_elems & UNIT_AUD) {
197 hp->units_needed |= UNIT_AUD;
198 enc->raw_aud = (H265RawAUD) {
199 .nal_unit_header = {
200 .nal_unit_type = HEVC_NAL_AUD,
201 .nuh_layer_id = 0,
202 .nuh_temporal_id_plus1 = 1,
203 },
204 .pic_type = hp->pic_type,
205 };
206 }
207
208 // Only look for the metadata on I/IDR frame on the output. We
209 // may force an IDR frame on the output where the medadata gets
210 // changed on the input frame.
211 if ((enc->unit_elems & UNIT_SEI_MASTERING_DISPLAY) &&
212 (pic->type == FF_HW_PICTURE_TYPE_I || pic->type == FF_HW_PICTURE_TYPE_IDR)) {
213 AVFrameSideData *sd =
214 av_frame_get_side_data(pic->input_image,
215 AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
216
217 if (sd) {
218 AVMasteringDisplayMetadata *mdm = (AVMasteringDisplayMetadata *)sd->data;
219
220 // SEI is needed when both the primaries and luminance are set
221 if (mdm->has_primaries && mdm->has_luminance) {
222 SEIRawMasteringDisplayColourVolume *mdcv =
223 &enc->sei_mastering_display;
224 const int mapping[3] = {1, 2, 0};
225 const int chroma_den = 50000;
226 const int luma_den = 10000;
227
228 for (int i = 0; i < 3; i++) {
229 const int j = mapping[i];
230 mdcv->display_primaries_x[i] =
231 FFMIN(lrint(chroma_den *
232 av_q2d(mdm->display_primaries[j][0])),
233 chroma_den);
234 mdcv->display_primaries_y[i] =
235 FFMIN(lrint(chroma_den *
236 av_q2d(mdm->display_primaries[j][1])),
237 chroma_den);
238 }
239
240 mdcv->white_point_x =
241 FFMIN(lrint(chroma_den * av_q2d(mdm->white_point[0])),
242 chroma_den);
243 mdcv->white_point_y =
244 FFMIN(lrint(chroma_den * av_q2d(mdm->white_point[1])),
245 chroma_den);
246
247 mdcv->max_display_mastering_luminance =
248 lrint(luma_den * av_q2d(mdm->max_luminance));
249 mdcv->min_display_mastering_luminance =
250 FFMIN(lrint(luma_den * av_q2d(mdm->min_luminance)),
251 mdcv->max_display_mastering_luminance);
252
253 hp->units_needed |= UNIT_SEI_MASTERING_DISPLAY;
254 }
255 }
256 }
257
258 if ((enc->unit_elems & UNIT_SEI_CONTENT_LIGHT_LEVEL) &&
259 (pic->type == FF_HW_PICTURE_TYPE_I || pic->type == FF_HW_PICTURE_TYPE_IDR)) {
260 AVFrameSideData *sd = av_frame_get_side_data(pic->input_image,
261 AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
262
263 if (sd) {
264 AVContentLightMetadata *clm = (AVContentLightMetadata *)sd->data;
265 SEIRawContentLightLevelInfo *clli = &enc->sei_content_light_level;
266
267 clli->max_content_light_level = FFMIN(clm->MaxCLL, 65535);
268 clli->max_pic_average_light_level = FFMIN(clm->MaxFALL, 65535);
269
270 hp->units_needed |= UNIT_SEI_CONTENT_LIGHT_LEVEL;
271 }
272 }
273
274 if (enc->unit_elems & UNIT_SEI_A53_CC) {
275 int err;
276 size_t sei_a53cc_len;
277 av_freep(&enc->sei_a53cc_data);
278 err = ff_alloc_a53_sei(pic->input_image, 0, &enc->sei_a53cc_data, &sei_a53cc_len);
279 if (err < 0)
280 return err;
281 if (enc->sei_a53cc_data != NULL) {
282 enc->sei_a53cc.itu_t_t35_country_code = 181;
283 enc->sei_a53cc.data = (uint8_t *)enc->sei_a53cc_data + 1;
284 enc->sei_a53cc.data_length = sei_a53cc_len - 1;
285
286 hp->units_needed |= UNIT_SEI_A53_CC;
287 }
288 }
289
290 return 0;
291}
292
293static void setup_slices(AVCodecContext *avctx,
294 FFHWBaseEncodePicture *pic)
295{
296 VulkanEncodeH265Context *enc = avctx->priv_data;
297 VulkanEncodeH265Picture *hp = pic->codec_priv;
298
299 hp->slice_wt = (StdVideoEncodeH265WeightTable) {
300 .flags = (StdVideoEncodeH265WeightTableFlags) {
301 .luma_weight_l0_flag = 0,
302 .chroma_weight_l0_flag = 0,
303 .luma_weight_l1_flag = 0,
304 .chroma_weight_l1_flag = 0,
305 },
306 .luma_log2_weight_denom = 0,
307 .delta_chroma_log2_weight_denom = 0,
308 .delta_luma_weight_l0 = { 0 },
309 .luma_offset_l0 = { 0 },
310 .delta_chroma_weight_l0 = { { 0 } },
311 .delta_chroma_offset_l0 = { { 0 } },
312 .delta_luma_weight_l1 = { 0 },
313 .luma_offset_l1 = { 0 },
314 .delta_chroma_weight_l1 = { { 0 } },
315 .delta_chroma_offset_l1 = { { 0 } },
316 };
317
318 hp->slice_hdr = (StdVideoEncodeH265SliceSegmentHeader) {
319 .flags = (StdVideoEncodeH265SliceSegmentHeaderFlags) {
320 .first_slice_segment_in_pic_flag = 1,
321 .dependent_slice_segment_flag = 0,
322 .slice_sao_luma_flag = enc->units.raw_sps.sample_adaptive_offset_enabled_flag,
323 .slice_sao_chroma_flag = enc->units.raw_sps.sample_adaptive_offset_enabled_flag,
324 .num_ref_idx_active_override_flag = 0,
325 .mvd_l1_zero_flag = 0,
326 .cabac_init_flag = 0,
327 .cu_chroma_qp_offset_enabled_flag = 0,
328 .deblocking_filter_override_flag = 0,
329 .slice_deblocking_filter_disabled_flag = 0,
330 .collocated_from_l0_flag = 1,
331 .slice_loop_filter_across_slices_enabled_flag = 0,
332 /* Reserved */
333 },
334 .slice_type = hp->slice_type,
335 .slice_segment_address = 0,
336 .collocated_ref_idx = 0,
337 .MaxNumMergeCand = 5,
338 .slice_cb_qp_offset = 0,
339 .slice_cr_qp_offset = 0,
340 .slice_beta_offset_div2 = 0,
341 .slice_tc_offset_div2 = 0,
342 .slice_act_y_qp_offset = 0,
343 .slice_act_cb_qp_offset = 0,
344 .slice_act_cr_qp_offset = 0,
345 .slice_qp_delta = 0, /* Filled in below */
346 /* Reserved */
347 .pWeightTable = NULL, // &hp->slice_wt,
348 };
349
350 hp->vkslice = (VkVideoEncodeH265NaluSliceSegmentInfoKHR) {
351 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_NALU_SLICE_SEGMENT_INFO_KHR,
352 .pNext = NULL,
353 .constantQp = pic->type == FF_HW_PICTURE_TYPE_B ? enc->fixed_qp_b :
354 pic->type == FF_HW_PICTURE_TYPE_P ? enc->fixed_qp_p :
355 enc->fixed_qp_idr,
356 .pStdSliceSegmentHeader = &hp->slice_hdr,
357 };
358
359 if (enc->common.opts.rc_mode != VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR)
360 hp->vkslice.constantQp = 0;
361
362 hp->slice_hdr.slice_qp_delta = hp->vkslice.constantQp -
363 (enc->units.raw_pps.init_qp_minus26 + 26);
364
365 hp->vkh265pic_info.pNaluSliceSegmentEntries = &hp->vkslice;
366 hp->vkh265pic_info.naluSliceSegmentEntryCount = 1;
367}
368
369static void setup_refs(AVCodecContext *avctx,
370 FFHWBaseEncodePicture *pic,
371 VkVideoEncodeInfoKHR *encode_info)
372{
373 int i, j;
374 VulkanEncodeH265Context *enc = avctx->priv_data;
375 VulkanEncodeH265Picture *hp = pic->codec_priv;
376
377 hp->ref_list_info = (StdVideoEncodeH265ReferenceListsInfo) {
378 .flags = (StdVideoEncodeH265ReferenceListsInfoFlags) {
379 .ref_pic_list_modification_flag_l0 = 0,
380 .ref_pic_list_modification_flag_l1 = 0,
381 /* Reserved */
382 },
383 /* May be overridden during setup_slices() */
384 .num_ref_idx_l0_active_minus1 = pic->nb_refs[0] - 1,
385 .num_ref_idx_l1_active_minus1 = pic->nb_refs[1] - 1,
386 /* Reserved */
387 .list_entry_l0 = { 0 },
388 .list_entry_l1 = { 0 },
389 };
390
391 for (i = 0; i < STD_VIDEO_H265_MAX_NUM_LIST_REF; i++)
392 hp->ref_list_info.RefPicList0[i] = hp->ref_list_info.RefPicList1[i] = -1;
393
394 /* Note: really not sure */
395 for (i = 0; i < pic->nb_refs[0]; i++) {
396 VkVideoReferenceSlotInfoKHR *slot_info;
397 slot_info = (VkVideoReferenceSlotInfoKHR *)&encode_info->pReferenceSlots[i];
398 hp->ref_list_info.RefPicList0[i] = slot_info->slotIndex;
399 }
400
401 /* Note: really not sure */
402 for (i = 0; i < pic->nb_refs[1]; i++) {
403 VkVideoReferenceSlotInfoKHR *slot_info;
404 slot_info = (VkVideoReferenceSlotInfoKHR *)&encode_info->pReferenceSlots[pic->nb_refs[0] + i];
405 hp->ref_list_info.RefPicList1[i] = slot_info->slotIndex;
406 }
407
408 hp->h265pic_info.pRefLists = &hp->ref_list_info;
409
410 if (pic->type != FF_HW_PICTURE_TYPE_IDR) {
411 StdVideoH265ShortTermRefPicSet *rps;
412 VulkanEncodeH265Picture *strp;
413 int rps_poc[MAX_DPB_SIZE];
414 int rps_used[MAX_DPB_SIZE];
415 int poc, rps_pics;
416
417 hp->h265pic_info.flags.short_term_ref_pic_set_sps_flag = 0;
418
419 rps = &hp->s_rps;
420 memset(rps, 0, sizeof(*rps));
421
422 rps_pics = 0;
423 for (i = 0; i < MAX_REFERENCE_LIST_NUM; i++) {
424 for (j = 0; j < pic->nb_refs[i]; j++) {
425 strp = pic->refs[i][j]->codec_priv;
426 rps_poc[rps_pics] = strp->pic_order_cnt;
427 rps_used[rps_pics] = 1;
428 ++rps_pics;
429 }
430 }
431
432 for (i = 0; i < pic->nb_dpb_pics; i++) {
433 if (pic->dpb[i] == pic)
434 continue;
435
436 for (j = 0; j < pic->nb_refs[0]; j++) {
437 if (pic->dpb[i] == pic->refs[0][j])
438 break;
439 }
440 if (j < pic->nb_refs[0])
441 continue;
442
443 for (j = 0; j < pic->nb_refs[1]; j++) {
444 if (pic->dpb[i] == pic->refs[1][j])
445 break;
446 }
447 if (j < pic->nb_refs[1])
448 continue;
449
450 strp = pic->dpb[i]->codec_priv;
451 rps_poc[rps_pics] = strp->pic_order_cnt;
452 rps_used[rps_pics] = 0;
453 ++rps_pics;
454 }
455
456 for (i = 1; i < rps_pics; i++) {
457 for (j = i; j > 0; j--) {
458 if (rps_poc[j] > rps_poc[j - 1])
459 break;
460 av_assert0(rps_poc[j] != rps_poc[j - 1]);
461 FFSWAP(int, rps_poc[j], rps_poc[j - 1]);
462 FFSWAP(int, rps_used[j], rps_used[j - 1]);
463 }
464 }
465
466 av_log(avctx, AV_LOG_DEBUG, "RPS for POC %d:", hp->pic_order_cnt);
467 for (i = 0; i < rps_pics; i++)
468 av_log(avctx, AV_LOG_DEBUG, " (%d,%d)", rps_poc[i], rps_used[i]);
469
470 av_log(avctx, AV_LOG_DEBUG, "\n");
471
472 for (i = 0; i < rps_pics; i++) {
473 av_assert0(rps_poc[i] != hp->pic_order_cnt);
474 if (rps_poc[i] > hp->pic_order_cnt)
475 break;
476 }
477
478 rps->num_negative_pics = i;
479 rps->used_by_curr_pic_s0_flag = 0x0;
480 poc = hp->pic_order_cnt;
481 for (j = i - 1; j >= 0; j--) {
482 rps->delta_poc_s0_minus1[i - 1 - j] = poc - rps_poc[j] - 1;
483 rps->used_by_curr_pic_s0_flag |= rps_used[j] << (i - 1 - j);
484 poc = rps_poc[j];
485 }
486
487 rps->num_positive_pics = rps_pics - i;
488 rps->used_by_curr_pic_s1_flag = 0x0;
489 poc = hp->pic_order_cnt;
490 for (j = i; j < rps_pics; j++) {
491 rps->delta_poc_s1_minus1[j - i] = rps_poc[j] - poc - 1;
492 rps->used_by_curr_pic_s1_flag |= rps_used[j] << (j - i);
493 poc = rps_poc[j];
494 }
495
496 hp->l_rps.num_long_term_sps = 0;
497 hp->l_rps.num_long_term_pics = 0;
498
499 // when this flag is not present, it is inerred to 1.
500 hp->slice_hdr.flags.collocated_from_l0_flag = 1;
501 hp->h265pic_info.flags.slice_temporal_mvp_enabled_flag =
502 enc->units.raw_sps.sps_temporal_mvp_enabled_flag;
503 if (hp->h265pic_info.flags.slice_temporal_mvp_enabled_flag) {
504 if (hp->slice_hdr.slice_type == STD_VIDEO_H265_SLICE_TYPE_B)
505 hp->slice_hdr.flags.collocated_from_l0_flag = 1;
506 hp->slice_hdr.collocated_ref_idx = 0;
507 }
508
509 hp->slice_hdr.flags.num_ref_idx_active_override_flag = 0;
510 hp->ref_list_info.num_ref_idx_l0_active_minus1 = enc->units.raw_pps.num_ref_idx_l0_default_active_minus1;
511 hp->ref_list_info.num_ref_idx_l1_active_minus1 = enc->units.raw_pps.num_ref_idx_l1_default_active_minus1;
512 }
513
514 hp->h265pic_info.pShortTermRefPicSet = &hp->s_rps;
515 hp->h265pic_info.pLongTermRefPics = &hp->l_rps;
516}
517
518static int init_pic_params(AVCodecContext *avctx, FFHWBaseEncodePicture *pic,
519 VkVideoEncodeInfoKHR *encode_info)
520{
521 int err;
522 VulkanEncodeH265Context *enc = avctx->priv_data;
523 FFVulkanEncodePicture *vp = pic->priv;
524 VulkanEncodeH265Picture *hp = pic->codec_priv;
525 VkVideoReferenceSlotInfoKHR *ref_slot;
526
527 err = vk_enc_h265_update_pic_info(avctx, pic);
528 if (err < 0)
529 return err;
530
531 hp->vkh265pic_info = (VkVideoEncodeH265PictureInfoKHR) {
532 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PICTURE_INFO_KHR,
533 .pNext = NULL,
534 .pNaluSliceSegmentEntries = NULL, // Filled in during setup_slices()
535 .naluSliceSegmentEntryCount = 0, // Filled in during setup_slices()
536 .pStdPictureInfo = &hp->h265pic_info,
537 };
538
539 hp->h265pic_info = (StdVideoEncodeH265PictureInfo) {
540 .flags = (StdVideoEncodeH265PictureInfoFlags) {
541 .is_reference = pic->is_reference,
542 .IrapPicFlag = pic->type == FF_HW_PICTURE_TYPE_IDR,
543 .used_for_long_term_reference = 0,
544 .discardable_flag = 0,
545 .cross_layer_bla_flag = 0,
546 .pic_output_flag = 1,
547 .no_output_of_prior_pics_flag = 0,
548 .short_term_ref_pic_set_sps_flag = 0,
549 .slice_temporal_mvp_enabled_flag = enc->units.raw_sps.sps_temporal_mvp_enabled_flag,
550 /* Reserved */
551 },
552 .pic_type = hp->pic_type,
553 .sps_video_parameter_set_id = 0,
554 .pps_seq_parameter_set_id = 0,
555 .pps_pic_parameter_set_id = 0,
556 .short_term_ref_pic_set_idx = 0,
557 .PicOrderCntVal = hp->pic_order_cnt,
558 .TemporalId = 0,
559 /* Reserved */
560 .pRefLists = NULL, // Filled in during setup_refs
561 .pShortTermRefPicSet = NULL,
562 .pLongTermRefPics = NULL,
563 };
564 encode_info->pNext = &hp->vkh265pic_info;
565
566 hp->h265dpb_info = (StdVideoEncodeH265ReferenceInfo) {
567 .flags = (StdVideoEncodeH265ReferenceInfoFlags) {
568 .used_for_long_term_reference = 0,
569 .unused_for_reference = 0,
570 /* Reserved */
571 },
572 .pic_type = hp->h265pic_info.pic_type,
573 .PicOrderCntVal = hp->h265pic_info.PicOrderCntVal,
574 .TemporalId = hp->h265pic_info.TemporalId,
575 };
576 hp->vkh265dpb_info = (VkVideoEncodeH265DpbSlotInfoKHR) {
577 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_DPB_SLOT_INFO_KHR,
578 .pStdReferenceInfo = &hp->h265dpb_info,
579 };
580
581 vp->dpb_slot.pNext = &hp->vkh265dpb_info;
582
583 ref_slot = (VkVideoReferenceSlotInfoKHR *)encode_info->pSetupReferenceSlot;
584 ref_slot->pNext = &hp->vkh265dpb_info;
585
586 setup_refs(avctx, pic, encode_info);
587
588 setup_slices(avctx, pic);
589
590 return 0;
591}
592
593static int init_profile(AVCodecContext *avctx,
594 VkVideoProfileInfoKHR *profile, void *pnext)
595{
596 VkResult ret;
597 VulkanEncodeH265Context *enc = avctx->priv_data;
598 FFVulkanEncodeContext *ctx = &enc->common;
599 FFVulkanContext *s = &ctx->s;
600 FFVulkanFunctions *vk = &ctx->s.vkfn;
601 VkVideoEncodeH265CapabilitiesKHR h265_caps = {
602 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_CAPABILITIES_KHR,
603 };
604 VkVideoEncodeCapabilitiesKHR enc_caps = {
605 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_CAPABILITIES_KHR,
606 .pNext = &h265_caps,
607 };
608 VkVideoCapabilitiesKHR caps = {
609 .sType = VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR,
610 .pNext = &enc_caps,
611 };
612
613 /* In order of preference */
614 int last_supported = AV_PROFILE_UNKNOWN;
615 static const int known_profiles[] = {
616 AV_PROFILE_HEVC_MAIN,
617 AV_PROFILE_HEVC_MAIN_10,
618 AV_PROFILE_HEVC_REXT,
619 };
620 int nb_profiles = FF_ARRAY_ELEMS(known_profiles);
621
622 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->frames->sw_format);
623 if (!desc)
624 return AVERROR(EINVAL);
625
626 if (s->frames->sw_format == AV_PIX_FMT_NV12)
627 nb_profiles = 1;
628 else if (s->frames->sw_format == AV_PIX_FMT_P010)
629 nb_profiles = 2;
630
631 enc->profile = (VkVideoEncodeH265ProfileInfoKHR) {
632 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_INFO_KHR,
633 .pNext = pnext,
634 .stdProfileIdc = ff_vk_h265_profile_to_vk(avctx->profile),
635 };
636 profile->pNext = &enc->profile;
637
638 /* Set level */
639 if (avctx->level == AV_LEVEL_UNKNOWN)
640 avctx->level = enc->common.opts.level;
641
642 /* User has explicitly specified a profile. */
643 if (avctx->profile != AV_PROFILE_UNKNOWN)
644 return 0;
645
646 av_log(avctx, AV_LOG_DEBUG, "Supported profiles:\n");
647 for (int i = 0; i < nb_profiles; i++) {
648 enc->profile.stdProfileIdc = ff_vk_h265_profile_to_vk(known_profiles[i]);
649 ret = vk->GetPhysicalDeviceVideoCapabilitiesKHR(s->hwctx->phys_dev,
650 profile,
651 &caps);
652 if (ret == VK_SUCCESS) {
653 av_log(avctx, AV_LOG_DEBUG, " %s\n",
654 avcodec_profile_name(avctx->codec_id, known_profiles[i]));
655 last_supported = known_profiles[i];
656 }
657 }
658
659 if (last_supported == AV_PROFILE_UNKNOWN) {
660 av_log(avctx, AV_LOG_ERROR, "No supported profiles for given format\n");
661 return AVERROR(ENOTSUP);
662 }
663
664 enc->profile.stdProfileIdc = ff_vk_h265_profile_to_vk(last_supported);
665 av_log(avctx, AV_LOG_VERBOSE, "Using profile %s\n",
666 avcodec_profile_name(avctx->codec_id, last_supported));
667 avctx->profile = last_supported;
668
669 return 0;
670}
671
672static int init_enc_options(AVCodecContext *avctx)
673{
674 VulkanEncodeH265Context *enc = avctx->priv_data;
675
676 if (avctx->rc_buffer_size)
677 enc->hrd_buffer_size = avctx->rc_buffer_size;
678 else if (avctx->rc_max_rate > 0)
679 enc->hrd_buffer_size = avctx->rc_max_rate;
680 else
681 enc->hrd_buffer_size = avctx->bit_rate;
682
683 if (avctx->rc_initial_buffer_occupancy) {
684 if (avctx->rc_initial_buffer_occupancy > enc->hrd_buffer_size) {
685 av_log(avctx, AV_LOG_ERROR, "Invalid RC buffer settings: "
686 "must have initial buffer size (%d) <= "
687 "buffer size (%"PRId64").\n",
688 avctx->rc_initial_buffer_occupancy, enc->hrd_buffer_size);
689 return AVERROR(EINVAL);
690 }
691 enc->initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;
692 } else {
693 enc->initial_buffer_fullness = enc->hrd_buffer_size * 3 / 4;
694 }
695
696 if (enc->common.opts.rc_mode == VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR) {
697 enc->fixed_qp_p = av_clip(enc->common.opts.qp,
698 enc->caps.minQp, enc->caps.maxQp);
699
700 if (avctx->i_quant_factor > 0.0)
701 enc->fixed_qp_idr = av_clip((avctx->i_quant_factor * enc->fixed_qp_p +
702 avctx->i_quant_offset) + 0.5,
703 enc->caps.minQp, enc->caps.maxQp);
704 else
705 enc->fixed_qp_idr = enc->fixed_qp_p;
706
707 if (avctx->b_quant_factor > 0.0)
708 enc->fixed_qp_b = av_clip((avctx->b_quant_factor * enc->fixed_qp_p +
709 avctx->b_quant_offset) + 0.5,
710 enc->caps.minQp, enc->caps.maxQp);
711 else
712 enc->fixed_qp_b = enc->fixed_qp_p;
713
714 av_log(avctx, AV_LOG_DEBUG, "Using fixed QP = "
715 "%d / %d / %d for IDR- / P- / B-frames.\n",
716 enc->fixed_qp_idr, enc->fixed_qp_p, enc->fixed_qp_b);
717 } else {
718 enc->fixed_qp_idr = 26;
719 enc->fixed_qp_p = 26;
720 enc->fixed_qp_b = 26;
721 }
722
723 return 0;
724}
725
726static av_cold int init_sequence_headers(AVCodecContext *avctx)
727{
728 int err;
729 VulkanEncodeH265Context *enc = avctx->priv_data;
730 FFVulkanEncodeContext *ctx = &enc->common;
731 FFHWBaseEncodeContext *base_ctx = &ctx->base;
732
733 FFHWBaseEncodeH265 *units = &enc->units;
734 FFHWBaseEncodeH265Opts *unit_opts = &enc->unit_opts;
735
736 int max_ctb_size;
737 unsigned min_tb_size;
738 unsigned max_tb_size;
739 unsigned max_transform_hierarchy;
740
741 unit_opts->tier = enc->common.opts.tier;
742 unit_opts->fixed_qp_idr = enc->fixed_qp_idr;
743 unit_opts->cu_qp_delta_enabled_flag = enc->common.opts.rc_mode != VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR;
744
745 unit_opts->nb_slices = 1;
746
747 unit_opts->slice_block_rows = (avctx->height + base_ctx->slice_block_height - 1) /
748 base_ctx->slice_block_height;
749 unit_opts->slice_block_cols = (avctx->width + base_ctx->slice_block_width - 1) /
750 base_ctx->slice_block_width;
751
752 /* cabac already set via an option */
753 /* fixed_qp_idr initialized in init_enc_options() */
754 /* hrd_buffer_size initialized in init_enc_options() */
755 /* initial_buffer_fullness initialized in init_enc_options() */
756
757 err = ff_hw_base_encode_init_params_h265(&enc->common.base, avctx,
758 units, unit_opts);
759 if (err < 0)
760 return err;
761
762 units->raw_sps.sample_adaptive_offset_enabled_flag =
763 !!(enc->caps.stdSyntaxFlags & VK_VIDEO_ENCODE_H265_STD_SAMPLE_ADAPTIVE_OFFSET_ENABLED_FLAG_SET_BIT_KHR);
764 units->raw_pps.transform_skip_enabled_flag =
765 !!(enc->caps.stdSyntaxFlags & VK_VIDEO_ENCODE_H265_STD_TRANSFORM_SKIP_ENABLED_FLAG_SET_BIT_KHR);
766
767 max_ctb_size = 16;
768
769 /* coding blocks from 8x8 to max CTB size. */
770 if (enc->caps.ctbSizes & VK_VIDEO_ENCODE_H265_CTB_SIZE_64_BIT_KHR)
771 max_ctb_size = 64;
772 else if (enc->caps.ctbSizes & VK_VIDEO_ENCODE_H265_CTB_SIZE_32_BIT_KHR)
773 max_ctb_size = 32;
774
775 min_tb_size = 0;
776 max_tb_size = 0;
777 if (enc->caps.transformBlockSizes & VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_4_BIT_KHR)
778 min_tb_size = 4;
779 else if (enc->caps.transformBlockSizes & VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_8_BIT_KHR)
780 min_tb_size = 8;
781 else if (enc->caps.transformBlockSizes & VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_16_BIT_KHR)
782 min_tb_size = 16;
783 else if (enc->caps.transformBlockSizes & VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_32_BIT_KHR)
784 min_tb_size = 32;
785
786 if (enc->caps.transformBlockSizes & VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_32_BIT_KHR)
787 max_tb_size = 32;
788 else if (enc->caps.transformBlockSizes & VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_16_BIT_KHR)
789 max_tb_size = 16;
790 else if (enc->caps.transformBlockSizes & VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_8_BIT_KHR)
791 max_tb_size = 8;
792 else if (enc->caps.transformBlockSizes & VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_4_BIT_KHR)
793 max_tb_size = 4;
794
795 units->raw_sps.log2_min_luma_coding_block_size_minus3 = 0;
796 units->raw_sps.log2_diff_max_min_luma_coding_block_size = av_log2(max_ctb_size) - 3;
797 units->raw_sps.log2_min_luma_transform_block_size_minus2 = av_log2(min_tb_size) - 2;
798 units->raw_sps.log2_diff_max_min_luma_transform_block_size = av_log2(max_tb_size) - av_log2(min_tb_size);
799
800 max_transform_hierarchy = av_log2(max_ctb_size) - av_log2(min_tb_size);
801 units->raw_sps.max_transform_hierarchy_depth_intra = max_transform_hierarchy;
802 units->raw_sps.max_transform_hierarchy_depth_intra = max_transform_hierarchy;
803
804 units->raw_sps.vui.bitstream_restriction_flag = 0;
805 units->raw_sps.vui.max_bytes_per_pic_denom = 2;
806 units->raw_sps.vui.max_bits_per_min_cu_denom = 1;
807
808 units->raw_sps.sps_temporal_mvp_enabled_flag = 0;
809
810 if (base_ctx->gop_size & base_ctx->gop_size - 1 == 0)
811 units->raw_sps.log2_max_pic_order_cnt_lsb_minus4 = FFMAX(av_log2(base_ctx->gop_size) - 4, 0);
812 else
813 units->raw_sps.log2_max_pic_order_cnt_lsb_minus4 = FFMAX(av_log2(base_ctx->gop_size) - 3, 0);
814
815 return 0;
816}
817
818typedef struct VulkanH265Units {
819 StdVideoH265SequenceParameterSet sps;
820 StdVideoH265ShortTermRefPicSet str[STD_VIDEO_H265_SUBLAYERS_LIST_SIZE];
821 StdVideoH265LongTermRefPicsSps ltr;
822 StdVideoH265ProfileTierLevel ptl_sps;
823 StdVideoH265DecPicBufMgr dpbm_sps;
824
825 StdVideoH265HrdParameters vui_header_sps;
826 StdVideoH265SequenceParameterSetVui vui_sps;
827
828 StdVideoH265SubLayerHrdParameters slhdrnal[HEVC_MAX_SUB_LAYERS];
829 StdVideoH265SubLayerHrdParameters slhdrvcl[HEVC_MAX_SUB_LAYERS];
830
831 StdVideoH265PictureParameterSet pps;
832 StdVideoH265ScalingLists pps_scaling;
833
834 StdVideoH265VideoParameterSet vps;
835 StdVideoH265ProfileTierLevel ptl_vps;
836 StdVideoH265DecPicBufMgr dpbm_vps;
837 StdVideoH265HrdParameters vui_header_vps;
838} VulkanH265Units;
839
840static av_cold int base_unit_to_vk(AVCodecContext *avctx,
841 VulkanH265Units *vk_units)
842{
843 VulkanEncodeH265Context *enc = avctx->priv_data;
844
845 H265RawSPS *sps = &enc->units.raw_sps;
846 StdVideoH265SequenceParameterSet *vksps = &vk_units->sps;
847 StdVideoH265ShortTermRefPicSet *str = vk_units->str;
848 StdVideoH265LongTermRefPicsSps *ltr = &vk_units->ltr;
849 StdVideoH265ProfileTierLevel *ptl_sps = &vk_units->ptl_sps;
850 StdVideoH265DecPicBufMgr *dpbm_sps = &vk_units->dpbm_sps;
851
852 StdVideoH265HrdParameters *vui_header_sps = &vk_units->vui_header_sps;
853 StdVideoH265SequenceParameterSetVui *vui_sps = &vk_units->vui_sps;
854
855 StdVideoH265SubLayerHrdParameters *slhdrnal = vk_units->slhdrnal;
856 StdVideoH265SubLayerHrdParameters *slhdrvcl = vk_units->slhdrvcl;
857
858 H265RawPPS *pps = &enc->units.raw_pps;
859 StdVideoH265PictureParameterSet *vkpps = &vk_units->pps;
860
861 H265RawVPS *vps = &enc->units.raw_vps;
862 StdVideoH265VideoParameterSet *vkvps = &vk_units->vps;
863 StdVideoH265ProfileTierLevel *ptl_vps = &vk_units->ptl_vps;
864 StdVideoH265DecPicBufMgr *dpbm_vps = &vk_units->dpbm_vps;
865 StdVideoH265HrdParameters *vui_header_vps = &vk_units->vui_header_vps;
866
867 /* SPS */
868 for (int i = 0; i < HEVC_MAX_SUB_LAYERS; i++) {
869 memcpy(&slhdrnal[i], &sps->vui.hrd_parameters.nal_sub_layer_hrd_parameters[i], sizeof(*slhdrnal));
870 memcpy(&slhdrvcl[i], &sps->vui.hrd_parameters.vcl_sub_layer_hrd_parameters[i], sizeof(*slhdrvcl));
871 slhdrnal[i].cbr_flag = 0x0;
872 slhdrvcl[i].cbr_flag = 0x0;
873 for (int j = 0; j < HEVC_MAX_CPB_CNT; j++) {
874 slhdrnal[i].cbr_flag |= sps->vui.hrd_parameters.nal_sub_layer_hrd_parameters[i].cbr_flag[j] << i;
875 slhdrvcl[i].cbr_flag |= sps->vui.hrd_parameters.vcl_sub_layer_hrd_parameters[i].cbr_flag[j] << i;
876 }
877 }
878
879 *vui_header_sps = (StdVideoH265HrdParameters) {
880 .flags = (StdVideoH265HrdFlags) {
881 .nal_hrd_parameters_present_flag = sps->vui.hrd_parameters.nal_hrd_parameters_present_flag,
882 .vcl_hrd_parameters_present_flag = sps->vui.hrd_parameters.vcl_hrd_parameters_present_flag,
883 .sub_pic_hrd_params_present_flag = sps->vui.hrd_parameters.sub_pic_hrd_params_present_flag,
884 .sub_pic_cpb_params_in_pic_timing_sei_flag = sps->vui.hrd_parameters.sub_pic_cpb_params_in_pic_timing_sei_flag,
885 .fixed_pic_rate_general_flag = 0x0,
886 .fixed_pic_rate_within_cvs_flag = 0x0,
887 .low_delay_hrd_flag = 0x0,
888 },
889 .tick_divisor_minus2 = sps->vui.hrd_parameters.tick_divisor_minus2,
890 .du_cpb_removal_delay_increment_length_minus1 = sps->vui.hrd_parameters.du_cpb_removal_delay_increment_length_minus1,
891 .dpb_output_delay_du_length_minus1 = sps->vui.hrd_parameters.dpb_output_delay_du_length_minus1,
892 .bit_rate_scale = sps->vui.hrd_parameters.bit_rate_scale,
893 .cpb_size_scale = sps->vui.hrd_parameters.cpb_size_scale,
894 .cpb_size_du_scale = sps->vui.hrd_parameters.cpb_size_du_scale,
895 .initial_cpb_removal_delay_length_minus1 = sps->vui.hrd_parameters.initial_cpb_removal_delay_length_minus1,
896 .au_cpb_removal_delay_length_minus1 = sps->vui.hrd_parameters.au_cpb_removal_delay_length_minus1,
897 .dpb_output_delay_length_minus1 = sps->vui.hrd_parameters.dpb_output_delay_length_minus1,
898 /* Reserved - 3*16 bits */
899 .pSubLayerHrdParametersNal = slhdrnal,
900 .pSubLayerHrdParametersVcl = slhdrvcl,
901 };
902
903 for (int i = 0; i < HEVC_MAX_SUB_LAYERS; i++) {
904 vui_header_sps->flags.fixed_pic_rate_general_flag |= sps->vui.hrd_parameters.fixed_pic_rate_general_flag[i] << i;
905 vui_header_sps->flags.fixed_pic_rate_within_cvs_flag |= sps->vui.hrd_parameters.fixed_pic_rate_within_cvs_flag[i] << i;
906 vui_header_sps->flags.low_delay_hrd_flag |= sps->vui.hrd_parameters.low_delay_hrd_flag[i] << i;
907 }
908
909 for (int i = 0; i < STD_VIDEO_H265_SUBLAYERS_LIST_SIZE; i++) {
910 dpbm_sps->max_latency_increase_plus1[i] = sps->sps_max_latency_increase_plus1[i];
911 dpbm_sps->max_dec_pic_buffering_minus1[i] = sps->sps_max_dec_pic_buffering_minus1[i];
912 dpbm_sps->max_num_reorder_pics[i] = sps->sps_max_num_reorder_pics[i];
913 }
914
915 *ptl_sps = (StdVideoH265ProfileTierLevel) {
916 .flags = (StdVideoH265ProfileTierLevelFlags) {
917 .general_tier_flag = sps->profile_tier_level.general_tier_flag,
918 .general_progressive_source_flag = sps->profile_tier_level.general_progressive_source_flag,
919 .general_interlaced_source_flag = sps->profile_tier_level.general_interlaced_source_flag,
920 .general_non_packed_constraint_flag = sps->profile_tier_level.general_non_packed_constraint_flag,
921 .general_frame_only_constraint_flag = sps->profile_tier_level.general_frame_only_constraint_flag,
922 },
923 .general_profile_idc = ff_vk_h265_profile_to_vk(sps->profile_tier_level.general_profile_idc),
924 .general_level_idc = ff_vk_h265_level_to_vk(sps->profile_tier_level.general_level_idc),
925 };
926
927 for (int i = 0; i < STD_VIDEO_H265_MAX_SHORT_TERM_REF_PIC_SETS; i++) {
928 const H265RawSTRefPicSet *st_rps = &sps->st_ref_pic_set[i];
929
930 str[i] = (StdVideoH265ShortTermRefPicSet) {
931 .flags = (StdVideoH265ShortTermRefPicSetFlags) {
932 .inter_ref_pic_set_prediction_flag = st_rps->inter_ref_pic_set_prediction_flag,
933 .delta_rps_sign = st_rps->delta_rps_sign,
934 },
935 .delta_idx_minus1 = st_rps->delta_idx_minus1,
936 .use_delta_flag = 0x0,
937 .abs_delta_rps_minus1 = st_rps->abs_delta_rps_minus1,
938 .used_by_curr_pic_flag = 0x0,
939 .used_by_curr_pic_s0_flag = 0x0,
940 .used_by_curr_pic_s1_flag = 0x0,
941 /* Reserved */
942 /* Reserved */
943 /* Reserved */
944 .num_negative_pics = st_rps->num_negative_pics,
945 .num_positive_pics = st_rps->num_positive_pics,
946 };
947
948 for (int j = 0; j < HEVC_MAX_REFS; j++) {
949 str[i].use_delta_flag |= st_rps->use_delta_flag[j] << i;
950 str[i].used_by_curr_pic_flag |= st_rps->used_by_curr_pic_flag[j] << i;
951 str[i].used_by_curr_pic_s0_flag |= st_rps->used_by_curr_pic_s0_flag[j] << i;
952 str[i].used_by_curr_pic_s1_flag |= st_rps->used_by_curr_pic_s1_flag[j] << i;
953 str[i].delta_poc_s0_minus1[j] = st_rps->delta_poc_s0_minus1[j];
954 str[i].delta_poc_s1_minus1[j] = st_rps->delta_poc_s1_minus1[j];
955 }
956 }
957
958 ltr->used_by_curr_pic_lt_sps_flag = 0;
959 for (int i = 0; i < STD_VIDEO_H265_MAX_LONG_TERM_REF_PICS_SPS; i++) {
960 ltr->used_by_curr_pic_lt_sps_flag |= sps->lt_ref_pic_poc_lsb_sps[i] << i;
961 ltr->lt_ref_pic_poc_lsb_sps[i] = sps->lt_ref_pic_poc_lsb_sps[i];
962 }
963
964 *vksps = (StdVideoH265SequenceParameterSet) {
965 .flags = (StdVideoH265SpsFlags) {
966 .sps_temporal_id_nesting_flag = sps->sps_temporal_id_nesting_flag,
967 .separate_colour_plane_flag = sps->separate_colour_plane_flag,
968 .conformance_window_flag = sps->conformance_window_flag,
969 .sps_sub_layer_ordering_info_present_flag = sps->sps_sub_layer_ordering_info_present_flag,
970 .scaling_list_enabled_flag = sps->scaling_list_enabled_flag,
971 .sps_scaling_list_data_present_flag = sps->sps_scaling_list_data_present_flag,
972 .amp_enabled_flag = sps->amp_enabled_flag,
973 .sample_adaptive_offset_enabled_flag = sps->sample_adaptive_offset_enabled_flag,
974 .pcm_enabled_flag = sps->pcm_enabled_flag,
975 .pcm_loop_filter_disabled_flag = sps->pcm_loop_filter_disabled_flag,
976 .long_term_ref_pics_present_flag = sps->long_term_ref_pics_present_flag,
977 .sps_temporal_mvp_enabled_flag = sps->sps_temporal_mvp_enabled_flag,
978 .strong_intra_smoothing_enabled_flag = sps->strong_intra_smoothing_enabled_flag,
979 .vui_parameters_present_flag = sps->vui_parameters_present_flag,
980 .sps_extension_present_flag = sps->sps_extension_present_flag,
981 .sps_range_extension_flag = sps->sps_range_extension_flag,
982 .transform_skip_rotation_enabled_flag = sps->transform_skip_rotation_enabled_flag,
983 .transform_skip_context_enabled_flag = sps->transform_skip_context_enabled_flag,
984 .implicit_rdpcm_enabled_flag = sps->implicit_rdpcm_enabled_flag,
985 .explicit_rdpcm_enabled_flag = sps->explicit_rdpcm_enabled_flag,
986 .extended_precision_processing_flag = sps->extended_precision_processing_flag,
987 .intra_smoothing_disabled_flag = sps->intra_smoothing_disabled_flag,
988 .high_precision_offsets_enabled_flag = sps->high_precision_offsets_enabled_flag,
989 .persistent_rice_adaptation_enabled_flag = sps->persistent_rice_adaptation_enabled_flag,
990 .cabac_bypass_alignment_enabled_flag = sps->cabac_bypass_alignment_enabled_flag,
991 .sps_scc_extension_flag = sps->sps_scc_extension_flag,
992 .sps_curr_pic_ref_enabled_flag = sps->sps_curr_pic_ref_enabled_flag,
993 .palette_mode_enabled_flag = sps->palette_mode_enabled_flag,
994 .sps_palette_predictor_initializers_present_flag = sps->sps_palette_predictor_initializer_present_flag,
995 .intra_boundary_filtering_disabled_flag = sps->intra_boundary_filtering_disable_flag,
996 },
997 .chroma_format_idc = sps->chroma_format_idc,
998 .pic_width_in_luma_samples = sps->pic_width_in_luma_samples,
999 .pic_height_in_luma_samples = sps->pic_height_in_luma_samples,
1000 .sps_video_parameter_set_id = sps->sps_video_parameter_set_id,
1001 .sps_max_sub_layers_minus1 = sps->sps_max_sub_layers_minus1,
1002 .sps_seq_parameter_set_id = sps->sps_seq_parameter_set_id,
1003 .bit_depth_luma_minus8 = sps->bit_depth_luma_minus8,
1004 .bit_depth_chroma_minus8 = sps->bit_depth_chroma_minus8,
1005 .log2_max_pic_order_cnt_lsb_minus4 = sps->log2_max_pic_order_cnt_lsb_minus4,
1006 .log2_min_luma_coding_block_size_minus3 = sps->log2_min_luma_coding_block_size_minus3,
1007 .log2_diff_max_min_luma_coding_block_size = sps->log2_diff_max_min_luma_coding_block_size,
1008 .log2_min_luma_transform_block_size_minus2 = sps->log2_min_luma_transform_block_size_minus2,
1009 .log2_diff_max_min_luma_transform_block_size = sps->log2_diff_max_min_luma_transform_block_size,
1010 .max_transform_hierarchy_depth_inter = sps->max_transform_hierarchy_depth_inter,
1011 .max_transform_hierarchy_depth_intra = sps->max_transform_hierarchy_depth_intra,
1012 .num_short_term_ref_pic_sets = sps->num_short_term_ref_pic_sets,
1013 .num_long_term_ref_pics_sps = sps->num_long_term_ref_pics_sps,
1014 .pcm_sample_bit_depth_luma_minus1 = sps->pcm_sample_bit_depth_luma_minus1,
1015 .pcm_sample_bit_depth_chroma_minus1 = sps->pcm_sample_bit_depth_chroma_minus1,
1016 .log2_min_pcm_luma_coding_block_size_minus3 = sps->log2_min_pcm_luma_coding_block_size_minus3,
1017 .log2_diff_max_min_pcm_luma_coding_block_size = sps->log2_diff_max_min_pcm_luma_coding_block_size,
1018 /* Reserved */
1019 /* Reserved */
1020 .palette_max_size = sps->palette_max_size,
1021 .delta_palette_max_predictor_size = sps->delta_palette_max_predictor_size,
1022 .motion_vector_resolution_control_idc = sps->motion_vector_resolution_control_idc,
1023 .sps_num_palette_predictor_initializers_minus1 = sps->sps_num_palette_predictor_initializer_minus1,
1024 .conf_win_left_offset = sps->conf_win_left_offset,
1025 .conf_win_right_offset = sps->conf_win_right_offset,
1026 .conf_win_top_offset = sps->conf_win_top_offset,
1027 .conf_win_bottom_offset = sps->conf_win_bottom_offset,
1028 .pProfileTierLevel = ptl_sps,
1029 .pDecPicBufMgr = dpbm_sps,
1030 .pScalingLists = NULL,
1031 .pShortTermRefPicSet = str,
1032 .pLongTermRefPicsSps = ltr,
1033 .pSequenceParameterSetVui = vui_sps,
1034 .pPredictorPaletteEntries = NULL,
1035 };
1036
1037 /* PPS */
1038 *vkpps = (StdVideoH265PictureParameterSet) {
1039 .flags = (StdVideoH265PpsFlags) {
1040 .dependent_slice_segments_enabled_flag = pps->dependent_slice_segments_enabled_flag,
1041 .output_flag_present_flag = pps->output_flag_present_flag,
1042 .sign_data_hiding_enabled_flag = pps->sign_data_hiding_enabled_flag,
1043 .cabac_init_present_flag = pps->cabac_init_present_flag,
1044 .constrained_intra_pred_flag = pps->constrained_intra_pred_flag,
1045 .transform_skip_enabled_flag = pps->transform_skip_enabled_flag,
1046 .cu_qp_delta_enabled_flag = pps->cu_qp_delta_enabled_flag,
1047 .pps_slice_chroma_qp_offsets_present_flag = pps->pps_slice_chroma_qp_offsets_present_flag,
1048 .weighted_pred_flag = pps->weighted_pred_flag,
1049 .weighted_bipred_flag = pps->weighted_bipred_flag,
1050 .transquant_bypass_enabled_flag = pps->transquant_bypass_enabled_flag,
1051 .tiles_enabled_flag = pps->tiles_enabled_flag,
1052 .entropy_coding_sync_enabled_flag = pps->entropy_coding_sync_enabled_flag,
1053 .uniform_spacing_flag = pps->uniform_spacing_flag,
1054 .loop_filter_across_tiles_enabled_flag = pps->loop_filter_across_tiles_enabled_flag,
1055 .pps_loop_filter_across_slices_enabled_flag = pps->pps_loop_filter_across_slices_enabled_flag,
1056 .deblocking_filter_control_present_flag = pps->deblocking_filter_control_present_flag,
1057 .deblocking_filter_override_enabled_flag = pps->deblocking_filter_override_enabled_flag,
1058 .pps_deblocking_filter_disabled_flag = pps->pps_deblocking_filter_disabled_flag,
1059 .pps_scaling_list_data_present_flag = pps->pps_scaling_list_data_present_flag,
1060 .lists_modification_present_flag = pps->lists_modification_present_flag,
1061 .slice_segment_header_extension_present_flag = pps->slice_segment_header_extension_present_flag,
1062 .pps_extension_present_flag = pps->pps_extension_present_flag,
1063 .cross_component_prediction_enabled_flag = pps->cross_component_prediction_enabled_flag,
1064 .chroma_qp_offset_list_enabled_flag = pps->chroma_qp_offset_list_enabled_flag,
1065 .pps_curr_pic_ref_enabled_flag = pps->pps_curr_pic_ref_enabled_flag,
1066 .residual_adaptive_colour_transform_enabled_flag = pps->residual_adaptive_colour_transform_enabled_flag,
1067 .pps_slice_act_qp_offsets_present_flag = pps->pps_slice_act_qp_offsets_present_flag,
1068 .pps_palette_predictor_initializers_present_flag = pps->pps_palette_predictor_initializer_present_flag,
1069 .monochrome_palette_flag = pps->monochrome_palette_flag,
1070 .pps_range_extension_flag = pps->pps_range_extension_flag,
1071 },
1072 .pps_pic_parameter_set_id = pps->pps_pic_parameter_set_id,
1073 .pps_seq_parameter_set_id = pps->pps_seq_parameter_set_id,
1074 .sps_video_parameter_set_id = sps->sps_video_parameter_set_id,
1075 .num_extra_slice_header_bits = pps->num_extra_slice_header_bits,
1076 .num_ref_idx_l0_default_active_minus1 = pps->num_ref_idx_l0_default_active_minus1,
1077 .num_ref_idx_l1_default_active_minus1 = pps->num_ref_idx_l1_default_active_minus1,
1078 .init_qp_minus26 = pps->init_qp_minus26,
1079 .diff_cu_qp_delta_depth = pps->diff_cu_qp_delta_depth,
1080 .pps_cb_qp_offset = pps->pps_cb_qp_offset,
1081 .pps_cr_qp_offset = pps->pps_cr_qp_offset,
1082 .pps_beta_offset_div2 = pps->pps_beta_offset_div2,
1083 .pps_tc_offset_div2 = pps->pps_tc_offset_div2,
1084 .log2_parallel_merge_level_minus2 = pps->log2_parallel_merge_level_minus2,
1085 .log2_max_transform_skip_block_size_minus2 = pps->log2_max_transform_skip_block_size_minus2,
1086 .diff_cu_chroma_qp_offset_depth = pps->diff_cu_chroma_qp_offset_depth,
1087 .chroma_qp_offset_list_len_minus1 = pps->chroma_qp_offset_list_len_minus1,
1088 .log2_sao_offset_scale_luma = pps->log2_sao_offset_scale_luma,
1089 .log2_sao_offset_scale_chroma = pps->log2_sao_offset_scale_chroma,
1090 .pps_act_y_qp_offset_plus5 = pps->pps_act_y_qp_offset_plus5,
1091 .pps_act_cb_qp_offset_plus5 = pps->pps_act_cb_qp_offset_plus5,
1092 .pps_act_cr_qp_offset_plus3 = pps->pps_act_cr_qp_offset_plus3,
1093 .pps_num_palette_predictor_initializers = pps->pps_num_palette_predictor_initializer,
1094 .luma_bit_depth_entry_minus8 = pps->luma_bit_depth_entry_minus8,
1095 .chroma_bit_depth_entry_minus8 = pps->chroma_bit_depth_entry_minus8,
1096 .num_tile_columns_minus1 = pps->num_tile_columns_minus1,
1097 .num_tile_rows_minus1 = pps->num_tile_rows_minus1,
1098 .pScalingLists = NULL,
1099 .pPredictorPaletteEntries = NULL,
1100 };
1101
1102 for (int i = 0; i < pps->num_tile_columns_minus1; i++)
1103 vkpps->column_width_minus1[i] = pps->column_width_minus1[i];
1104
1105 for (int i = 0; i < pps->num_tile_rows_minus1; i++)
1106 vkpps->row_height_minus1[i] = pps->row_height_minus1[i];
1107
1108 for (int i = 0; i <= pps->chroma_qp_offset_list_len_minus1; i++) {
1109 vkpps->cb_qp_offset_list[i] = pps->cb_qp_offset_list[i];
1110 vkpps->cr_qp_offset_list[i] = pps->cr_qp_offset_list[i];
1111 }
1112
1113 /* VPS */
1114 for (int i = 0; i < STD_VIDEO_H265_SUBLAYERS_LIST_SIZE; i++) {
1115 dpbm_vps->max_latency_increase_plus1[i] = vps->vps_max_latency_increase_plus1[i];
1116 dpbm_vps->max_dec_pic_buffering_minus1[i] = vps->vps_max_dec_pic_buffering_minus1[i];
1117 dpbm_vps->max_num_reorder_pics[i] = vps->vps_max_num_reorder_pics[i];
1118 }
1119
1120 *ptl_vps = (StdVideoH265ProfileTierLevel) {
1121 .flags = (StdVideoH265ProfileTierLevelFlags) {
1122 .general_tier_flag = vps->profile_tier_level.general_tier_flag,
1123 .general_progressive_source_flag = vps->profile_tier_level.general_progressive_source_flag,
1124 .general_interlaced_source_flag = vps->profile_tier_level.general_interlaced_source_flag,
1125 .general_non_packed_constraint_flag = vps->profile_tier_level.general_non_packed_constraint_flag,
1126 .general_frame_only_constraint_flag = vps->profile_tier_level.general_frame_only_constraint_flag,
1127 },
1128 .general_profile_idc = ff_vk_h265_profile_to_vk(vps->profile_tier_level.general_profile_idc),
1129 .general_level_idc = ff_vk_h265_level_to_vk(vps->profile_tier_level.general_level_idc),
1130 };
1131
1132 *vkvps = (StdVideoH265VideoParameterSet) {
1133 .flags = (StdVideoH265VpsFlags) {
1134 .vps_temporal_id_nesting_flag = vps->vps_temporal_id_nesting_flag,
1135 .vps_sub_layer_ordering_info_present_flag = vps->vps_sub_layer_ordering_info_present_flag,
1136 .vps_timing_info_present_flag = vps->vps_timing_info_present_flag,
1137 .vps_poc_proportional_to_timing_flag = vps->vps_poc_proportional_to_timing_flag,
1138 },
1139 .vps_video_parameter_set_id = vps->vps_video_parameter_set_id,
1140 .vps_max_sub_layers_minus1 = vps->vps_max_sub_layers_minus1,
1141 /* Reserved */
1142 /* Reserved */
1143 .vps_num_units_in_tick = vps->vps_num_units_in_tick,
1144 .vps_time_scale = vps->vps_time_scale,
1145 .vps_num_ticks_poc_diff_one_minus1 = vps->vps_num_ticks_poc_diff_one_minus1,
1146 /* Reserved */
1147 .pDecPicBufMgr = dpbm_vps,
1148 .pHrdParameters = vui_header_vps,
1149 .pProfileTierLevel = ptl_vps,
1150 };
1151
1152 return 0;
1153}
1154
1155static int create_session_params(AVCodecContext *avctx)
1156{
1157 int err;
1158 VkResult ret;
1159 VulkanEncodeH265Context *enc = avctx->priv_data;
1160 FFVulkanEncodeContext *ctx = &enc->common;
1161 FFVulkanContext *s = &ctx->s;
1162 FFVulkanFunctions *vk = &ctx->s.vkfn;
1163
1164 VulkanH265Units vk_units = { 0 };
1165
1166 VkVideoEncodeH265SessionParametersAddInfoKHR h265_params_info;
1167 VkVideoEncodeH265SessionParametersCreateInfoKHR h265_params;
1168 VkVideoSessionParametersCreateInfoKHR session_params_create;
1169
1170 /* Convert it to Vulkan */
1171 err = base_unit_to_vk(avctx, &vk_units);
1172 if (err < 0) {
1173 av_log(avctx, AV_LOG_ERROR, "Unable to convert SPS/PPS units to Vulkan: %s\n",
1174 av_err2str(err));
1175 return err;
1176 }
1177
1178 /* Destroy the session params */
1179 if (ctx->session_params)
1180 vk->DestroyVideoSessionParametersKHR(s->hwctx->act_dev,
1181 ctx->session_params,
1182 s->hwctx->alloc);
1183
1184 h265_params_info = (VkVideoEncodeH265SessionParametersAddInfoKHR) {
1185 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_ADD_INFO_KHR,
1186 .pStdSPSs = &vk_units.sps,
1187 .stdSPSCount = 1,
1188 .pStdPPSs = &vk_units.pps,
1189 .stdPPSCount = 1,
1190 .pStdVPSs = &vk_units.vps,
1191 .stdVPSCount = 1,
1192 };
1193 h265_params = (VkVideoEncodeH265SessionParametersCreateInfoKHR) {
1194 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_CREATE_INFO_KHR,
1195 .maxStdSPSCount = 1,
1196 .maxStdPPSCount = 1,
1197 .maxStdVPSCount = 1,
1198 .pParametersAddInfo = &h265_params_info,
1199 };
1200 session_params_create = (VkVideoSessionParametersCreateInfoKHR) {
1201 .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR,
1202 .pNext = &h265_params,
1203 .videoSession = ctx->common.session,
1204 .videoSessionParametersTemplate = NULL,
1205 };
1206
1207 /* Create session parameters */
1208 ret = vk->CreateVideoSessionParametersKHR(s->hwctx->act_dev, &session_params_create,
1209 s->hwctx->alloc, &ctx->session_params);
1210 if (ret != VK_SUCCESS) {
1211 av_log(avctx, AV_LOG_ERROR, "Unable to create Vulkan video session parameters: %s!\n",
1212 ff_vk_ret2str(ret));
1213 return AVERROR_EXTERNAL;
1214 }
1215
1216 return 0;
1217}
1218
1219static int parse_feedback_units(AVCodecContext *avctx,
1220 const uint8_t *data, size_t size,
1221 int sps_override, int pps_override)
1222{
1223 int err;
1224 VulkanEncodeH265Context *enc = avctx->priv_data;
1225
1226 CodedBitstreamContext *cbs;
1227 CodedBitstreamFragment au = { 0 };
1228
1229 err = ff_cbs_init(&cbs, AV_CODEC_ID_HEVC, avctx);
1230 if (err < 0)
1231 return err;
1232
1233 err = ff_cbs_read(cbs, &au, data, size);
1234 if (err < 0) {
1235 av_log(avctx, AV_LOG_ERROR, "Unable to parse feedback units, bad drivers: %s\n",
1236 av_err2str(err));
1237 return err;
1238 }
1239
1240 if (sps_override) {
1241 for (int i = 0; i < au.nb_units; i++) {
1242 if (au.units[i].type == HEVC_NAL_SPS) {
1243 H265RawSPS *sps = au.units[i].content;
1244 enc->units.raw_sps.pic_width_in_luma_samples = sps->pic_width_in_luma_samples;
1245 enc->units.raw_sps.pic_height_in_luma_samples = sps->pic_height_in_luma_samples;
1246 enc->units.raw_sps.log2_diff_max_min_luma_coding_block_size = sps->log2_diff_max_min_luma_coding_block_size;
1247 enc->units.raw_sps.max_transform_hierarchy_depth_inter = sps->max_transform_hierarchy_depth_inter;
1248 enc->units.raw_sps.max_transform_hierarchy_depth_intra = sps->max_transform_hierarchy_depth_intra;
1249 }
1250 }
1251 }
1252
1253 /* If PPS has an override, just copy it entirely. */
1254 if (pps_override) {
1255 for (int i = 0; i < au.nb_units; i++) {
1256 if (au.units[i].type == HEVC_NAL_PPS) {
1257 H265RawPPS *pps = au.units[i].content;
1258 memcpy(&enc->units.raw_pps, pps, sizeof(*pps));
1259 enc->fixed_qp_idr = pps->init_qp_minus26 + 26;
1260 break;
1261 }
1262 }
1263 }
1264
1265 ff_cbs_fragment_free(&au);
1266 ff_cbs_close(&cbs);
1267
1268 return 0;
1269}
1270
1271static int init_base_units(AVCodecContext *avctx)
1272{
1273 int err;
1274 VkResult ret;
1275 VulkanEncodeH265Context *enc = avctx->priv_data;
1276 FFVulkanEncodeContext *ctx = &enc->common;
1277 FFVulkanContext *s = &ctx->s;
1278 FFVulkanFunctions *vk = &ctx->s.vkfn;
1279
1280 VkVideoEncodeH265SessionParametersGetInfoKHR h265_params_info;
1281 VkVideoEncodeSessionParametersGetInfoKHR params_info;
1282 VkVideoEncodeH265SessionParametersFeedbackInfoKHR h265_params_feedback;
1283 VkVideoEncodeSessionParametersFeedbackInfoKHR params_feedback;
1284
1285 void *data = NULL;
1286 size_t data_size = 0;
1287
1288 /* Generate SPS/PPS unit info */
1289 err = init_sequence_headers(avctx);
1290 if (err < 0) {
1291 av_log(avctx, AV_LOG_ERROR, "Unable to initialize SPS/PPS units: %s\n",
1292 av_err2str(err));
1293 return err;
1294 }
1295
1296 /* Create session parameters from them */
1297 err = create_session_params(avctx);
1298 if (err < 0)
1299 return err;
1300
1301 h265_params_info = (VkVideoEncodeH265SessionParametersGetInfoKHR) {
1302 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_GET_INFO_KHR,
1303 .writeStdSPS = 1,
1304 .writeStdPPS = 1,
1305 .writeStdVPS = 1,
1306 .stdSPSId = enc->units.raw_sps.sps_seq_parameter_set_id,
1307 .stdPPSId = enc->units.raw_pps.pps_pic_parameter_set_id,
1308 .stdVPSId = enc->units.raw_vps.vps_video_parameter_set_id,
1309 };
1310 params_info = (VkVideoEncodeSessionParametersGetInfoKHR) {
1311 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_SESSION_PARAMETERS_GET_INFO_KHR,
1312 .pNext = &h265_params_info,
1313 .videoSessionParameters = ctx->session_params,
1314 };
1315
1316 h265_params_feedback = (VkVideoEncodeH265SessionParametersFeedbackInfoKHR) {
1317 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_FEEDBACK_INFO_KHR,
1318 };
1319 params_feedback = (VkVideoEncodeSessionParametersFeedbackInfoKHR) {
1320 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_SESSION_PARAMETERS_FEEDBACK_INFO_KHR,
1321 .pNext = &h265_params_feedback,
1322 };
1323
1324 ret = vk->GetEncodedVideoSessionParametersKHR(s->hwctx->act_dev, &params_info,
1325 &params_feedback,
1326 &data_size, data);
1327 if (ret == VK_INCOMPLETE ||
1328 (ret == VK_SUCCESS) && (data_size > 0)) {
1329 data = av_mallocz(data_size);
1330 if (!data)
1331 return AVERROR(ENOMEM);
1332 } else {
1333 av_log(avctx, AV_LOG_ERROR, "Unable to get feedback for H.265 units = %lu\n", data_size);
1334 return err;
1335 }
1336
1337 ret = vk->GetEncodedVideoSessionParametersKHR(s->hwctx->act_dev, &params_info,
1338 &params_feedback,
1339 &data_size, data);
1340 if (ret != VK_SUCCESS) {
1341 av_log(avctx, AV_LOG_ERROR, "Error writing feedback units\n");
1342 return err;
1343 }
1344
1345 av_log(avctx, AV_LOG_VERBOSE, "Feedback units written, overrides: %i (SPS: %i PPS: %i VPS: %i)\n",
1346 params_feedback.hasOverrides,
1347 h265_params_feedback.hasStdSPSOverrides,
1348 h265_params_feedback.hasStdPPSOverrides,
1349 h265_params_feedback.hasStdVPSOverrides);
1350
1351 params_feedback.hasOverrides = 1;
1352 h265_params_feedback.hasStdSPSOverrides = 1;
1353 h265_params_feedback.hasStdPPSOverrides = 1;
1354
1355 /* No need to sync any overrides */
1356 if (!params_feedback.hasOverrides)
1357 return 0;
1358
1359 /* Parse back tne units and override */
1360 err = parse_feedback_units(avctx, data, data_size,
1361 h265_params_feedback.hasStdSPSOverrides,
1362 h265_params_feedback.hasStdPPSOverrides);
1363 if (err < 0)
1364 return err;
1365
1366 /* Create final session parameters */
1367 err = create_session_params(avctx);
1368 if (err < 0)
1369 return err;
1370
1371 return 0;
1372}
1373
1374static int vulkan_encode_h265_add_nal(AVCodecContext *avctx,
1375 CodedBitstreamFragment *au,
1376 void *nal_unit)
1377{
1378 H265RawNALUnitHeader *header = nal_unit;
1379
1380 int err = ff_cbs_insert_unit_content(au, -1,
1381 header->nal_unit_type, nal_unit, NULL);
1382 if (err < 0)
1383 av_log(avctx, AV_LOG_ERROR, "Failed to add NAL unit: "
1384 "type = %d.\n", header->nal_unit_type);
1385
1386 return err;
1387}
1388
1389static int write_access_unit(AVCodecContext *avctx,
1390 uint8_t *data, size_t *data_len,
1391 CodedBitstreamFragment *au)
1392{
1393 VulkanEncodeH265Context *enc = avctx->priv_data;
1394
1395 int err = ff_cbs_write_fragment_data(enc->cbs, au);
1396 if (err < 0) {
1397 av_log(avctx, AV_LOG_ERROR, "Failed to write packed header.\n");
1398 return err;
1399 }
1400
1401 if (*data_len < au->data_size) {
1402 av_log(avctx, AV_LOG_ERROR, "Access unit too large: %zu < %zu.\n",
1403 *data_len, au->data_size);
1404 return AVERROR(ENOSPC);
1405 }
1406
1407 memcpy(data, au->data, au->data_size);
1408 *data_len = au->data_size;
1409
1410 return 0;
1411}
1412
1413static int write_sequence_headers(AVCodecContext *avctx,
1414 FFHWBaseEncodePicture *base_pic,
1415 uint8_t *data, size_t *data_len)
1416{
1417 int err;
1418 VulkanEncodeH265Context *enc = avctx->priv_data;
1419 VulkanEncodeH265Picture *hp = base_pic ? base_pic->codec_priv : NULL;
1420 CodedBitstreamFragment *au = &enc->current_access_unit;
1421
1422 if (hp && hp->units_needed & UNIT_AUD) {
1423 err = vulkan_encode_h265_add_nal(avctx, au, &enc->raw_aud);
1424 if (err < 0)
1425 goto fail;
1426 hp->units_needed &= ~UNIT_AUD;
1427 }
1428
1429 err = vulkan_encode_h265_add_nal(avctx, au, &enc->units.raw_vps);
1430 if (err < 0)
1431 goto fail;
1432
1433 err = vulkan_encode_h265_add_nal(avctx, au, &enc->units.raw_sps);
1434 if (err < 0)
1435 goto fail;
1436
1437 err = vulkan_encode_h265_add_nal(avctx, au, &enc->units.raw_pps);
1438 if (err < 0)
1439 goto fail;
1440
1441 err = write_access_unit(avctx, data, data_len, au);
1442fail:
1443 ff_cbs_fragment_reset(au);
1444 return err;
1445}
1446
1447static int write_extra_headers(AVCodecContext *avctx,
1448 FFHWBaseEncodePicture *base_pic,
1449 uint8_t *data, size_t *data_len)
1450{
1451 int err;
1452 VulkanEncodeH265Context *enc = avctx->priv_data;
1453 VulkanEncodeH265Picture *hp = base_pic->codec_priv;
1454 CodedBitstreamFragment *au = &enc->current_access_unit;
1455
1456 if (hp->units_needed & UNIT_AUD) {
1457 err = vulkan_encode_h265_add_nal(avctx, au, &enc->raw_aud);
1458 if (err < 0)
1459 goto fail;
1460 }
1461
1462 if (hp->units_needed & UNIT_SEI_MASTERING_DISPLAY) {
1463 err = ff_cbs_sei_add_message(enc->cbs, au, 1,
1464 SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME,
1465 &enc->sei_mastering_display, NULL);
1466 if (err < 0)
1467 goto fail;
1468 }
1469
1470 if (hp->units_needed & UNIT_SEI_CONTENT_LIGHT_LEVEL) {
1471 err = ff_cbs_sei_add_message(enc->cbs, au, 1,
1472 SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO,
1473 &enc->sei_content_light_level, NULL);
1474 if (err < 0)
1475 goto fail;
1476 }
1477 if (hp->units_needed & UNIT_SEI_A53_CC) {
1478 err = ff_cbs_sei_add_message(enc->cbs, au, 1,
1479 SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35,
1480 &enc->sei_a53cc, NULL);
1481 if (err < 0)
1482 goto fail;
1483 }
1484
1485 if (hp->units_needed) {
1486 err = write_access_unit(avctx, data, data_len, au);
1487 if (err < 0)
1488 goto fail;
1489 } else {
1490 *data_len = 0;
1491 }
1492
1493fail:
1494 ff_cbs_fragment_reset(au);
1495 return err;
1496}
1497
1498static int write_filler(AVCodecContext *avctx, uint32_t filler,
1499 uint8_t *data, size_t *data_len)
1500{
1501 int err;
1502 VulkanEncodeH265Context *enc = avctx->priv_data;
1503 CodedBitstreamFragment *au = &enc->current_access_unit;
1504
1505 H265RawFiller raw_filler = {
1506 .nal_unit_header =
1507 {
1508 .nal_unit_type = HEVC_NAL_FD_NUT,
1509 .nuh_temporal_id_plus1 = 1,
1510 },
1511 .filler_size = filler,
1512 };
1513
1514 err = vulkan_encode_h265_add_nal(avctx, au, &raw_filler);
1515 if (err < 0)
1516 goto fail;
1517
1518 err = write_access_unit(avctx, data, data_len, au);
1519fail:
1520 ff_cbs_fragment_reset(au);
1521 return err;
1522}
1523
1524static const FFVulkanCodec enc_cb = {
1525 .flags = FF_HW_FLAG_B_PICTURES |
1526 FF_HW_FLAG_B_PICTURE_REFERENCES |
1527 FF_HW_FLAG_NON_IDR_KEY_PICTURES,
1528 .picture_priv_data_size = sizeof(VulkanEncodeH265Picture),
1529 .filler_header_size = 7,
1530 .init_profile = init_profile,
1531 .init_pic_rc = init_pic_rc,
1532 .init_pic_params = init_pic_params,
1533 .write_sequence_headers = write_sequence_headers,
1534 .write_extra_headers = write_extra_headers,
1535 .write_filler = write_filler,
1536};
1537
1538static av_cold int vulkan_encode_h265_init(AVCodecContext *avctx)
1539{
1540 int err, ref_l0, ref_l1;
1541 VulkanEncodeH265Context *enc = avctx->priv_data;
1542 FFVulkanEncodeContext *ctx = &enc->common;
1543 FFHWBaseEncodeContext *base_ctx = &ctx->base;
1544 int flags;
1545
1546 if (avctx->profile == AV_PROFILE_UNKNOWN)
1547 avctx->profile = enc->common.opts.profile;
1548
1549 enc->caps = (VkVideoEncodeH265CapabilitiesKHR) {
1550 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_CAPABILITIES_KHR,
1551 };
1552
1553 enc->quality_props = (VkVideoEncodeH265QualityLevelPropertiesKHR) {
1554 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_QUALITY_LEVEL_PROPERTIES_KHR,
1555 };
1556
1557 err = ff_vulkan_encode_init(avctx, &enc->common,
1558 &ff_vk_enc_h265_desc, &enc_cb,
1559 &enc->caps, &enc->quality_props);
1560 if (err < 0)
1561 return err;
1562
1563 av_log(avctx, AV_LOG_VERBOSE, "H265 encoder capabilities:\n");
1564 av_log(avctx, AV_LOG_VERBOSE, " Standard capability flags:\n");
1565 av_log(avctx, AV_LOG_VERBOSE, " separate_color_plane: %i\n",
1566 !!(enc->caps.stdSyntaxFlags & VK_VIDEO_ENCODE_H265_STD_SEPARATE_COLOR_PLANE_FLAG_SET_BIT_KHR));
1567 av_log(avctx, AV_LOG_VERBOSE, " sample_adaptive_offset: %i\n",
1568 !!(enc->caps.stdSyntaxFlags & VK_VIDEO_ENCODE_H265_STD_SAMPLE_ADAPTIVE_OFFSET_ENABLED_FLAG_SET_BIT_KHR));
1569 av_log(avctx, AV_LOG_VERBOSE, " scaling_lists: %i\n",
1570 !!(enc->caps.stdSyntaxFlags & VK_VIDEO_ENCODE_H265_STD_SCALING_LIST_DATA_PRESENT_FLAG_SET_BIT_KHR));
1571 av_log(avctx, AV_LOG_VERBOSE, " pcm: %i\n",
1572 !!(enc->caps.stdSyntaxFlags & VK_VIDEO_ENCODE_H265_STD_PCM_ENABLED_FLAG_SET_BIT_KHR));
1573 av_log(avctx, AV_LOG_VERBOSE, " temporal_mvp: %i\n",
1574 !!(enc->caps.stdSyntaxFlags & VK_VIDEO_ENCODE_H265_STD_SPS_TEMPORAL_MVP_ENABLED_FLAG_SET_BIT_KHR));
1575 av_log(avctx, AV_LOG_VERBOSE, " init_qp: %i\n",
1576 !!(enc->caps.stdSyntaxFlags & VK_VIDEO_ENCODE_H265_STD_INIT_QP_MINUS26_BIT_KHR));
1577 av_log(avctx, AV_LOG_VERBOSE, " weighted:%s%s\n",
1578 enc->caps.stdSyntaxFlags & VK_VIDEO_ENCODE_H265_STD_WEIGHTED_PRED_FLAG_SET_BIT_KHR ?
1579 " pred" : "",
1580 enc->caps.stdSyntaxFlags & VK_VIDEO_ENCODE_H265_STD_WEIGHTED_BIPRED_FLAG_SET_BIT_KHR ?
1581 " bipred" : "");
1582 av_log(avctx, AV_LOG_VERBOSE, " parallel_merge_level: %i\n",
1583 !!(enc->caps.stdSyntaxFlags & VK_VIDEO_ENCODE_H265_STD_LOG2_PARALLEL_MERGE_LEVEL_MINUS2_BIT_KHR));
1584 av_log(avctx, AV_LOG_VERBOSE, " sign_data_hiding: %i\n",
1585 !!(enc->caps.stdSyntaxFlags & VK_VIDEO_ENCODE_H265_STD_SIGN_DATA_HIDING_ENABLED_FLAG_SET_BIT_KHR));
1586 av_log(avctx, AV_LOG_VERBOSE, " transform_skip:%s%s\n",
1587 enc->caps.stdSyntaxFlags & VK_VIDEO_ENCODE_H265_STD_TRANSFORM_SKIP_ENABLED_FLAG_SET_BIT_KHR ?
1588 " set" : "",
1589 enc->caps.stdSyntaxFlags & VK_VIDEO_ENCODE_H265_STD_TRANSFORM_SKIP_ENABLED_FLAG_UNSET_BIT_KHR ?
1590 " unset" : "");
1591 av_log(avctx, AV_LOG_VERBOSE, " slice_chroma_qp_offsets: %i\n",
1592 !!(enc->caps.stdSyntaxFlags & VK_VIDEO_ENCODE_H265_STD_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT_FLAG_SET_BIT_KHR));
1593 av_log(avctx, AV_LOG_VERBOSE, " transquant_bypass: %i\n",
1594 !!(enc->caps.stdSyntaxFlags & VK_VIDEO_ENCODE_H265_STD_TRANSQUANT_BYPASS_ENABLED_FLAG_SET_BIT_KHR));
1595 av_log(avctx, AV_LOG_VERBOSE, " constrained_intra_pred: %i\n",
1596 !!(enc->caps.stdSyntaxFlags & VK_VIDEO_ENCODE_H265_STD_CONSTRAINED_INTRA_PRED_FLAG_SET_BIT_KHR));
1597 av_log(avctx, AV_LOG_VERBOSE, " entrypy_coding_sync: %i\n",
1598 !!(enc->caps.stdSyntaxFlags & VK_VIDEO_ENCODE_H265_STD_ENTROPY_CODING_SYNC_ENABLED_FLAG_SET_BIT_KHR));
1599 av_log(avctx, AV_LOG_VERBOSE, " dependent_slice_segment:%s%s\n",
1600 enc->caps.stdSyntaxFlags & VK_VIDEO_ENCODE_H265_STD_DEPENDENT_SLICE_SEGMENTS_ENABLED_FLAG_SET_BIT_KHR ?
1601 " enabled" : "",
1602 enc->caps.stdSyntaxFlags & VK_VIDEO_ENCODE_H265_STD_DEPENDENT_SLICE_SEGMENT_FLAG_SET_BIT_KHR ?
1603 " set" : "");
1604 av_log(avctx, AV_LOG_VERBOSE, " slice_qp_delta: %i\n",
1605 !!(enc->caps.stdSyntaxFlags & VK_VIDEO_ENCODE_H265_STD_SLICE_QP_DELTA_BIT_KHR));
1606 av_log(avctx, AV_LOG_VERBOSE, " different_slice_qp_delta: %i\n",
1607 !!(enc->caps.stdSyntaxFlags & VK_VIDEO_ENCODE_H265_STD_DIFFERENT_SLICE_QP_DELTA_BIT_KHR));
1608
1609 av_log(avctx, AV_LOG_VERBOSE, " Capability flags:\n");
1610 av_log(avctx, AV_LOG_VERBOSE, " hdr_compliance: %i\n",
1611 !!(enc->caps.flags & VK_VIDEO_ENCODE_H264_CAPABILITY_HRD_COMPLIANCE_BIT_KHR));
1612 av_log(avctx, AV_LOG_VERBOSE, " pred_weight_table_generated: %i\n",
1613 !!(enc->caps.flags & VK_VIDEO_ENCODE_H264_CAPABILITY_PREDICTION_WEIGHT_TABLE_GENERATED_BIT_KHR));
1614 av_log(avctx, AV_LOG_VERBOSE, " row_unaligned_slice: %i\n",
1615 !!(enc->caps.flags & VK_VIDEO_ENCODE_H264_CAPABILITY_ROW_UNALIGNED_SLICE_BIT_KHR));
1616 av_log(avctx, AV_LOG_VERBOSE, " different_slice_type: %i\n",
1617 !!(enc->caps.flags & VK_VIDEO_ENCODE_H264_CAPABILITY_DIFFERENT_SLICE_TYPE_BIT_KHR));
1618 av_log(avctx, AV_LOG_VERBOSE, " b_frame_in_l0_list: %i\n",
1619 !!(enc->caps.flags & VK_VIDEO_ENCODE_H264_CAPABILITY_B_FRAME_IN_L0_LIST_BIT_KHR));
1620 av_log(avctx, AV_LOG_VERBOSE, " b_frame_in_l1_list: %i\n",
1621 !!(enc->caps.flags & VK_VIDEO_ENCODE_H264_CAPABILITY_B_FRAME_IN_L1_LIST_BIT_KHR));
1622 av_log(avctx, AV_LOG_VERBOSE, " per_pict_type_min_max_qp: %i\n",
1623 !!(enc->caps.flags & VK_VIDEO_ENCODE_H264_CAPABILITY_PER_PICTURE_TYPE_MIN_MAX_QP_BIT_KHR));
1624 av_log(avctx, AV_LOG_VERBOSE, " per_slice_constant_qp: %i\n",
1625 !!(enc->caps.flags & VK_VIDEO_ENCODE_H264_CAPABILITY_PER_SLICE_CONSTANT_QP_BIT_KHR));
1626 av_log(avctx, AV_LOG_VERBOSE, " generate_prefix_nalu: %i\n",
1627 !!(enc->caps.flags & VK_VIDEO_ENCODE_H264_CAPABILITY_GENERATE_PREFIX_NALU_BIT_KHR));
1628
1629 av_log(avctx, AV_LOG_VERBOSE, " Capabilities:\n");
1630 av_log(avctx, AV_LOG_VERBOSE, " maxLevelIdc: %i\n",
1631 enc->caps.maxLevelIdc);
1632 av_log(avctx, AV_LOG_VERBOSE, " maxSliceCount: %i\n",
1633 enc->caps.maxSliceSegmentCount);
1634 av_log(avctx, AV_LOG_VERBOSE, " maxTiles: %ix%i\n",
1635 enc->caps.maxTiles.width, enc->caps.maxTiles.height);
1636 av_log(avctx, AV_LOG_VERBOSE, " cbtSizes: 0x%x\n",
1637 enc->caps.ctbSizes);
1638 av_log(avctx, AV_LOG_VERBOSE, " transformBlockSizes: 0x%x\n",
1639 enc->caps.transformBlockSizes);
1640 av_log(avctx, AV_LOG_VERBOSE, " max(P/B)PictureL0ReferenceCount: %i P's; %i B's\n",
1641 enc->caps.maxPPictureL0ReferenceCount,
1642 enc->caps.maxBPictureL0ReferenceCount);
1643 av_log(avctx, AV_LOG_VERBOSE, " maxL1ReferenceCount: %i\n",
1644 enc->caps.maxL1ReferenceCount);
1645 av_log(avctx, AV_LOG_VERBOSE, " maxSubLayerCount: %i\n",
1646 enc->caps.maxSubLayerCount);
1647 av_log(avctx, AV_LOG_VERBOSE, " expectDyadicTemporalLayerPattern: %i\n",
1648 enc->caps.expectDyadicTemporalSubLayerPattern);
1649 av_log(avctx, AV_LOG_VERBOSE, " min/max Qp: [%i, %i]\n",
1650 enc->caps.minQp, enc->caps.maxQp);
1651 av_log(avctx, AV_LOG_VERBOSE, " prefersGopRemainingFrames: %i\n",
1652 enc->caps.prefersGopRemainingFrames);
1653 av_log(avctx, AV_LOG_VERBOSE, " requiresGopRemainingFrames: %i\n",
1654 enc->caps.requiresGopRemainingFrames);
1655
1656 err = init_enc_options(avctx);
1657 if (err < 0)
1658 return err;
1659
1660 flags = ctx->codec->flags;
1661 if (!enc->caps.maxPPictureL0ReferenceCount &&
1662 !enc->caps.maxBPictureL0ReferenceCount &&
1663 !enc->caps.maxL1ReferenceCount) {
1664 /* Intra-only */
1665 flags |= FF_HW_FLAG_INTRA_ONLY;
1666 ref_l0 = ref_l1 = 0;
1667 } else if (!enc->caps.maxPPictureL0ReferenceCount) {
1668 /* No P-frames? How. */
1669 base_ctx->p_to_gpb = 1;
1670 ref_l0 = enc->caps.maxBPictureL0ReferenceCount;
1671 ref_l1 = enc->caps.maxL1ReferenceCount;
1672 } else if (!enc->caps.maxBPictureL0ReferenceCount &&
1673 !enc->caps.maxL1ReferenceCount) {
1674 /* No B-frames */
1675 flags &= ~(FF_HW_FLAG_B_PICTURES | FF_HW_FLAG_B_PICTURE_REFERENCES);
1676 ref_l0 = enc->caps.maxPPictureL0ReferenceCount;
1677 ref_l1 = 0;
1678 } else {
1679 /* P and B frames */
1680 ref_l0 = FFMIN(enc->caps.maxPPictureL0ReferenceCount,
1681 enc->caps.maxBPictureL0ReferenceCount);
1682 ref_l1 = enc->caps.maxL1ReferenceCount;
1683 }
1684
1685 err = ff_hw_base_init_gop_structure(base_ctx, avctx, ref_l0, ref_l1,
1686 flags, 0);
1687 if (err < 0)
1688 return err;
1689
1690 base_ctx->output_delay = base_ctx->b_per_p;
1691 base_ctx->decode_delay = base_ctx->max_b_depth;
1692
1693 /* Init CBS */
1694 err = ff_cbs_init(&enc->cbs, AV_CODEC_ID_HEVC, avctx);
1695 if (err < 0)
1696 return err;
1697
1698 /* Create units and session parameters */
1699 err = init_base_units(avctx);
1700 if (err < 0)
1701 return err;
1702
1703 /* Write out extradata */
1704 err = ff_vulkan_write_global_header(avctx, &enc->common);
1705 if (err < 0)
1706 return err;
1707
1708 return 0;
1709}
1710
1711static av_cold int vulkan_encode_h265_close(AVCodecContext *avctx)
1712{
1713 VulkanEncodeH265Context *enc = avctx->priv_data;
1714 ff_vulkan_encode_uninit(&enc->common);
1715 return 0;
1716}
1717
1718#define OFFSET(x) offsetof(VulkanEncodeH265Context, x)
1719#define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
1720static const AVOption vulkan_encode_h265_options[] = {
1721 HW_BASE_ENCODE_COMMON_OPTIONS,
1722 VULKAN_ENCODE_COMMON_OPTIONS,
1723
1724 { "profile", "Set profile (profile_idc and constraint_set*_flag)",
1725 OFFSET(common.opts.profile), AV_OPT_TYPE_INT,
1726 { .i64 = AV_PROFILE_UNKNOWN }, AV_PROFILE_UNKNOWN, 0xffff, FLAGS, .unit = "profile" },
1727
1728#define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
1729 { .i64 = value }, 0, 0, FLAGS, .unit = "profile"
1730 { PROFILE("main", AV_PROFILE_HEVC_MAIN) },
1731 { PROFILE("main10", AV_PROFILE_HEVC_MAIN_10) },
1732 { PROFILE("rext", AV_PROFILE_HEVC_REXT) },
1733#undef PROFILE
1734
1735 { "tier", "Set tier (general_tier_flag)", OFFSET(common.opts.tier), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS, .unit = "tier" },
1736 { "main", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FLAGS, .unit = "tier" },
1737 { "high", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, FLAGS, .unit = "tier" },
1738
1739 { "level", "Set level (general_level_idc)",
1740 OFFSET(common.opts.level), AV_OPT_TYPE_INT,
1741 { .i64 = AV_LEVEL_UNKNOWN }, AV_LEVEL_UNKNOWN, 0xff, FLAGS, .unit = "level" },
1742
1743#define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
1744 { .i64 = value }, 0, 0, FLAGS, .unit = "level"
1745 { LEVEL("1", 30) },
1746 { LEVEL("2", 60) },
1747 { LEVEL("2.1", 63) },
1748 { LEVEL("3", 90) },
1749 { LEVEL("3.1", 93) },
1750 { LEVEL("4", 120) },
1751 { LEVEL("4.1", 123) },
1752 { LEVEL("5", 150) },
1753 { LEVEL("5.1", 153) },
1754 { LEVEL("5.2", 156) },
1755 { LEVEL("6", 180) },
1756 { LEVEL("6.1", 183) },
1757 { LEVEL("6.2", 186) },
1758#undef LEVEL
1759
1760 { "units", "Set units to include", OFFSET(unit_elems), AV_OPT_TYPE_FLAGS, { .i64 = UNIT_SEI_MASTERING_DISPLAY | UNIT_SEI_CONTENT_LIGHT_LEVEL | UNIT_SEI_A53_CC }, 0, INT_MAX, FLAGS, "units" },
1761 { "hdr", "Include HDR metadata for mastering display colour volume and content light level information", 0, AV_OPT_TYPE_CONST, { .i64 = UNIT_SEI_MASTERING_DISPLAY | UNIT_SEI_CONTENT_LIGHT_LEVEL }, INT_MIN, INT_MAX, FLAGS, "units" },
1762 { "a53_cc", "Include A/53 caption data", 0, AV_OPT_TYPE_CONST, { .i64 = UNIT_SEI_A53_CC }, INT_MIN, INT_MAX, FLAGS, "units" },
1763
1764 { NULL },
1765};
1766
1767static const FFCodecDefault vulkan_encode_h265_defaults[] = {
1768 { "b", "0" },
1769 { "bf", "2" },
1770 { "g", "300" },
1771 { "i_qfactor", "1" },
1772 { "i_qoffset", "0" },
1773 { "b_qfactor", "6/5" },
1774 { "b_qoffset", "0" },
1775 { "qmin", "-1" },
1776 { "qmax", "-1" },
1777 { NULL },
1778};
1779
1780static const AVClass vulkan_encode_h265_class = {
1781 .class_name = "hevc_vulkan",
1782 .item_name = av_default_item_name,
1783 .option = vulkan_encode_h265_options,
1784 .version = LIBAVUTIL_VERSION_INT,
1785};
1786
1787const FFCodec ff_hevc_vulkan_encoder = {
1788 .p.name = "hevc_vulkan",
1789 CODEC_LONG_NAME("H.265/HEVC (Vulkan)"),
1790 .p.type = AVMEDIA_TYPE_VIDEO,
1791 .p.id = AV_CODEC_ID_HEVC,
1792 .priv_data_size = sizeof(VulkanEncodeH265Context),
1793 .init = &vulkan_encode_h265_init,
1794 FF_CODEC_RECEIVE_PACKET_CB(&ff_vulkan_encode_receive_packet),
1795 .close = &vulkan_encode_h265_close,
1796 .p.priv_class = &vulkan_encode_h265_class,
1797 .p.capabilities = AV_CODEC_CAP_DELAY |
1798 AV_CODEC_CAP_HARDWARE |
1799 AV_CODEC_CAP_DR1 |
1800 AV_CODEC_CAP_ENCODER_FLUSH |
1801 AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
1802 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1803 .defaults = vulkan_encode_h265_defaults,
1804 .p.pix_fmts = (const enum AVPixelFormat[]) {
1805 AV_PIX_FMT_VULKAN,
1806 AV_PIX_FMT_NONE,
1807 },
1808 .hw_configs = ff_vulkan_encode_hw_configs,
1809 .p.wrapper_name = "vulkan",
1810};
libavcodec/vulkan_hevc.c+3−22
@@ -179,25 +179,6 @@ static int vk_hevc_fill_pict(AVCodecContext *avctx, HEVCFrame **ref_src, · 178 unmodified lines
179 return 0;179 return 0;
180}180}
181 181
182static StdVideoH265LevelIdc convert_to_vk_level_idc(int level_idc)
183{
184 switch (level_idc) {
185 case 10: return STD_VIDEO_H265_LEVEL_IDC_1_0;
186 case 20: return STD_VIDEO_H265_LEVEL_IDC_2_0;
187 case 21: return STD_VIDEO_H265_LEVEL_IDC_2_1;
188 case 30: return STD_VIDEO_H265_LEVEL_IDC_3_0;
189 case 31: return STD_VIDEO_H265_LEVEL_IDC_3_1;
190 case 40: return STD_VIDEO_H265_LEVEL_IDC_4_0;
191 case 41: return STD_VIDEO_H265_LEVEL_IDC_4_1;
192 case 50: return STD_VIDEO_H265_LEVEL_IDC_5_0;
193 case 51: return STD_VIDEO_H265_LEVEL_IDC_5_1;
194 case 60: return STD_VIDEO_H265_LEVEL_IDC_6_0;
195 case 61: return STD_VIDEO_H265_LEVEL_IDC_6_1;
196 default:
197 case 62: return STD_VIDEO_H265_LEVEL_IDC_6_2;
198 }
199}
200
201static void copy_scaling_list(const ScalingList *sl, StdVideoH265ScalingLists *vksl)182static void copy_scaling_list(const ScalingList *sl, StdVideoH265ScalingLists *vksl)
202{183{
203 for (int i = 0; i < STD_VIDEO_H265_SCALING_LIST_4X4_NUM_LISTS; i++) {184 for (int i = 0; i < STD_VIDEO_H265_SCALING_LIST_4X4_NUM_LISTS; i++) {
@@ -338,7 +319,7 @@ static void set_sps(const HEVCSPS *sps, int sps_idx, · 134 unmodified lines
338 .general_frame_only_constraint_flag = sps->ptl.general_ptl.frame_only_constraint_flag,319 .general_frame_only_constraint_flag = sps->ptl.general_ptl.frame_only_constraint_flag,
339 },320 },
340 .general_profile_idc = sps->ptl.general_ptl.profile_idc,321 .general_profile_idc = sps->ptl.general_ptl.profile_idc,
341 .general_level_idc = convert_to_vk_level_idc(sps->ptl.general_ptl.level_idc),322 .general_level_idc = ff_vk_h265_level_to_vk(sps->ptl.general_ptl.level_idc),
342 };323 };
343 324
344 for (int i = 0; i < sps->max_sub_layers; i++) {325 for (int i = 0; i < sps->max_sub_layers; i++) {
@@ -607,8 +588,8 @@ static void set_vps(const HEVCVPS *vps, · 262 unmodified lines
607 .general_non_packed_constraint_flag = vps->ptl.general_ptl.non_packed_constraint_flag,588 .general_non_packed_constraint_flag = vps->ptl.general_ptl.non_packed_constraint_flag,
608 .general_frame_only_constraint_flag = vps->ptl.general_ptl.frame_only_constraint_flag,589 .general_frame_only_constraint_flag = vps->ptl.general_ptl.frame_only_constraint_flag,
609 },590 },
610 .general_profile_idc = vps->ptl.general_ptl.profile_idc,591 .general_profile_idc = ff_vk_h265_profile_to_vk(vps->ptl.general_ptl.profile_idc),
611 .general_level_idc = convert_to_vk_level_idc(vps->ptl.general_ptl.level_idc),592 .general_level_idc = ff_vk_h265_level_to_vk(vps->ptl.general_ptl.level_idc),
612 };593 };
613 594
614 for (int i = 0; i < vps->vps_max_sub_layers; i++) {595 for (int i = 0; i < vps->vps_max_sub_layers; i++) {
libavcodec/vulkan_video.c+39−0
@@ -203,6 +203,25 @@ int ff_vk_h265_level_to_av(StdVideoH265LevelIdc level) · 202 unmodified lines
203 }203 }
204}204}
205 205
206StdVideoH265LevelIdc ff_vk_h265_level_to_vk(int level_idc)
207{
208 switch (level_idc) {
209 case 10: return STD_VIDEO_H265_LEVEL_IDC_1_0;
210 case 20: return STD_VIDEO_H265_LEVEL_IDC_2_0;
211 case 21: return STD_VIDEO_H265_LEVEL_IDC_2_1;
212 case 30: return STD_VIDEO_H265_LEVEL_IDC_3_0;
213 case 31: return STD_VIDEO_H265_LEVEL_IDC_3_1;
214 case 40: return STD_VIDEO_H265_LEVEL_IDC_4_0;
215 case 41: return STD_VIDEO_H265_LEVEL_IDC_4_1;
216 case 50: return STD_VIDEO_H265_LEVEL_IDC_5_0;
217 case 51: return STD_VIDEO_H265_LEVEL_IDC_5_1;
218 case 60: return STD_VIDEO_H265_LEVEL_IDC_6_0;
219 case 61: return STD_VIDEO_H265_LEVEL_IDC_6_1;
220 default:
221 case 62: return STD_VIDEO_H265_LEVEL_IDC_6_2;
222 }
223}
224
206StdVideoH264ProfileIdc ff_vk_h264_profile_to_vk(int profile)225StdVideoH264ProfileIdc ff_vk_h264_profile_to_vk(int profile)
207{226{
208 switch (profile) {227 switch (profile) {
@@ -214,6 +233,16 @@ StdVideoH264ProfileIdc ff_vk_h264_profile_to_vk(int profile) · 5 unmodified lines
214 }233 }
215}234}
216 235
236StdVideoH265ProfileIdc ff_vk_h265_profile_to_vk(int profile)
237{
238 switch (profile) {
239 case AV_PROFILE_HEVC_MAIN: return STD_VIDEO_H265_PROFILE_IDC_MAIN;
240 case AV_PROFILE_HEVC_MAIN_10: return STD_VIDEO_H265_PROFILE_IDC_MAIN_10;
241 case AV_PROFILE_HEVC_REXT: return STD_VIDEO_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSIONS;
242 default: return STD_VIDEO_H265_PROFILE_IDC_INVALID;
243 }
244}
245
217int ff_vk_h264_profile_to_av(StdVideoH264ProfileIdc profile)246int ff_vk_h264_profile_to_av(StdVideoH264ProfileIdc profile)
218{247{
219 switch (profile) {248 switch (profile) {
@@ -225,6 +254,16 @@ int ff_vk_h264_profile_to_av(StdVideoH264ProfileIdc profile) · 5 unmodified lines
225 }254 }
226}255}
227 256
257int ff_vk_h265_profile_to_av(StdVideoH264ProfileIdc profile)
258{
259 switch (profile) {
260 case STD_VIDEO_H265_PROFILE_IDC_MAIN: return AV_PROFILE_HEVC_MAIN;
261 case STD_VIDEO_H265_PROFILE_IDC_MAIN_10: return AV_PROFILE_HEVC_MAIN_10;
262 case STD_VIDEO_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSIONS: return AV_PROFILE_HEVC_REXT;
263 default: return AV_PROFILE_UNKNOWN;
264 }
265}
266
228int ff_vk_video_qf_init(FFVulkanContext *s, FFVkQueueFamilyCtx *qf,267int ff_vk_video_qf_init(FFVulkanContext *s, FFVkQueueFamilyCtx *qf,
229 VkQueueFlagBits family, VkVideoCodecOperationFlagBitsKHR caps)268 VkQueueFlagBits family, VkVideoCodecOperationFlagBitsKHR caps)
230{269{
libavcodec/vulkan_video.h+3−0
@@ -76,12 +76,15 @@ int ff_vk_h264_level_to_av(StdVideoH264LevelIdc level); · 75 unmodified lines
76int ff_vk_h265_level_to_av(StdVideoH265LevelIdc level);76int ff_vk_h265_level_to_av(StdVideoH265LevelIdc level);
77 77
78StdVideoH264LevelIdc ff_vk_h264_level_to_vk(int level_idc);78StdVideoH264LevelIdc ff_vk_h264_level_to_vk(int level_idc);
79StdVideoH265LevelIdc ff_vk_h265_level_to_vk(int level_idc);
79 80
80/**81/**
81 * Convert profile from/to AV to Vulkan82 * Convert profile from/to AV to Vulkan
82 */83 */
83StdVideoH264ProfileIdc ff_vk_h264_profile_to_vk(int profile);84StdVideoH264ProfileIdc ff_vk_h264_profile_to_vk(int profile);
85StdVideoH265ProfileIdc ff_vk_h265_profile_to_vk(int profile);
84int ff_vk_h264_profile_to_av(StdVideoH264ProfileIdc profile);86int ff_vk_h264_profile_to_av(StdVideoH264ProfileIdc profile);
87int ff_vk_h265_profile_to_av(StdVideoH264ProfileIdc profile);
85 88
86/**89/**
87 * Creates image views for video frames.90 * Creates image views for video frames.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t