]> git.sesse.net Git - ffmpeg/blob - libavcodec/vaapi_encode_h265.c
lavc/hevcdec: Treat clean random access nals as keyframes for -skip_frame.
[ffmpeg] / libavcodec / vaapi_encode_h265.c
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 <string.h>
20
21 #include <va/va.h>
22 #include <va/va_enc_hevc.h>
23
24 #include "libavutil/avassert.h"
25 #include "libavutil/common.h"
26 #include "libavutil/opt.h"
27 #include "libavutil/mastering_display_metadata.h"
28
29 #include "avcodec.h"
30 #include "cbs.h"
31 #include "cbs_h265.h"
32 #include "hevc.h"
33 #include "hevc_sei.h"
34 #include "internal.h"
35 #include "put_bits.h"
36 #include "vaapi_encode.h"
37
38 enum {
39     SEI_MASTERING_DISPLAY       = 0x08,
40     SEI_CONTENT_LIGHT_LEVEL     = 0x10,
41 };
42
43 typedef struct VAAPIEncodeH265Context {
44     unsigned int ctu_width;
45     unsigned int ctu_height;
46
47     int fixed_qp_idr;
48     int fixed_qp_p;
49     int fixed_qp_b;
50
51     H265RawAUD aud;
52     H265RawVPS vps;
53     H265RawSPS sps;
54     H265RawPPS pps;
55     H265RawSlice slice;
56     H265RawSEI sei;
57
58     H265RawSEIMasteringDisplayColourVolume mastering_display;
59     H265RawSEIContentLightLevelInfo content_light_level;
60
61     int64_t last_idr_frame;
62     int pic_order_cnt;
63
64     int slice_nal_unit;
65     int slice_type;
66     int pic_type;
67
68     CodedBitstreamContext *cbc;
69     CodedBitstreamFragment current_access_unit;
70     int aud_needed;
71     int sei_needed;
72 } VAAPIEncodeH265Context;
73
74 typedef struct VAAPIEncodeH265Options {
75     int qp;
76     int aud;
77     int profile;
78     int level;
79     int sei;
80 } VAAPIEncodeH265Options;
81
82
83 static int vaapi_encode_h265_write_access_unit(AVCodecContext *avctx,
84                                                char *data, size_t *data_len,
85                                                CodedBitstreamFragment *au)
86 {
87     VAAPIEncodeContext      *ctx = avctx->priv_data;
88     VAAPIEncodeH265Context *priv = ctx->priv_data;
89     int err;
90
91     err = ff_cbs_write_fragment_data(priv->cbc, au);
92     if (err < 0) {
93         av_log(avctx, AV_LOG_ERROR, "Failed to write packed header.\n");
94         return err;
95     }
96
97     if (*data_len < 8 * au->data_size - au->data_bit_padding) {
98         av_log(avctx, AV_LOG_ERROR, "Access unit too large: "
99                "%zu < %zu.\n", *data_len,
100                8 * au->data_size - au->data_bit_padding);
101         return AVERROR(ENOSPC);
102     }
103
104     memcpy(data, au->data, au->data_size);
105     *data_len = 8 * au->data_size - au->data_bit_padding;
106
107     return 0;
108 }
109
110 static int vaapi_encode_h265_add_nal(AVCodecContext *avctx,
111                                      CodedBitstreamFragment *au,
112                                      void *nal_unit)
113 {
114     VAAPIEncodeContext      *ctx = avctx->priv_data;
115     VAAPIEncodeH265Context *priv = ctx->priv_data;
116     H265RawNALUnitHeader *header = nal_unit;
117     int err;
118
119     err = ff_cbs_insert_unit_content(priv->cbc, au, -1,
120                                      header->nal_unit_type, nal_unit, NULL);
121     if (err < 0) {
122         av_log(avctx, AV_LOG_ERROR, "Failed to add NAL unit: "
123                "type = %d.\n", header->nal_unit_type);
124         return err;
125     }
126
127     return 0;
128 }
129
130 static int vaapi_encode_h265_write_sequence_header(AVCodecContext *avctx,
131                                                    char *data, size_t *data_len)
132 {
133     VAAPIEncodeContext      *ctx = avctx->priv_data;
134     VAAPIEncodeH265Context *priv = ctx->priv_data;
135     CodedBitstreamFragment   *au = &priv->current_access_unit;
136     int err;
137
138     if (priv->aud_needed) {
139         err = vaapi_encode_h265_add_nal(avctx, au, &priv->aud);
140         if (err < 0)
141             goto fail;
142         priv->aud_needed = 0;
143     }
144
145     err = vaapi_encode_h265_add_nal(avctx, au, &priv->vps);
146     if (err < 0)
147         goto fail;
148
149     err = vaapi_encode_h265_add_nal(avctx, au, &priv->sps);
150     if (err < 0)
151         goto fail;
152
153     err = vaapi_encode_h265_add_nal(avctx, au, &priv->pps);
154     if (err < 0)
155         goto fail;
156
157     err = vaapi_encode_h265_write_access_unit(avctx, data, data_len, au);
158 fail:
159     ff_cbs_fragment_uninit(priv->cbc, au);
160     return err;
161 }
162
163 static int vaapi_encode_h265_write_slice_header(AVCodecContext *avctx,
164                                                 VAAPIEncodePicture *pic,
165                                                 VAAPIEncodeSlice *slice,
166                                                 char *data, size_t *data_len)
167 {
168     VAAPIEncodeContext      *ctx = avctx->priv_data;
169     VAAPIEncodeH265Context *priv = ctx->priv_data;
170     CodedBitstreamFragment   *au = &priv->current_access_unit;
171     int err;
172
173     if (priv->aud_needed) {
174         err = vaapi_encode_h265_add_nal(avctx, au, &priv->aud);
175         if (err < 0)
176             goto fail;
177         priv->aud_needed = 0;
178     }
179
180     err = vaapi_encode_h265_add_nal(avctx, au, &priv->slice);
181     if (err < 0)
182         goto fail;
183
184     err = vaapi_encode_h265_write_access_unit(avctx, data, data_len, au);
185 fail:
186     ff_cbs_fragment_uninit(priv->cbc, au);
187     return err;
188 }
189
190 static int vaapi_encode_h265_write_extra_header(AVCodecContext *avctx,
191                                                 VAAPIEncodePicture *pic,
192                                                 int index, int *type,
193                                                 char *data, size_t *data_len)
194 {
195     VAAPIEncodeContext      *ctx = avctx->priv_data;
196     VAAPIEncodeH265Context *priv = ctx->priv_data;
197     CodedBitstreamFragment   *au = &priv->current_access_unit;
198     int err, i;
199
200     if (priv->sei_needed) {
201         if (priv->aud_needed) {
202             err = vaapi_encode_h265_add_nal(avctx, au, &priv->aud);
203             if (err < 0)
204                 goto fail;
205             priv->aud_needed = 0;
206         }
207
208         memset(&priv->sei, 0, sizeof(priv->sei));
209         priv->sei.nal_unit_header  = (H265RawNALUnitHeader) {
210             .nal_unit_type         = HEVC_NAL_SEI_PREFIX,
211             .nuh_layer_id          = 0,
212             .nuh_temporal_id_plus1 = 1,
213         };
214
215         i = 0;
216
217         if (priv->sei_needed & SEI_MASTERING_DISPLAY) {
218             priv->sei.payload[i].payload_type = HEVC_SEI_TYPE_MASTERING_DISPLAY_INFO;
219             priv->sei.payload[i].payload.mastering_display = priv->mastering_display;
220             ++i;
221         }
222
223         if (priv->sei_needed & SEI_CONTENT_LIGHT_LEVEL) {
224             priv->sei.payload[i].payload_type = HEVC_SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO;
225             priv->sei.payload[i].payload.content_light_level = priv->content_light_level;
226             ++i;
227         }
228
229         priv->sei.payload_count = i;
230         av_assert0(priv->sei.payload_count > 0);
231
232         err = vaapi_encode_h265_add_nal(avctx, au, &priv->sei);
233         if (err < 0)
234             goto fail;
235         priv->sei_needed = 0;
236
237         err = vaapi_encode_h265_write_access_unit(avctx, data, data_len, au);
238         if (err < 0)
239             goto fail;
240
241         ff_cbs_fragment_uninit(priv->cbc, au);
242
243         *type = VAEncPackedHeaderRawData;
244         return 0;
245     } else {
246         return AVERROR_EOF;
247     }
248
249 fail:
250     ff_cbs_fragment_uninit(priv->cbc, au);
251     return err;
252 }
253
254 static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
255 {
256     VAAPIEncodeContext                *ctx = avctx->priv_data;
257     VAAPIEncodeH265Context           *priv = ctx->priv_data;
258     H265RawVPS                        *vps = &priv->vps;
259     H265RawSPS                        *sps = &priv->sps;
260     H265RawPPS                        *pps = &priv->pps;
261     H265RawVUI                        *vui = &sps->vui;
262     VAEncSequenceParameterBufferHEVC *vseq = ctx->codec_sequence_params;
263     VAEncPictureParameterBufferHEVC  *vpic = ctx->codec_picture_params;
264     int i;
265
266     memset(&priv->current_access_unit, 0,
267            sizeof(priv->current_access_unit));
268
269     memset(vps, 0, sizeof(*vps));
270     memset(sps, 0, sizeof(*sps));
271     memset(pps, 0, sizeof(*pps));
272
273
274     // VPS
275
276     vps->nal_unit_header = (H265RawNALUnitHeader) {
277         .nal_unit_type         = HEVC_NAL_VPS,
278         .nuh_layer_id          = 0,
279         .nuh_temporal_id_plus1 = 1,
280     };
281
282     vps->vps_video_parameter_set_id = 0;
283
284     vps->vps_base_layer_internal_flag  = 1;
285     vps->vps_base_layer_available_flag = 1;
286     vps->vps_max_layers_minus1         = 0;
287     vps->vps_max_sub_layers_minus1     = 0;
288     vps->vps_temporal_id_nesting_flag  = 1;
289
290     vps->profile_tier_level = (H265RawProfileTierLevel) {
291         .general_profile_space = 0,
292         .general_profile_idc   = avctx->profile,
293         .general_tier_flag     = 0,
294
295         .general_progressive_source_flag    = 1,
296         .general_interlaced_source_flag     = 0,
297         .general_non_packed_constraint_flag = 1,
298         .general_frame_only_constraint_flag = 1,
299
300         .general_level_idc     = avctx->level,
301     };
302     vps->profile_tier_level.general_profile_compatibility_flag[avctx->profile & 31] = 1;
303
304     vps->vps_sub_layer_ordering_info_present_flag = 0;
305     vps->vps_max_dec_pic_buffering_minus1[0]      = (ctx->b_per_p > 0) + 1;
306     vps->vps_max_num_reorder_pics[0]              = (ctx->b_per_p > 0);
307     vps->vps_max_latency_increase_plus1[0]        = 0;
308
309     vps->vps_max_layer_id             = 0;
310     vps->vps_num_layer_sets_minus1    = 0;
311     vps->layer_id_included_flag[0][0] = 1;
312
313     vps->vps_timing_info_present_flag = 1;
314     if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
315         vps->vps_num_units_in_tick  = avctx->framerate.den;
316         vps->vps_time_scale         = avctx->framerate.num;
317         vps->vps_poc_proportional_to_timing_flag = 1;
318         vps->vps_num_ticks_poc_diff_one_minus1   = 0;
319     } else {
320         vps->vps_num_units_in_tick  = avctx->time_base.num;
321         vps->vps_time_scale         = avctx->time_base.den;
322         vps->vps_poc_proportional_to_timing_flag = 0;
323     }
324     vps->vps_num_hrd_parameters = 0;
325
326
327     // SPS
328
329     sps->nal_unit_header = (H265RawNALUnitHeader) {
330         .nal_unit_type         = HEVC_NAL_SPS,
331         .nuh_layer_id          = 0,
332         .nuh_temporal_id_plus1 = 1,
333     };
334
335     sps->sps_video_parameter_set_id = vps->vps_video_parameter_set_id;
336
337     sps->sps_max_sub_layers_minus1    = vps->vps_max_sub_layers_minus1;
338     sps->sps_temporal_id_nesting_flag = vps->vps_temporal_id_nesting_flag;
339
340     sps->profile_tier_level = vps->profile_tier_level;
341
342     sps->sps_seq_parameter_set_id = 0;
343
344     sps->chroma_format_idc          = 1; // YUV 4:2:0.
345     sps->separate_colour_plane_flag = 0;
346
347     sps->pic_width_in_luma_samples  = ctx->surface_width;
348     sps->pic_height_in_luma_samples = ctx->surface_height;
349
350     if (avctx->width  != ctx->surface_width ||
351         avctx->height != ctx->surface_height) {
352         sps->conformance_window_flag = 1;
353         sps->conf_win_left_offset   = 0;
354         sps->conf_win_right_offset  =
355             (ctx->surface_width - avctx->width) / 2;
356         sps->conf_win_top_offset    = 0;
357         sps->conf_win_bottom_offset =
358             (ctx->surface_height - avctx->height) / 2;
359     } else {
360         sps->conformance_window_flag = 0;
361     }
362
363     sps->bit_depth_luma_minus8 =
364         avctx->profile == FF_PROFILE_HEVC_MAIN_10 ? 2 : 0;
365     sps->bit_depth_chroma_minus8 = sps->bit_depth_luma_minus8;
366
367     sps->log2_max_pic_order_cnt_lsb_minus4 = 8;
368
369     sps->sps_sub_layer_ordering_info_present_flag =
370         vps->vps_sub_layer_ordering_info_present_flag;
371     for (i = 0; i <= sps->sps_max_sub_layers_minus1; i++) {
372         sps->sps_max_dec_pic_buffering_minus1[i] =
373             vps->vps_max_dec_pic_buffering_minus1[i];
374         sps->sps_max_num_reorder_pics[i] =
375             vps->vps_max_num_reorder_pics[i];
376         sps->sps_max_latency_increase_plus1[i] =
377             vps->vps_max_latency_increase_plus1[i];
378     }
379
380     // These have to come from the capabilities of the encoder.  We have no
381     // way to query them, so just hardcode parameters which work on the Intel
382     // driver.
383     // CTB size from 8x8 to 32x32.
384     sps->log2_min_luma_coding_block_size_minus3   = 0;
385     sps->log2_diff_max_min_luma_coding_block_size = 2;
386     // Transform size from 4x4 to 32x32.
387     sps->log2_min_luma_transform_block_size_minus2   = 0;
388     sps->log2_diff_max_min_luma_transform_block_size = 3;
389     // Full transform hierarchy allowed (2-5).
390     sps->max_transform_hierarchy_depth_inter = 3;
391     sps->max_transform_hierarchy_depth_intra = 3;
392     // AMP works.
393     sps->amp_enabled_flag = 1;
394     // SAO and temporal MVP do not work.
395     sps->sample_adaptive_offset_enabled_flag = 0;
396     sps->sps_temporal_mvp_enabled_flag       = 0;
397
398     sps->pcm_enabled_flag = 0;
399
400     // STRPSs should ideally be here rather than defined individually in
401     // each slice, but the structure isn't completely fixed so for now
402     // don't bother.
403     sps->num_short_term_ref_pic_sets     = 0;
404     sps->long_term_ref_pics_present_flag = 0;
405
406     sps->vui_parameters_present_flag = 1;
407
408     if (avctx->sample_aspect_ratio.num != 0 &&
409         avctx->sample_aspect_ratio.den != 0) {
410         static const AVRational sar_idc[] = {
411             {   0,  0 },
412             {   1,  1 }, {  12, 11 }, {  10, 11 }, {  16, 11 },
413             {  40, 33 }, {  24, 11 }, {  20, 11 }, {  32, 11 },
414             {  80, 33 }, {  18, 11 }, {  15, 11 }, {  64, 33 },
415             { 160, 99 }, {   4,  3 }, {   3,  2 }, {   2,  1 },
416         };
417         int i;
418         for (i = 0; i < FF_ARRAY_ELEMS(sar_idc); i++) {
419             if (avctx->sample_aspect_ratio.num == sar_idc[i].num &&
420                 avctx->sample_aspect_ratio.den == sar_idc[i].den) {
421                 vui->aspect_ratio_idc = i;
422                 break;
423             }
424         }
425         if (i >= FF_ARRAY_ELEMS(sar_idc)) {
426             vui->aspect_ratio_idc = 255;
427             vui->sar_width  = avctx->sample_aspect_ratio.num;
428             vui->sar_height = avctx->sample_aspect_ratio.den;
429         }
430         vui->aspect_ratio_info_present_flag = 1;
431     }
432
433     if (avctx->color_range     != AVCOL_RANGE_UNSPECIFIED ||
434         avctx->color_primaries != AVCOL_PRI_UNSPECIFIED ||
435         avctx->color_trc       != AVCOL_TRC_UNSPECIFIED ||
436         avctx->colorspace      != AVCOL_SPC_UNSPECIFIED) {
437         vui->video_signal_type_present_flag = 1;
438         vui->video_format      = 5; // Unspecified.
439         vui->video_full_range_flag =
440             avctx->color_range == AVCOL_RANGE_JPEG;
441
442         if (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED ||
443             avctx->color_trc       != AVCOL_TRC_UNSPECIFIED ||
444             avctx->colorspace      != AVCOL_SPC_UNSPECIFIED) {
445             vui->colour_description_present_flag = 1;
446             vui->colour_primaries         = avctx->color_primaries;
447             vui->transfer_characteristics = avctx->color_trc;
448             vui->matrix_coefficients      = avctx->colorspace;
449         }
450     } else {
451         vui->video_format             = 5;
452         vui->video_full_range_flag    = 0;
453         vui->colour_primaries         = avctx->color_primaries;
454         vui->transfer_characteristics = avctx->color_trc;
455         vui->matrix_coefficients      = avctx->colorspace;
456     }
457
458     if (avctx->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED) {
459         vui->chroma_loc_info_present_flag = 1;
460         vui->chroma_sample_loc_type_top_field    =
461         vui->chroma_sample_loc_type_bottom_field =
462             avctx->chroma_sample_location - 1;
463     }
464
465     vui->vui_timing_info_present_flag        = 1;
466     vui->vui_num_units_in_tick               = vps->vps_num_units_in_tick;
467     vui->vui_time_scale                      = vps->vps_time_scale;
468     vui->vui_poc_proportional_to_timing_flag = vps->vps_poc_proportional_to_timing_flag;
469     vui->vui_num_ticks_poc_diff_one_minus1   = vps->vps_num_ticks_poc_diff_one_minus1;
470     vui->vui_hrd_parameters_present_flag     = 0;
471
472     vui->bitstream_restriction_flag    = 1;
473     vui->motion_vectors_over_pic_boundaries_flag = 1;
474     vui->restricted_ref_pic_lists_flag = 1;
475     vui->max_bytes_per_pic_denom       = 0;
476     vui->max_bits_per_min_cu_denom     = 0;
477     vui->log2_max_mv_length_horizontal = 15;
478     vui->log2_max_mv_length_vertical   = 15;
479
480
481     // PPS
482
483     pps->nal_unit_header = (H265RawNALUnitHeader) {
484         .nal_unit_type         = HEVC_NAL_PPS,
485         .nuh_layer_id          = 0,
486         .nuh_temporal_id_plus1 = 1,
487     };
488
489     pps->pps_pic_parameter_set_id = 0;
490     pps->pps_seq_parameter_set_id = sps->sps_seq_parameter_set_id;
491
492     pps->num_ref_idx_l0_default_active_minus1 = 0;
493     pps->num_ref_idx_l1_default_active_minus1 = 0;
494
495     pps->init_qp_minus26 = priv->fixed_qp_idr - 26;
496
497     pps->cu_qp_delta_enabled_flag = (ctx->va_rc_mode != VA_RC_CQP);
498     pps->diff_cu_qp_delta_depth   = 0;
499
500     pps->pps_loop_filter_across_slices_enabled_flag = 1;
501
502
503     // Fill VAAPI parameter buffers.
504
505     *vseq = (VAEncSequenceParameterBufferHEVC) {
506         .general_profile_idc = vps->profile_tier_level.general_profile_idc,
507         .general_level_idc   = vps->profile_tier_level.general_level_idc,
508         .general_tier_flag   = vps->profile_tier_level.general_tier_flag,
509
510         .intra_period     = avctx->gop_size,
511         .intra_idr_period = avctx->gop_size,
512         .ip_period        = ctx->b_per_p + 1,
513         .bits_per_second   = avctx->bit_rate,
514
515         .pic_width_in_luma_samples  = sps->pic_width_in_luma_samples,
516         .pic_height_in_luma_samples = sps->pic_height_in_luma_samples,
517
518         .seq_fields.bits = {
519             .chroma_format_idc             = sps->chroma_format_idc,
520             .separate_colour_plane_flag    = sps->separate_colour_plane_flag,
521             .bit_depth_luma_minus8         = sps->bit_depth_luma_minus8,
522             .bit_depth_chroma_minus8       = sps->bit_depth_chroma_minus8,
523             .scaling_list_enabled_flag     = sps->scaling_list_enabled_flag,
524             .strong_intra_smoothing_enabled_flag =
525                 sps->strong_intra_smoothing_enabled_flag,
526             .amp_enabled_flag              = sps->amp_enabled_flag,
527             .sample_adaptive_offset_enabled_flag =
528                 sps->sample_adaptive_offset_enabled_flag,
529             .pcm_enabled_flag              = sps->pcm_enabled_flag,
530             .pcm_loop_filter_disabled_flag = sps->pcm_loop_filter_disabled_flag,
531             .sps_temporal_mvp_enabled_flag = sps->sps_temporal_mvp_enabled_flag,
532         },
533
534         .log2_min_luma_coding_block_size_minus3 =
535             sps->log2_min_luma_coding_block_size_minus3,
536         .log2_diff_max_min_luma_coding_block_size =
537             sps->log2_diff_max_min_luma_coding_block_size,
538         .log2_min_transform_block_size_minus2 =
539             sps->log2_min_luma_transform_block_size_minus2,
540         .log2_diff_max_min_transform_block_size =
541             sps->log2_diff_max_min_luma_transform_block_size,
542         .max_transform_hierarchy_depth_inter =
543             sps->max_transform_hierarchy_depth_inter,
544         .max_transform_hierarchy_depth_intra =
545             sps->max_transform_hierarchy_depth_intra,
546
547         .pcm_sample_bit_depth_luma_minus1 =
548             sps->pcm_sample_bit_depth_luma_minus1,
549         .pcm_sample_bit_depth_chroma_minus1 =
550             sps->pcm_sample_bit_depth_chroma_minus1,
551         .log2_min_pcm_luma_coding_block_size_minus3 =
552             sps->log2_min_pcm_luma_coding_block_size_minus3,
553         .log2_max_pcm_luma_coding_block_size_minus3 =
554             sps->log2_min_pcm_luma_coding_block_size_minus3 +
555             sps->log2_diff_max_min_pcm_luma_coding_block_size,
556
557         .vui_parameters_present_flag = 0,
558     };
559
560     *vpic = (VAEncPictureParameterBufferHEVC) {
561         .decoded_curr_pic = {
562             .picture_id = VA_INVALID_ID,
563             .flags      = VA_PICTURE_HEVC_INVALID,
564         },
565
566         .coded_buf = VA_INVALID_ID,
567
568         .collocated_ref_pic_index = 0xff,
569
570         .last_picture = 0,
571
572         .pic_init_qp            = pps->init_qp_minus26 + 26,
573         .diff_cu_qp_delta_depth = pps->diff_cu_qp_delta_depth,
574         .pps_cb_qp_offset       = pps->pps_cb_qp_offset,
575         .pps_cr_qp_offset       = pps->pps_cr_qp_offset,
576
577         .num_tile_columns_minus1 = pps->num_tile_columns_minus1,
578         .num_tile_rows_minus1    = pps->num_tile_rows_minus1,
579
580         .log2_parallel_merge_level_minus2 = pps->log2_parallel_merge_level_minus2,
581         .ctu_max_bitsize_allowed          = 0,
582
583         .num_ref_idx_l0_default_active_minus1 =
584             pps->num_ref_idx_l0_default_active_minus1,
585         .num_ref_idx_l1_default_active_minus1 =
586             pps->num_ref_idx_l1_default_active_minus1,
587
588         .slice_pic_parameter_set_id = pps->pps_pic_parameter_set_id,
589
590         .pic_fields.bits = {
591             .sign_data_hiding_enabled_flag  = pps->sign_data_hiding_enabled_flag,
592             .constrained_intra_pred_flag    = pps->constrained_intra_pred_flag,
593             .transform_skip_enabled_flag    = pps->transform_skip_enabled_flag,
594             .cu_qp_delta_enabled_flag       = pps->cu_qp_delta_enabled_flag,
595             .weighted_pred_flag             = pps->weighted_pred_flag,
596             .weighted_bipred_flag           = pps->weighted_bipred_flag,
597             .transquant_bypass_enabled_flag = pps->transquant_bypass_enabled_flag,
598             .tiles_enabled_flag             = pps->tiles_enabled_flag,
599             .entropy_coding_sync_enabled_flag = pps->entropy_coding_sync_enabled_flag,
600             .loop_filter_across_tiles_enabled_flag =
601                 pps->loop_filter_across_tiles_enabled_flag,
602             .scaling_list_data_present_flag = (sps->sps_scaling_list_data_present_flag |
603                                                pps->pps_scaling_list_data_present_flag),
604             .screen_content_flag            = 0,
605             .enable_gpu_weighted_prediction = 0,
606             .no_output_of_prior_pics_flag   = 0,
607         },
608     };
609
610     return 0;
611 }
612
613 static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx,
614                                                  VAAPIEncodePicture *pic)
615 {
616     VAAPIEncodeContext               *ctx = avctx->priv_data;
617     VAAPIEncodeH265Context          *priv = ctx->priv_data;
618     VAAPIEncodeH265Options           *opt = ctx->codec_options;
619     VAEncPictureParameterBufferHEVC *vpic = pic->codec_picture_params;
620     int i;
621
622     if (pic->type == PICTURE_TYPE_IDR) {
623         av_assert0(pic->display_order == pic->encode_order);
624
625         priv->last_idr_frame = pic->display_order;
626
627         priv->slice_nal_unit = HEVC_NAL_IDR_W_RADL;
628         priv->slice_type     = HEVC_SLICE_I;
629         priv->pic_type       = 0;
630     } else {
631         av_assert0(pic->encode_order > priv->last_idr_frame);
632
633         if (pic->type == PICTURE_TYPE_I) {
634             priv->slice_nal_unit = HEVC_NAL_CRA_NUT;
635             priv->slice_type     = HEVC_SLICE_I;
636             priv->pic_type       = 0;
637         } else if (pic->type == PICTURE_TYPE_P) {
638             av_assert0(pic->refs[0]);
639             priv->slice_nal_unit = HEVC_NAL_TRAIL_R;
640             priv->slice_type     = HEVC_SLICE_P;
641             priv->pic_type       = 1;
642         } else {
643             av_assert0(pic->refs[0] && pic->refs[1]);
644             if (pic->refs[1]->type == PICTURE_TYPE_I)
645                 priv->slice_nal_unit = HEVC_NAL_RASL_N;
646             else
647                 priv->slice_nal_unit = HEVC_NAL_TRAIL_N;
648             priv->slice_type = HEVC_SLICE_B;
649             priv->pic_type   = 2;
650         }
651     }
652     priv->pic_order_cnt = pic->display_order - priv->last_idr_frame;
653
654     if (opt->aud) {
655         priv->aud_needed = 1;
656         priv->aud.nal_unit_header = (H265RawNALUnitHeader) {
657             .nal_unit_type         = HEVC_NAL_AUD,
658             .nuh_layer_id          = 0,
659             .nuh_temporal_id_plus1 = 1,
660         };
661         priv->aud.pic_type = priv->pic_type;
662     } else {
663         priv->aud_needed = 0;
664     }
665
666     priv->sei_needed = 0;
667
668     // Only look for the metadata on I/IDR frame on the output. We
669     // may force an IDR frame on the output where the medadata gets
670     // changed on the input frame.
671     if ((opt->sei & SEI_MASTERING_DISPLAY) &&
672         (pic->type == PICTURE_TYPE_I || pic->type == PICTURE_TYPE_IDR)) {
673         AVFrameSideData *sd =
674             av_frame_get_side_data(pic->input_image,
675                                    AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
676
677         if (sd) {
678             AVMasteringDisplayMetadata *mdm =
679                 (AVMasteringDisplayMetadata *)sd->data;
680
681             // SEI is needed when both the primaries and luminance are set
682             if (mdm->has_primaries && mdm->has_luminance) {
683                 const int mapping[3] = {1, 2, 0};
684                 const int chroma_den = 50000;
685                 const int luma_den   = 10000;
686
687                 for (i = 0; i < 3; i++) {
688                     const int j = mapping[i];
689                     priv->mastering_display.display_primaries_x[i] =
690                         FFMIN(lrint(chroma_den *
691                                     av_q2d(mdm->display_primaries[j][0])),
692                               chroma_den);
693                     priv->mastering_display.display_primaries_y[i] =
694                         FFMIN(lrint(chroma_den *
695                                     av_q2d(mdm->display_primaries[j][1])),
696                               chroma_den);
697                 }
698
699                 priv->mastering_display.white_point_x =
700                     FFMIN(lrint(chroma_den * av_q2d(mdm->white_point[0])),
701                           chroma_den);
702                 priv->mastering_display.white_point_y =
703                     FFMIN(lrint(chroma_den * av_q2d(mdm->white_point[1])),
704                           chroma_den);
705
706                 priv->mastering_display.max_display_mastering_luminance =
707                     lrint(luma_den * av_q2d(mdm->max_luminance));
708                 priv->mastering_display.min_display_mastering_luminance =
709                     FFMIN(lrint(luma_den * av_q2d(mdm->min_luminance)),
710                           priv->mastering_display.max_display_mastering_luminance);
711
712                 priv->sei_needed |= SEI_MASTERING_DISPLAY;
713             }
714         }
715     }
716
717     if ((opt->sei & SEI_CONTENT_LIGHT_LEVEL) &&
718         (pic->type == PICTURE_TYPE_I || pic->type == PICTURE_TYPE_IDR)) {
719         AVFrameSideData *sd =
720             av_frame_get_side_data(pic->input_image,
721                                    AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
722
723         if (sd) {
724             AVContentLightMetadata *clm =
725                 (AVContentLightMetadata *)sd->data;
726
727             priv->content_light_level.max_content_light_level =
728                 FFMIN(clm->MaxCLL, 65535);
729             priv->content_light_level.max_pic_average_light_level =
730                 FFMIN(clm->MaxFALL, 65535);
731
732             priv->sei_needed |= SEI_CONTENT_LIGHT_LEVEL;
733         }
734     }
735
736     vpic->decoded_curr_pic = (VAPictureHEVC) {
737         .picture_id    = pic->recon_surface,
738         .pic_order_cnt = priv->pic_order_cnt,
739         .flags         = 0,
740     };
741
742     for (i = 0; i < pic->nb_refs; i++) {
743         VAAPIEncodePicture *ref = pic->refs[i];
744         av_assert0(ref && ref->encode_order < pic->encode_order);
745
746         vpic->reference_frames[i] = (VAPictureHEVC) {
747             .picture_id    = ref->recon_surface,
748             .pic_order_cnt = ref->display_order - priv->last_idr_frame,
749             .flags = (ref->display_order < pic->display_order ?
750                       VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE : 0) |
751                      (ref->display_order > pic->display_order ?
752                       VA_PICTURE_HEVC_RPS_ST_CURR_AFTER  : 0),
753         };
754     }
755     for (; i < FF_ARRAY_ELEMS(vpic->reference_frames); i++) {
756         vpic->reference_frames[i] = (VAPictureHEVC) {
757             .picture_id = VA_INVALID_ID,
758             .flags      = VA_PICTURE_HEVC_INVALID,
759         };
760     }
761
762     vpic->coded_buf = pic->output_buffer;
763
764     vpic->nal_unit_type = priv->slice_nal_unit;
765
766     switch (pic->type) {
767     case PICTURE_TYPE_IDR:
768         vpic->pic_fields.bits.idr_pic_flag       = 1;
769         vpic->pic_fields.bits.coding_type        = 1;
770         vpic->pic_fields.bits.reference_pic_flag = 1;
771         break;
772     case PICTURE_TYPE_I:
773         vpic->pic_fields.bits.idr_pic_flag       = 0;
774         vpic->pic_fields.bits.coding_type        = 1;
775         vpic->pic_fields.bits.reference_pic_flag = 1;
776         break;
777     case PICTURE_TYPE_P:
778         vpic->pic_fields.bits.idr_pic_flag       = 0;
779         vpic->pic_fields.bits.coding_type        = 2;
780         vpic->pic_fields.bits.reference_pic_flag = 1;
781         break;
782     case PICTURE_TYPE_B:
783         vpic->pic_fields.bits.idr_pic_flag       = 0;
784         vpic->pic_fields.bits.coding_type        = 3;
785         vpic->pic_fields.bits.reference_pic_flag = 0;
786         break;
787     default:
788         av_assert0(0 && "invalid picture type");
789     }
790
791     pic->nb_slices = 1;
792
793     return 0;
794 }
795
796 static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
797                                                VAAPIEncodePicture *pic,
798                                                VAAPIEncodeSlice *slice)
799 {
800     VAAPIEncodeContext                *ctx = avctx->priv_data;
801     VAAPIEncodeH265Context           *priv = ctx->priv_data;
802     const H265RawSPS                  *sps = &priv->sps;
803     const H265RawPPS                  *pps = &priv->pps;
804     H265RawSliceHeader                 *sh = &priv->slice.header;
805     VAEncPictureParameterBufferHEVC  *vpic = pic->codec_picture_params;
806     VAEncSliceParameterBufferHEVC  *vslice = slice->codec_slice_params;
807     int i;
808
809     sh->nal_unit_header = (H265RawNALUnitHeader) {
810         .nal_unit_type         = priv->slice_nal_unit,
811         .nuh_layer_id          = 0,
812         .nuh_temporal_id_plus1 = 1,
813     };
814
815     sh->slice_pic_parameter_set_id      = pps->pps_pic_parameter_set_id;
816
817     // Currently we only support one slice per frame.
818     sh->first_slice_segment_in_pic_flag = 1;
819     sh->slice_segment_address           = 0;
820
821     sh->slice_type = priv->slice_type;
822
823     sh->slice_pic_order_cnt_lsb = priv->pic_order_cnt &
824         (1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4)) - 1;
825
826     if (pic->type != PICTURE_TYPE_IDR) {
827         H265RawSTRefPicSet *rps;
828         VAAPIEncodePicture *st;
829         int used;
830
831         sh->short_term_ref_pic_set_sps_flag = 0;
832
833         rps = &sh->short_term_ref_pic_set;
834         memset(rps, 0, sizeof(*rps));
835
836         for (st = ctx->pic_start; st; st = st->next) {
837             if (st->encode_order >= pic->encode_order) {
838                 // Not yet in DPB.
839                 continue;
840             }
841             used = 0;
842             for (i = 0; i < pic->nb_refs; i++) {
843                 if (pic->refs[i] == st)
844                     used = 1;
845             }
846             if (!used) {
847                 // Usually each picture always uses all of the others in the
848                 // DPB as references.  The one case we have to treat here is
849                 // a non-IDR IRAP picture, which may need to hold unused
850                 // references across itself to be used for the decoding of
851                 // following RASL pictures.  This looks for such an RASL
852                 // picture, and keeps the reference if there is one.
853                 VAAPIEncodePicture *rp;
854                 for (rp = ctx->pic_start; rp; rp = rp->next) {
855                     if (rp->encode_order < pic->encode_order)
856                         continue;
857                     if (rp->type != PICTURE_TYPE_B)
858                         continue;
859                     if (rp->refs[0] == st && rp->refs[1] == pic)
860                         break;
861                 }
862                 if (!rp)
863                     continue;
864             }
865             // This only works for one instance of each (delta_poc_sN_minus1
866             // is relative to the previous frame in the list, not relative to
867             // the current frame directly).
868             if (st->display_order < pic->display_order) {
869                 rps->delta_poc_s0_minus1[rps->num_negative_pics] =
870                     pic->display_order - st->display_order - 1;
871                 rps->used_by_curr_pic_s0_flag[rps->num_negative_pics] = used;
872                 ++rps->num_negative_pics;
873             } else {
874                 rps->delta_poc_s1_minus1[rps->num_positive_pics] =
875                     st->display_order - pic->display_order - 1;
876                 rps->used_by_curr_pic_s1_flag[rps->num_positive_pics] = used;
877                 ++rps->num_positive_pics;
878             }
879         }
880
881         sh->num_long_term_sps  = 0;
882         sh->num_long_term_pics = 0;
883
884         sh->slice_temporal_mvp_enabled_flag =
885             sps->sps_temporal_mvp_enabled_flag;
886         if (sh->slice_temporal_mvp_enabled_flag) {
887             sh->collocated_from_l0_flag = sh->slice_type == HEVC_SLICE_B;
888             sh->collocated_ref_idx      = 0;
889         }
890
891         sh->num_ref_idx_active_override_flag = 0;
892         sh->num_ref_idx_l0_active_minus1 = pps->num_ref_idx_l0_default_active_minus1;
893         sh->num_ref_idx_l1_active_minus1 = pps->num_ref_idx_l1_default_active_minus1;
894     }
895
896     sh->slice_sao_luma_flag = sh->slice_sao_chroma_flag =
897         sps->sample_adaptive_offset_enabled_flag;
898
899     if (pic->type == PICTURE_TYPE_B)
900         sh->slice_qp_delta = priv->fixed_qp_b - (pps->init_qp_minus26 + 26);
901     else if (pic->type == PICTURE_TYPE_P)
902         sh->slice_qp_delta = priv->fixed_qp_p - (pps->init_qp_minus26 + 26);
903     else
904         sh->slice_qp_delta = priv->fixed_qp_idr - (pps->init_qp_minus26 + 26);
905
906
907     *vslice = (VAEncSliceParameterBufferHEVC) {
908         .slice_segment_address = sh->slice_segment_address,
909         .num_ctu_in_slice      = priv->ctu_width * priv->ctu_height,
910
911         .slice_type                 = sh->slice_type,
912         .slice_pic_parameter_set_id = sh->slice_pic_parameter_set_id,
913
914         .num_ref_idx_l0_active_minus1 = sh->num_ref_idx_l0_active_minus1,
915         .num_ref_idx_l1_active_minus1 = sh->num_ref_idx_l1_active_minus1,
916
917         .luma_log2_weight_denom         = sh->luma_log2_weight_denom,
918         .delta_chroma_log2_weight_denom = sh->delta_chroma_log2_weight_denom,
919
920         .max_num_merge_cand = 5 - sh->five_minus_max_num_merge_cand,
921
922         .slice_qp_delta     = sh->slice_qp_delta,
923         .slice_cb_qp_offset = sh->slice_cb_qp_offset,
924         .slice_cr_qp_offset = sh->slice_cr_qp_offset,
925
926         .slice_beta_offset_div2 = sh->slice_beta_offset_div2,
927         .slice_tc_offset_div2   = sh->slice_tc_offset_div2,
928
929         .slice_fields.bits = {
930             .last_slice_of_pic_flag       = 1,
931             .dependent_slice_segment_flag = sh->dependent_slice_segment_flag,
932             .colour_plane_id              = sh->colour_plane_id,
933             .slice_temporal_mvp_enabled_flag =
934                 sh->slice_temporal_mvp_enabled_flag,
935             .slice_sao_luma_flag          = sh->slice_sao_luma_flag,
936             .slice_sao_chroma_flag        = sh->slice_sao_chroma_flag,
937             .num_ref_idx_active_override_flag =
938                 sh->num_ref_idx_active_override_flag,
939             .mvd_l1_zero_flag             = sh->mvd_l1_zero_flag,
940             .cabac_init_flag              = sh->cabac_init_flag,
941             .slice_deblocking_filter_disabled_flag =
942                 sh->slice_deblocking_filter_disabled_flag,
943             .slice_loop_filter_across_slices_enabled_flag =
944                 sh->slice_loop_filter_across_slices_enabled_flag,
945             .collocated_from_l0_flag      = sh->collocated_from_l0_flag,
946         },
947     };
948
949     for (i = 0; i < FF_ARRAY_ELEMS(vslice->ref_pic_list0); i++) {
950         vslice->ref_pic_list0[i].picture_id = VA_INVALID_ID;
951         vslice->ref_pic_list0[i].flags      = VA_PICTURE_HEVC_INVALID;
952         vslice->ref_pic_list1[i].picture_id = VA_INVALID_ID;
953         vslice->ref_pic_list1[i].flags      = VA_PICTURE_HEVC_INVALID;
954     }
955
956     av_assert0(pic->nb_refs <= 2);
957     if (pic->nb_refs >= 1) {
958         // Backward reference for P- or B-frame.
959         av_assert0(pic->type == PICTURE_TYPE_P ||
960                    pic->type == PICTURE_TYPE_B);
961         vslice->ref_pic_list0[0] = vpic->reference_frames[0];
962     }
963     if (pic->nb_refs >= 2) {
964         // Forward reference for B-frame.
965         av_assert0(pic->type == PICTURE_TYPE_B);
966         vslice->ref_pic_list1[0] = vpic->reference_frames[1];
967     }
968
969     return 0;
970 }
971
972 static av_cold int vaapi_encode_h265_configure(AVCodecContext *avctx)
973 {
974     VAAPIEncodeContext      *ctx = avctx->priv_data;
975     VAAPIEncodeH265Context *priv = ctx->priv_data;
976     VAAPIEncodeH265Options  *opt = ctx->codec_options;
977     int err;
978
979     err = ff_cbs_init(&priv->cbc, AV_CODEC_ID_HEVC, avctx);
980     if (err < 0)
981         return err;
982
983     priv->ctu_width     = FFALIGN(ctx->surface_width,  32) / 32;
984     priv->ctu_height    = FFALIGN(ctx->surface_height, 32) / 32;
985
986     av_log(avctx, AV_LOG_VERBOSE, "Input %ux%u -> Surface %ux%u -> CTU %ux%u.\n",
987            avctx->width, avctx->height, ctx->surface_width,
988            ctx->surface_height, priv->ctu_width, priv->ctu_height);
989
990     if (ctx->va_rc_mode == VA_RC_CQP) {
991         priv->fixed_qp_p = opt->qp;
992         if (avctx->i_quant_factor > 0.0)
993             priv->fixed_qp_idr = (int)((priv->fixed_qp_p * avctx->i_quant_factor +
994                                         avctx->i_quant_offset) + 0.5);
995         else
996             priv->fixed_qp_idr = priv->fixed_qp_p;
997         if (avctx->b_quant_factor > 0.0)
998             priv->fixed_qp_b = (int)((priv->fixed_qp_p * avctx->b_quant_factor +
999                                       avctx->b_quant_offset) + 0.5);
1000         else
1001             priv->fixed_qp_b = priv->fixed_qp_p;
1002
1003         av_log(avctx, AV_LOG_DEBUG, "Using fixed QP = "
1004                "%d / %d / %d for IDR- / P- / B-frames.\n",
1005                priv->fixed_qp_idr, priv->fixed_qp_p, priv->fixed_qp_b);
1006
1007     } else if (ctx->va_rc_mode == VA_RC_CBR ||
1008                ctx->va_rc_mode == VA_RC_VBR) {
1009         // These still need to be  set for pic_init_qp/slice_qp_delta.
1010         priv->fixed_qp_idr = 30;
1011         priv->fixed_qp_p   = 30;
1012         priv->fixed_qp_b   = 30;
1013
1014         av_log(avctx, AV_LOG_DEBUG, "Using %s-bitrate = %"PRId64" bps.\n",
1015                ctx->va_rc_mode == VA_RC_CBR ? "constant" : "variable",
1016                avctx->bit_rate);
1017
1018     } else {
1019         av_assert0(0 && "Invalid RC mode.");
1020     }
1021
1022     return 0;
1023 }
1024
1025 static const VAAPIEncodeType vaapi_encode_type_h265 = {
1026     .priv_data_size        = sizeof(VAAPIEncodeH265Context),
1027
1028     .configure             = &vaapi_encode_h265_configure,
1029
1030     .sequence_params_size  = sizeof(VAEncSequenceParameterBufferHEVC),
1031     .init_sequence_params  = &vaapi_encode_h265_init_sequence_params,
1032
1033     .picture_params_size   = sizeof(VAEncPictureParameterBufferHEVC),
1034     .init_picture_params   = &vaapi_encode_h265_init_picture_params,
1035
1036     .slice_params_size     = sizeof(VAEncSliceParameterBufferHEVC),
1037     .init_slice_params     = &vaapi_encode_h265_init_slice_params,
1038
1039     .sequence_header_type  = VAEncPackedHeaderSequence,
1040     .write_sequence_header = &vaapi_encode_h265_write_sequence_header,
1041
1042     .slice_header_type     = VAEncPackedHeaderHEVC_Slice,
1043     .write_slice_header    = &vaapi_encode_h265_write_slice_header,
1044
1045     .write_extra_header    = &vaapi_encode_h265_write_extra_header,
1046 };
1047
1048 static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx)
1049 {
1050     VAAPIEncodeContext     *ctx = avctx->priv_data;
1051     VAAPIEncodeH265Options *opt =
1052         (VAAPIEncodeH265Options*)ctx->codec_options_data;
1053
1054     ctx->codec = &vaapi_encode_type_h265;
1055
1056     if (avctx->profile == FF_PROFILE_UNKNOWN)
1057         avctx->profile = opt->profile;
1058     if (avctx->level == FF_LEVEL_UNKNOWN)
1059         avctx->level = opt->level;
1060
1061     switch (avctx->profile) {
1062     case FF_PROFILE_HEVC_MAIN:
1063     case FF_PROFILE_UNKNOWN:
1064         ctx->va_profile = VAProfileHEVCMain;
1065         ctx->va_rt_format = VA_RT_FORMAT_YUV420;
1066         break;
1067     case FF_PROFILE_HEVC_MAIN_10:
1068 #ifdef VA_RT_FORMAT_YUV420_10BPP
1069         ctx->va_profile = VAProfileHEVCMain10;
1070         ctx->va_rt_format = VA_RT_FORMAT_YUV420_10BPP;
1071         break;
1072 #else
1073         av_log(avctx, AV_LOG_ERROR, "10-bit encoding is not "
1074                "supported with this VAAPI version.\n");
1075         return AVERROR(ENOSYS);
1076 #endif
1077     default:
1078         av_log(avctx, AV_LOG_ERROR, "Unknown H.265 profile %d.\n",
1079                avctx->profile);
1080         return AVERROR(EINVAL);
1081     }
1082     ctx->va_entrypoint = VAEntrypointEncSlice;
1083
1084     if (avctx->bit_rate > 0) {
1085         if (avctx->rc_max_rate == avctx->bit_rate)
1086             ctx->va_rc_mode = VA_RC_CBR;
1087         else
1088             ctx->va_rc_mode = VA_RC_VBR;
1089     } else
1090         ctx->va_rc_mode = VA_RC_CQP;
1091
1092     ctx->va_packed_headers =
1093         VA_ENC_PACKED_HEADER_SEQUENCE | // VPS, SPS and PPS.
1094         VA_ENC_PACKED_HEADER_SLICE    | // Slice headers.
1095         VA_ENC_PACKED_HEADER_MISC;      // SEI
1096
1097     ctx->surface_width  = FFALIGN(avctx->width,  16);
1098     ctx->surface_height = FFALIGN(avctx->height, 16);
1099
1100     return ff_vaapi_encode_init(avctx);
1101 }
1102
1103 static av_cold int vaapi_encode_h265_close(AVCodecContext *avctx)
1104 {
1105     VAAPIEncodeContext *ctx = avctx->priv_data;
1106     VAAPIEncodeH265Context *priv = ctx->priv_data;
1107
1108     if (priv)
1109         ff_cbs_close(&priv->cbc);
1110
1111     return ff_vaapi_encode_close(avctx);
1112 }
1113
1114 #define OFFSET(x) (offsetof(VAAPIEncodeContext, codec_options_data) + \
1115                    offsetof(VAAPIEncodeH265Options, x))
1116 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
1117 static const AVOption vaapi_encode_h265_options[] = {
1118     { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
1119       OFFSET(qp), AV_OPT_TYPE_INT, { .i64 = 25 }, 0, 52, FLAGS },
1120
1121     { "aud", "Include AUD",
1122       OFFSET(aud), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS },
1123
1124     { "profile", "Set profile (general_profile_idc)",
1125       OFFSET(profile), AV_OPT_TYPE_INT,
1126       { .i64 = FF_PROFILE_HEVC_MAIN }, 0x00, 0xff, FLAGS, "profile" },
1127
1128 #define PROFILE(name, value)  name, NULL, 0, AV_OPT_TYPE_CONST, \
1129       { .i64 = value }, 0, 0, FLAGS, "profile"
1130     { PROFILE("main",               FF_PROFILE_HEVC_MAIN) },
1131     { PROFILE("main10",             FF_PROFILE_HEVC_MAIN_10) },
1132 #undef PROFILE
1133
1134     { "level", "Set level (general_level_idc)",
1135       OFFSET(level), AV_OPT_TYPE_INT,
1136       { .i64 = 153 }, 0x00, 0xff, FLAGS, "level" },
1137
1138 #define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
1139       { .i64 = value }, 0, 0, FLAGS, "level"
1140     { LEVEL("1",    30) },
1141     { LEVEL("2",    60) },
1142     { LEVEL("2.1",  63) },
1143     { LEVEL("3",    90) },
1144     { LEVEL("3.1",  93) },
1145     { LEVEL("4",   120) },
1146     { LEVEL("4.1", 123) },
1147     { LEVEL("5",   150) },
1148     { LEVEL("5.1", 153) },
1149     { LEVEL("5.2", 156) },
1150     { LEVEL("6",   180) },
1151     { LEVEL("6.1", 183) },
1152     { LEVEL("6.2", 186) },
1153 #undef LEVEL
1154
1155     { "sei", "Set SEI to include",
1156       OFFSET(sei), AV_OPT_TYPE_FLAGS,
1157       { .i64 = SEI_MASTERING_DISPLAY | SEI_CONTENT_LIGHT_LEVEL },
1158       0, INT_MAX, FLAGS, "sei" },
1159     { "hdr",
1160       "Include HDR metadata for mastering display colour volume "
1161       "and content light level information",
1162       0, AV_OPT_TYPE_CONST,
1163       { .i64 = SEI_MASTERING_DISPLAY | SEI_CONTENT_LIGHT_LEVEL },
1164       INT_MIN, INT_MAX, FLAGS, "sei" },
1165
1166     { NULL },
1167 };
1168
1169 static const AVCodecDefault vaapi_encode_h265_defaults[] = {
1170     { "b",              "0"   },
1171     { "bf",             "2"   },
1172     { "g",              "120" },
1173     { "i_qfactor",      "1"   },
1174     { "i_qoffset",      "0"   },
1175     { "b_qfactor",      "6/5" },
1176     { "b_qoffset",      "0"   },
1177     { NULL },
1178 };
1179
1180 static const AVClass vaapi_encode_h265_class = {
1181     .class_name = "h265_vaapi",
1182     .item_name  = av_default_item_name,
1183     .option     = vaapi_encode_h265_options,
1184     .version    = LIBAVUTIL_VERSION_INT,
1185 };
1186
1187 AVCodec ff_hevc_vaapi_encoder = {
1188     .name           = "hevc_vaapi",
1189     .long_name      = NULL_IF_CONFIG_SMALL("H.265/HEVC (VAAPI)"),
1190     .type           = AVMEDIA_TYPE_VIDEO,
1191     .id             = AV_CODEC_ID_HEVC,
1192     .priv_data_size = (sizeof(VAAPIEncodeContext) +
1193                        sizeof(VAAPIEncodeH265Options)),
1194     .init           = &vaapi_encode_h265_init,
1195     .encode2        = &ff_vaapi_encode2,
1196     .close          = &vaapi_encode_h265_close,
1197     .priv_class     = &vaapi_encode_h265_class,
1198     .capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,
1199     .defaults       = vaapi_encode_h265_defaults,
1200     .pix_fmts = (const enum AVPixelFormat[]) {
1201         AV_PIX_FMT_VAAPI,
1202         AV_PIX_FMT_NONE,
1203     },
1204     .wrapper_name   = "vaapi",
1205 };