]> git.sesse.net Git - ffmpeg/blob - libavcodec/vaapi_encode_h264.c
avcodec/mpeg4videoenc: Use 64 bit for times in mpeg4_encode_gop_header()
[ffmpeg] / libavcodec / vaapi_encode_h264.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_h264.h>
23
24 #include "libavutil/avassert.h"
25 #include "libavutil/common.h"
26 #include "libavutil/internal.h"
27 #include "libavutil/opt.h"
28
29 #include "avcodec.h"
30 #include "cbs.h"
31 #include "cbs_h264.h"
32 #include "h264.h"
33 #include "h264_sei.h"
34 #include "internal.h"
35 #include "vaapi_encode.h"
36
37 enum {
38     SEI_TIMING         = 0x01,
39     SEI_IDENTIFIER     = 0x02,
40     SEI_RECOVERY_POINT = 0x04,
41 };
42
43 // Random (version 4) ISO 11578 UUID.
44 static const uint8_t vaapi_encode_h264_sei_identifier_uuid[16] = {
45     0x59, 0x94, 0x8b, 0x28, 0x11, 0xec, 0x45, 0xaf,
46     0x96, 0x75, 0x19, 0xd4, 0x1f, 0xea, 0xa9, 0x4d,
47 };
48
49 typedef struct VAAPIEncodeH264Context {
50     int mb_width;
51     int mb_height;
52
53     int fixed_qp_idr;
54     int fixed_qp_p;
55     int fixed_qp_b;
56
57     H264RawAUD aud;
58     H264RawSPS sps;
59     H264RawPPS pps;
60     H264RawSEI sei;
61     H264RawSlice slice;
62
63     H264RawSEIBufferingPeriod buffering_period;
64     H264RawSEIPicTiming pic_timing;
65     H264RawSEIRecoveryPoint recovery_point;
66     H264RawSEIUserDataUnregistered identifier;
67     char *identifier_string;
68
69     int frame_num;
70     int pic_order_cnt;
71     int next_frame_num;
72     int64_t last_idr_frame;
73     int64_t idr_pic_count;
74
75     int primary_pic_type;
76     int slice_type;
77
78     int cpb_delay;
79     int dpb_delay;
80
81     CodedBitstreamContext *cbc;
82     CodedBitstreamFragment current_access_unit;
83     int aud_needed;
84     int sei_needed;
85     int sei_cbr_workaround_needed;
86 } VAAPIEncodeH264Context;
87
88 typedef struct VAAPIEncodeH264Options {
89     int qp;
90     int quality;
91     int low_power;
92     // Entropy encoder type.
93     int coder;
94     int aud;
95     int sei;
96     int profile;
97     int level;
98 } VAAPIEncodeH264Options;
99
100
101 static int vaapi_encode_h264_write_access_unit(AVCodecContext *avctx,
102                                                char *data, size_t *data_len,
103                                                CodedBitstreamFragment *au)
104 {
105     VAAPIEncodeContext      *ctx = avctx->priv_data;
106     VAAPIEncodeH264Context *priv = ctx->priv_data;
107     int err;
108
109     err = ff_cbs_write_fragment_data(priv->cbc, au);
110     if (err < 0) {
111         av_log(avctx, AV_LOG_ERROR, "Failed to write packed header.\n");
112         return err;
113     }
114
115     if (*data_len < 8 * au->data_size - au->data_bit_padding) {
116         av_log(avctx, AV_LOG_ERROR, "Access unit too large: "
117                "%zu < %zu.\n", *data_len,
118                8 * au->data_size - au->data_bit_padding);
119         return AVERROR(ENOSPC);
120     }
121
122     memcpy(data, au->data, au->data_size);
123     *data_len = 8 * au->data_size - au->data_bit_padding;
124
125     return 0;
126 }
127
128 static int vaapi_encode_h264_add_nal(AVCodecContext *avctx,
129                                      CodedBitstreamFragment *au,
130                                      void *nal_unit)
131 {
132     VAAPIEncodeContext      *ctx = avctx->priv_data;
133     VAAPIEncodeH264Context *priv = ctx->priv_data;
134     H264RawNALUnitHeader *header = nal_unit;
135     int err;
136
137     err = ff_cbs_insert_unit_content(priv->cbc, au, -1,
138                                      header->nal_unit_type, nal_unit, NULL);
139     if (err < 0) {
140         av_log(avctx, AV_LOG_ERROR, "Failed to add NAL unit: "
141                "type = %d.\n", header->nal_unit_type);
142         return err;
143     }
144
145     return 0;
146 }
147
148 static int vaapi_encode_h264_write_sequence_header(AVCodecContext *avctx,
149                                                    char *data, size_t *data_len)
150 {
151     VAAPIEncodeContext      *ctx = avctx->priv_data;
152     VAAPIEncodeH264Context *priv = ctx->priv_data;
153     CodedBitstreamFragment   *au = &priv->current_access_unit;
154     int err;
155
156     if (priv->aud_needed) {
157         err = vaapi_encode_h264_add_nal(avctx, au, &priv->aud);
158         if (err < 0)
159             goto fail;
160         priv->aud_needed = 0;
161     }
162
163     err = vaapi_encode_h264_add_nal(avctx, au, &priv->sps);
164     if (err < 0)
165         goto fail;
166
167     err = vaapi_encode_h264_add_nal(avctx, au, &priv->pps);
168     if (err < 0)
169         goto fail;
170
171     err = vaapi_encode_h264_write_access_unit(avctx, data, data_len, au);
172 fail:
173     ff_cbs_fragment_uninit(priv->cbc, au);
174     return err;
175 }
176
177 static int vaapi_encode_h264_write_slice_header(AVCodecContext *avctx,
178                                                 VAAPIEncodePicture *pic,
179                                                 VAAPIEncodeSlice *slice,
180                                                 char *data, size_t *data_len)
181 {
182     VAAPIEncodeContext      *ctx = avctx->priv_data;
183     VAAPIEncodeH264Context *priv = ctx->priv_data;
184     CodedBitstreamFragment   *au = &priv->current_access_unit;
185     int err;
186
187     if (priv->aud_needed) {
188         err = vaapi_encode_h264_add_nal(avctx, au, &priv->aud);
189         if (err < 0)
190             goto fail;
191         priv->aud_needed = 0;
192     }
193
194     err = vaapi_encode_h264_add_nal(avctx, au, &priv->slice);
195     if (err < 0)
196         goto fail;
197
198     err = vaapi_encode_h264_write_access_unit(avctx, data, data_len, au);
199 fail:
200     ff_cbs_fragment_uninit(priv->cbc, au);
201     return err;
202 }
203
204 static int vaapi_encode_h264_write_extra_header(AVCodecContext *avctx,
205                                                 VAAPIEncodePicture *pic,
206                                                 int index, int *type,
207                                                 char *data, size_t *data_len)
208 {
209     VAAPIEncodeContext      *ctx = avctx->priv_data;
210     VAAPIEncodeH264Context *priv = ctx->priv_data;
211     CodedBitstreamFragment   *au = &priv->current_access_unit;
212     int err, i;
213
214     if (priv->sei_needed) {
215         if (priv->aud_needed) {
216             err = vaapi_encode_h264_add_nal(avctx, au, &priv->aud);
217             if (err < 0)
218                 goto fail;
219             priv->aud_needed = 0;
220         }
221
222         memset(&priv->sei, 0, sizeof(priv->sei));
223         priv->sei.nal_unit_header.nal_unit_type = H264_NAL_SEI;
224
225         i = 0;
226         if (priv->sei_needed & SEI_IDENTIFIER) {
227             priv->sei.payload[i].payload_type = H264_SEI_TYPE_USER_DATA_UNREGISTERED;
228             priv->sei.payload[i].payload.user_data_unregistered = priv->identifier;
229             ++i;
230         }
231         if (priv->sei_needed & SEI_TIMING) {
232             if (pic->type == PICTURE_TYPE_IDR) {
233                 priv->sei.payload[i].payload_type = H264_SEI_TYPE_BUFFERING_PERIOD;
234                 priv->sei.payload[i].payload.buffering_period = priv->buffering_period;
235                 ++i;
236             }
237             priv->sei.payload[i].payload_type = H264_SEI_TYPE_PIC_TIMING;
238             priv->sei.payload[i].payload.pic_timing = priv->pic_timing;
239             ++i;
240         }
241         if (priv->sei_needed & SEI_RECOVERY_POINT) {
242             priv->sei.payload[i].payload_type = H264_SEI_TYPE_RECOVERY_POINT;
243             priv->sei.payload[i].payload.recovery_point = priv->recovery_point;
244             ++i;
245         }
246
247         priv->sei.payload_count = i;
248         av_assert0(priv->sei.payload_count > 0);
249
250         err = vaapi_encode_h264_add_nal(avctx, au, &priv->sei);
251         if (err < 0)
252             goto fail;
253         priv->sei_needed = 0;
254
255         err = vaapi_encode_h264_write_access_unit(avctx, data, data_len, au);
256         if (err < 0)
257             goto fail;
258
259         ff_cbs_fragment_uninit(priv->cbc, au);
260
261         *type = VAEncPackedHeaderRawData;
262         return 0;
263
264 #if !CONFIG_VAAPI_1
265     } else if (priv->sei_cbr_workaround_needed) {
266         // Insert a zero-length header using the old SEI type.  This is
267         // required to avoid triggering broken behaviour on Intel platforms
268         // in CBR mode where an invalid SEI message is generated by the
269         // driver and inserted into the stream.
270         *data_len = 0;
271         *type = VAEncPackedHeaderH264_SEI;
272         priv->sei_cbr_workaround_needed = 0;
273         return 0;
274 #endif
275
276     } else {
277         return AVERROR_EOF;
278     }
279
280 fail:
281     ff_cbs_fragment_uninit(priv->cbc, au);
282     return err;
283 }
284
285 static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)
286 {
287     VAAPIEncodeContext                *ctx = avctx->priv_data;
288     VAAPIEncodeH264Context           *priv = ctx->priv_data;
289     VAAPIEncodeH264Options            *opt = ctx->codec_options;
290     H264RawSPS                        *sps = &priv->sps;
291     H264RawPPS                        *pps = &priv->pps;
292     VAEncSequenceParameterBufferH264 *vseq = ctx->codec_sequence_params;
293     VAEncPictureParameterBufferH264  *vpic = ctx->codec_picture_params;
294
295     memset(&priv->current_access_unit, 0,
296            sizeof(priv->current_access_unit));
297
298     memset(sps, 0, sizeof(*sps));
299     memset(pps, 0, sizeof(*pps));
300
301     sps->nal_unit_header.nal_ref_idc   = 3;
302     sps->nal_unit_header.nal_unit_type = H264_NAL_SPS;
303
304     sps->profile_idc = avctx->profile & 0xff;
305     sps->constraint_set1_flag =
306         !!(avctx->profile & FF_PROFILE_H264_CONSTRAINED);
307     sps->constraint_set3_flag =
308         !!(avctx->profile & FF_PROFILE_H264_INTRA);
309
310     sps->level_idc = avctx->level;
311
312     sps->seq_parameter_set_id = 0;
313     sps->chroma_format_idc    = 1;
314
315     sps->log2_max_frame_num_minus4 = 4;
316     sps->pic_order_cnt_type        = 0;
317     sps->log2_max_pic_order_cnt_lsb_minus4 =
318         av_clip(av_log2(ctx->b_per_p + 1) - 2, 0, 12);
319
320     sps->max_num_ref_frames =
321         (avctx->profile & FF_PROFILE_H264_INTRA) ? 0 :
322         1 + (ctx->b_per_p > 0);
323
324     sps->pic_width_in_mbs_minus1        = priv->mb_width  - 1;
325     sps->pic_height_in_map_units_minus1 = priv->mb_height - 1;
326
327     sps->frame_mbs_only_flag = 1;
328     sps->direct_8x8_inference_flag = 1;
329
330     if (avctx->width  != 16 * priv->mb_width ||
331         avctx->height != 16 * priv->mb_height) {
332         sps->frame_cropping_flag = 1;
333
334         sps->frame_crop_left_offset   = 0;
335         sps->frame_crop_right_offset  =
336             (16 * priv->mb_width - avctx->width) / 2;
337         sps->frame_crop_top_offset    = 0;
338         sps->frame_crop_bottom_offset =
339             (16 * priv->mb_height - avctx->height) / 2;
340     } else {
341         sps->frame_cropping_flag = 0;
342     }
343
344     sps->vui_parameters_present_flag = 1;
345
346     if (avctx->sample_aspect_ratio.num != 0 &&
347         avctx->sample_aspect_ratio.den != 0) {
348         static const AVRational sar_idc[] = {
349             {   0,  0 },
350             {   1,  1 }, {  12, 11 }, {  10, 11 }, {  16, 11 },
351             {  40, 33 }, {  24, 11 }, {  20, 11 }, {  32, 11 },
352             {  80, 33 }, {  18, 11 }, {  15, 11 }, {  64, 33 },
353             { 160, 99 }, {   4,  3 }, {   3,  2 }, {   2,  1 },
354         };
355         int i;
356         for (i = 0; i < FF_ARRAY_ELEMS(sar_idc); i++) {
357             if (avctx->sample_aspect_ratio.num == sar_idc[i].num &&
358                 avctx->sample_aspect_ratio.den == sar_idc[i].den) {
359                 sps->vui.aspect_ratio_idc = i;
360                 break;
361             }
362         }
363         if (i >= FF_ARRAY_ELEMS(sar_idc)) {
364             sps->vui.aspect_ratio_idc = 255;
365             sps->vui.sar_width  = avctx->sample_aspect_ratio.num;
366             sps->vui.sar_height = avctx->sample_aspect_ratio.den;
367         }
368         sps->vui.aspect_ratio_info_present_flag = 1;
369     }
370
371     if (avctx->color_range     != AVCOL_RANGE_UNSPECIFIED ||
372         avctx->color_primaries != AVCOL_PRI_UNSPECIFIED ||
373         avctx->color_trc       != AVCOL_TRC_UNSPECIFIED ||
374         avctx->colorspace      != AVCOL_SPC_UNSPECIFIED) {
375         sps->vui.video_signal_type_present_flag = 1;
376         sps->vui.video_format      = 5; // Unspecified.
377         sps->vui.video_full_range_flag =
378             avctx->color_range == AVCOL_RANGE_JPEG;
379
380         if (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED ||
381             avctx->color_trc       != AVCOL_TRC_UNSPECIFIED ||
382             avctx->colorspace      != AVCOL_SPC_UNSPECIFIED) {
383             sps->vui.colour_description_present_flag = 1;
384             sps->vui.colour_primaries         = avctx->color_primaries;
385             sps->vui.transfer_characteristics = avctx->color_trc;
386             sps->vui.matrix_coefficients      = avctx->colorspace;
387         }
388     } else {
389         sps->vui.video_format             = 5;
390         sps->vui.video_full_range_flag    = 0;
391         sps->vui.colour_primaries         = avctx->color_primaries;
392         sps->vui.transfer_characteristics = avctx->color_trc;
393         sps->vui.matrix_coefficients      = avctx->colorspace;
394     }
395
396     if (avctx->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED) {
397         sps->vui.chroma_loc_info_present_flag = 1;
398         sps->vui.chroma_sample_loc_type_top_field    =
399         sps->vui.chroma_sample_loc_type_bottom_field =
400             avctx->chroma_sample_location - 1;
401     }
402
403     sps->vui.timing_info_present_flag = 1;
404     if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
405         sps->vui.num_units_in_tick = avctx->framerate.den;
406         sps->vui.time_scale        = 2 * avctx->framerate.num;
407         sps->vui.fixed_frame_rate_flag = 1;
408     } else {
409         sps->vui.num_units_in_tick = avctx->time_base.num;
410         sps->vui.time_scale        = 2 * avctx->time_base.den;
411         sps->vui.fixed_frame_rate_flag = 0;
412     }
413
414     if (opt->sei & SEI_TIMING) {
415         H264RawHRD *hrd = &sps->vui.nal_hrd_parameters;
416
417         sps->vui.nal_hrd_parameters_present_flag = 1;
418
419         hrd->cpb_cnt_minus1 = 0;
420
421         // Try to scale these to a sensible range so that the
422         // golomb encode of the value is not overlong.
423         hrd->bit_rate_scale =
424             av_clip_uintp2(av_log2(avctx->bit_rate) - 15 - 6, 4);
425         hrd->bit_rate_value_minus1[0] =
426             (avctx->bit_rate >> hrd->bit_rate_scale + 6) - 1;
427
428         hrd->cpb_size_scale =
429             av_clip_uintp2(av_log2(ctx->hrd_params.hrd.buffer_size) - 15 - 4, 4);
430         hrd->cpb_size_value_minus1[0] =
431             (ctx->hrd_params.hrd.buffer_size >> hrd->cpb_size_scale + 4) - 1;
432
433         // CBR mode as defined for the HRD cannot be achieved without filler
434         // data, so this flag cannot be set even with VAAPI CBR modes.
435         hrd->cbr_flag[0] = 0;
436
437         hrd->initial_cpb_removal_delay_length_minus1 = 23;
438         hrd->cpb_removal_delay_length_minus1         = 23;
439         hrd->dpb_output_delay_length_minus1          = 7;
440         hrd->time_offset_length                      = 0;
441
442         priv->buffering_period.seq_parameter_set_id = sps->seq_parameter_set_id;
443
444         // This calculation can easily overflow 32 bits.
445         priv->buffering_period.nal.initial_cpb_removal_delay[0] = 90000 *
446             (uint64_t)ctx->hrd_params.hrd.initial_buffer_fullness /
447             ctx->hrd_params.hrd.buffer_size;
448         priv->buffering_period.nal.initial_cpb_removal_delay_offset[0] = 0;
449     } else {
450         sps->vui.nal_hrd_parameters_present_flag = 0;
451         sps->vui.low_delay_hrd_flag = 1 - sps->vui.fixed_frame_rate_flag;
452     }
453
454     sps->vui.bitstream_restriction_flag    = 1;
455     sps->vui.motion_vectors_over_pic_boundaries_flag = 1;
456     sps->vui.log2_max_mv_length_horizontal = 16;
457     sps->vui.log2_max_mv_length_vertical   = 16;
458     sps->vui.max_num_reorder_frames        = (ctx->b_per_p > 0);
459     sps->vui.max_dec_frame_buffering       = sps->max_num_ref_frames;
460
461     pps->nal_unit_header.nal_ref_idc = 3;
462     pps->nal_unit_header.nal_unit_type = H264_NAL_PPS;
463
464     pps->pic_parameter_set_id = 0;
465     pps->seq_parameter_set_id = 0;
466
467     pps->entropy_coding_mode_flag =
468         !(sps->profile_idc == FF_PROFILE_H264_BASELINE ||
469           sps->profile_idc == FF_PROFILE_H264_EXTENDED ||
470           sps->profile_idc == FF_PROFILE_H264_CAVLC_444);
471     if (!opt->coder && pps->entropy_coding_mode_flag)
472         pps->entropy_coding_mode_flag = 0;
473
474     pps->num_ref_idx_l0_default_active_minus1 = 0;
475     pps->num_ref_idx_l1_default_active_minus1 = 0;
476
477     pps->pic_init_qp_minus26 = priv->fixed_qp_idr - 26;
478
479     if (sps->profile_idc == FF_PROFILE_H264_BASELINE ||
480         sps->profile_idc == FF_PROFILE_H264_EXTENDED ||
481         sps->profile_idc == FF_PROFILE_H264_MAIN) {
482         pps->more_rbsp_data = 0;
483     } else {
484         pps->more_rbsp_data = 1;
485
486         pps->transform_8x8_mode_flag = 1;
487     }
488
489     *vseq = (VAEncSequenceParameterBufferH264) {
490         .seq_parameter_set_id = sps->seq_parameter_set_id,
491         .level_idc        = sps->level_idc,
492         .intra_period     = avctx->gop_size,
493         .intra_idr_period = avctx->gop_size,
494         .ip_period        = ctx->b_per_p + 1,
495
496         .bits_per_second       = avctx->bit_rate,
497         .max_num_ref_frames    = sps->max_num_ref_frames,
498         .picture_width_in_mbs  = sps->pic_width_in_mbs_minus1 + 1,
499         .picture_height_in_mbs = sps->pic_height_in_map_units_minus1 + 1,
500
501         .seq_fields.bits = {
502             .chroma_format_idc                 = sps->chroma_format_idc,
503             .frame_mbs_only_flag               = sps->frame_mbs_only_flag,
504             .mb_adaptive_frame_field_flag      = sps->mb_adaptive_frame_field_flag,
505             .seq_scaling_matrix_present_flag   = sps->seq_scaling_matrix_present_flag,
506             .direct_8x8_inference_flag         = sps->direct_8x8_inference_flag,
507             .log2_max_frame_num_minus4         = sps->log2_max_frame_num_minus4,
508             .pic_order_cnt_type                = sps->pic_order_cnt_type,
509             .log2_max_pic_order_cnt_lsb_minus4 = sps->log2_max_pic_order_cnt_lsb_minus4,
510             .delta_pic_order_always_zero_flag  = sps->delta_pic_order_always_zero_flag,
511         },
512
513         .bit_depth_luma_minus8   = sps->bit_depth_luma_minus8,
514         .bit_depth_chroma_minus8 = sps->bit_depth_chroma_minus8,
515
516         .frame_cropping_flag      = sps->frame_cropping_flag,
517         .frame_crop_left_offset   = sps->frame_crop_left_offset,
518         .frame_crop_right_offset  = sps->frame_crop_right_offset,
519         .frame_crop_top_offset    = sps->frame_crop_top_offset,
520         .frame_crop_bottom_offset = sps->frame_crop_bottom_offset,
521
522         .vui_parameters_present_flag = sps->vui_parameters_present_flag,
523
524         .vui_fields.bits = {
525             .aspect_ratio_info_present_flag = sps->vui.aspect_ratio_info_present_flag,
526             .timing_info_present_flag       = sps->vui.timing_info_present_flag,
527             .bitstream_restriction_flag     = sps->vui.bitstream_restriction_flag,
528             .log2_max_mv_length_horizontal  = sps->vui.log2_max_mv_length_horizontal,
529             .log2_max_mv_length_vertical    = sps->vui.log2_max_mv_length_vertical,
530         },
531
532         .aspect_ratio_idc  = sps->vui.aspect_ratio_idc,
533         .sar_width         = sps->vui.sar_width,
534         .sar_height        = sps->vui.sar_height,
535         .num_units_in_tick = sps->vui.num_units_in_tick,
536         .time_scale        = sps->vui.time_scale,
537     };
538
539     *vpic = (VAEncPictureParameterBufferH264) {
540         .CurrPic = {
541             .picture_id = VA_INVALID_ID,
542             .flags      = VA_PICTURE_H264_INVALID,
543         },
544
545         .coded_buf = VA_INVALID_ID,
546
547         .pic_parameter_set_id = pps->pic_parameter_set_id,
548         .seq_parameter_set_id = pps->seq_parameter_set_id,
549
550         .pic_init_qp                  = pps->pic_init_qp_minus26 + 26,
551         .num_ref_idx_l0_active_minus1 = pps->num_ref_idx_l0_default_active_minus1,
552         .num_ref_idx_l1_active_minus1 = pps->num_ref_idx_l1_default_active_minus1,
553
554         .chroma_qp_index_offset        = pps->chroma_qp_index_offset,
555         .second_chroma_qp_index_offset = pps->second_chroma_qp_index_offset,
556
557         .pic_fields.bits = {
558             .entropy_coding_mode_flag        = pps->entropy_coding_mode_flag,
559             .weighted_pred_flag              = pps->weighted_pred_flag,
560             .weighted_bipred_idc             = pps->weighted_bipred_idc,
561             .constrained_intra_pred_flag     = pps->constrained_intra_pred_flag,
562             .transform_8x8_mode_flag         = pps->transform_8x8_mode_flag,
563             .deblocking_filter_control_present_flag =
564                 pps->deblocking_filter_control_present_flag,
565             .redundant_pic_cnt_present_flag  = pps->redundant_pic_cnt_present_flag,
566             .pic_order_present_flag          =
567                 pps->bottom_field_pic_order_in_frame_present_flag,
568             .pic_scaling_matrix_present_flag = pps->pic_scaling_matrix_present_flag,
569         },
570     };
571
572     return 0;
573 }
574
575 static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx,
576                                                  VAAPIEncodePicture *pic)
577 {
578     VAAPIEncodeContext               *ctx = avctx->priv_data;
579     VAAPIEncodeH264Context          *priv = ctx->priv_data;
580     VAAPIEncodeH264Options           *opt = ctx->codec_options;
581     H264RawSPS                       *sps = &priv->sps;
582     VAEncPictureParameterBufferH264 *vpic = pic->codec_picture_params;
583     int i;
584
585     memset(&priv->current_access_unit, 0,
586            sizeof(priv->current_access_unit));
587
588     if (pic->type == PICTURE_TYPE_IDR) {
589         av_assert0(pic->display_order == pic->encode_order);
590         priv->frame_num      = 0;
591         priv->next_frame_num = 1;
592         priv->cpb_delay      = 0;
593         priv->last_idr_frame = pic->display_order;
594         ++priv->idr_pic_count;
595
596         priv->slice_type       = 7;
597         priv->primary_pic_type = 0;
598     } else {
599         priv->frame_num      = priv->next_frame_num;
600
601         if (pic->type != PICTURE_TYPE_B) {
602             // Reference picture, so frame_num advances.
603             priv->next_frame_num = (priv->frame_num + 1) &
604                 ((1 << (4 + sps->log2_max_frame_num_minus4)) - 1);
605         }
606         ++priv->cpb_delay;
607
608         if (pic->type == PICTURE_TYPE_I) {
609             priv->slice_type       = 7;
610             priv->primary_pic_type = 0;
611         } else if (pic->type == PICTURE_TYPE_P) {
612             priv->slice_type       = 5;
613             priv->primary_pic_type = 1;
614         } else {
615             priv->slice_type       = 6;
616             priv->primary_pic_type = 2;
617         }
618     }
619     priv->pic_order_cnt = pic->display_order - priv->last_idr_frame;
620     priv->dpb_delay     = pic->display_order - pic->encode_order + 1;
621
622     if (opt->aud) {
623         priv->aud_needed = 1;
624         priv->aud.nal_unit_header.nal_unit_type = H264_NAL_AUD;
625         priv->aud.primary_pic_type = priv->primary_pic_type;
626     } else {
627         priv->aud_needed = 0;
628     }
629
630     priv->sei_needed = 0;
631
632     if (opt->sei & SEI_IDENTIFIER && pic->encode_order == 0)
633         priv->sei_needed |= SEI_IDENTIFIER;
634 #if !CONFIG_VAAPI_1
635     if (ctx->va_rc_mode == VA_RC_CBR)
636         priv->sei_cbr_workaround_needed = 1;
637 #endif
638
639     if (opt->sei & SEI_TIMING) {
640         memset(&priv->pic_timing, 0, sizeof(priv->pic_timing));
641
642         priv->pic_timing.cpb_removal_delay = 2 * priv->cpb_delay;
643         priv->pic_timing.dpb_output_delay  = 2 * priv->dpb_delay;
644
645         priv->sei_needed |= SEI_TIMING;
646     }
647
648     if (opt->sei & SEI_RECOVERY_POINT && pic->type == PICTURE_TYPE_I) {
649         priv->recovery_point.recovery_frame_cnt = 0;
650         priv->recovery_point.exact_match_flag   = 1;
651         priv->recovery_point.broken_link_flag   = ctx->b_per_p > 0;
652
653         priv->sei_needed |= SEI_RECOVERY_POINT;
654     }
655
656     vpic->CurrPic = (VAPictureH264) {
657         .picture_id          = pic->recon_surface,
658         .frame_idx           = priv->frame_num,
659         .flags               = 0,
660         .TopFieldOrderCnt    = priv->pic_order_cnt,
661         .BottomFieldOrderCnt = priv->pic_order_cnt,
662     };
663
664     for (i = 0; i < pic->nb_refs; i++) {
665         VAAPIEncodePicture *ref = pic->refs[i];
666         unsigned int frame_num = (ref->encode_order - priv->last_idr_frame) &
667             ((1 << (4 + sps->log2_max_frame_num_minus4)) - 1);
668         unsigned int pic_order_cnt = ref->display_order - priv->last_idr_frame;
669
670         av_assert0(ref && ref->encode_order < pic->encode_order);
671         vpic->ReferenceFrames[i] = (VAPictureH264) {
672             .picture_id          = ref->recon_surface,
673             .frame_idx           = frame_num,
674             .flags               = VA_PICTURE_H264_SHORT_TERM_REFERENCE,
675             .TopFieldOrderCnt    = pic_order_cnt,
676             .BottomFieldOrderCnt = pic_order_cnt,
677         };
678     }
679     for (; i < FF_ARRAY_ELEMS(vpic->ReferenceFrames); i++) {
680         vpic->ReferenceFrames[i] = (VAPictureH264) {
681             .picture_id = VA_INVALID_ID,
682             .flags      = VA_PICTURE_H264_INVALID,
683         };
684     }
685
686     vpic->coded_buf = pic->output_buffer;
687
688     vpic->frame_num = priv->frame_num;
689
690     vpic->pic_fields.bits.idr_pic_flag       = (pic->type == PICTURE_TYPE_IDR);
691     vpic->pic_fields.bits.reference_pic_flag = (pic->type != PICTURE_TYPE_B);
692
693     pic->nb_slices = 1;
694
695     return 0;
696 }
697
698 static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx,
699                                                VAAPIEncodePicture *pic,
700                                                VAAPIEncodeSlice *slice)
701 {
702     VAAPIEncodeContext               *ctx = avctx->priv_data;
703     VAAPIEncodeH264Context          *priv = ctx->priv_data;
704     H264RawSPS                       *sps = &priv->sps;
705     H264RawPPS                       *pps = &priv->pps;
706     H264RawSliceHeader                *sh = &priv->slice.header;
707     VAEncPictureParameterBufferH264 *vpic = pic->codec_picture_params;
708     VAEncSliceParameterBufferH264 *vslice = slice->codec_slice_params;
709     int i;
710
711     if (pic->type == PICTURE_TYPE_IDR) {
712         sh->nal_unit_header.nal_unit_type = H264_NAL_IDR_SLICE;
713         sh->nal_unit_header.nal_ref_idc   = 3;
714     } else {
715         sh->nal_unit_header.nal_unit_type = H264_NAL_SLICE;
716         sh->nal_unit_header.nal_ref_idc   = pic->type != PICTURE_TYPE_B;
717     }
718
719     // Only one slice per frame.
720     sh->first_mb_in_slice = 0;
721     sh->slice_type        = priv->slice_type;
722
723     sh->pic_parameter_set_id = pps->pic_parameter_set_id;
724
725     sh->frame_num  = priv->frame_num;
726     sh->idr_pic_id = priv->idr_pic_count;
727
728     sh->pic_order_cnt_lsb = priv->pic_order_cnt &
729         ((1 << (4 + sps->log2_max_pic_order_cnt_lsb_minus4)) - 1);
730
731     sh->direct_spatial_mv_pred_flag = 1;
732
733     if (pic->type == PICTURE_TYPE_B)
734         sh->slice_qp_delta = priv->fixed_qp_b - (pps->pic_init_qp_minus26 + 26);
735     else if (pic->type == PICTURE_TYPE_P)
736         sh->slice_qp_delta = priv->fixed_qp_p - (pps->pic_init_qp_minus26 + 26);
737     else
738         sh->slice_qp_delta = priv->fixed_qp_idr - (pps->pic_init_qp_minus26 + 26);
739
740
741     vslice->macroblock_address = sh->first_mb_in_slice;
742     vslice->num_macroblocks    = priv->mb_width * priv->mb_height;
743
744     vslice->macroblock_info = VA_INVALID_ID;
745
746     vslice->slice_type           = sh->slice_type % 5;
747     vslice->pic_parameter_set_id = sh->pic_parameter_set_id;
748     vslice->idr_pic_id           = sh->idr_pic_id;
749
750     vslice->pic_order_cnt_lsb = sh->pic_order_cnt_lsb;
751
752     vslice->direct_spatial_mv_pred_flag = sh->direct_spatial_mv_pred_flag;
753
754     for (i = 0; i < FF_ARRAY_ELEMS(vslice->RefPicList0); i++) {
755         vslice->RefPicList0[i].picture_id = VA_INVALID_ID;
756         vslice->RefPicList0[i].flags      = VA_PICTURE_H264_INVALID;
757         vslice->RefPicList1[i].picture_id = VA_INVALID_ID;
758         vslice->RefPicList1[i].flags      = VA_PICTURE_H264_INVALID;
759     }
760
761     av_assert0(pic->nb_refs <= 2);
762     if (pic->nb_refs >= 1) {
763         // Backward reference for P- or B-frame.
764         av_assert0(pic->type == PICTURE_TYPE_P ||
765                    pic->type == PICTURE_TYPE_B);
766         vslice->RefPicList0[0] = vpic->ReferenceFrames[0];
767     }
768     if (pic->nb_refs >= 2) {
769         // Forward reference for B-frame.
770         av_assert0(pic->type == PICTURE_TYPE_B);
771         vslice->RefPicList1[0] = vpic->ReferenceFrames[1];
772     }
773
774     vslice->slice_qp_delta = sh->slice_qp_delta;
775
776     return 0;
777 }
778
779 static av_cold int vaapi_encode_h264_configure(AVCodecContext *avctx)
780 {
781     VAAPIEncodeContext      *ctx = avctx->priv_data;
782     VAAPIEncodeH264Context *priv = ctx->priv_data;
783     VAAPIEncodeH264Options  *opt = ctx->codec_options;
784     int err;
785
786     err = ff_cbs_init(&priv->cbc, AV_CODEC_ID_H264, avctx);
787     if (err < 0)
788         return err;
789
790     priv->mb_width  = FFALIGN(avctx->width,  16) / 16;
791     priv->mb_height = FFALIGN(avctx->height, 16) / 16;
792
793     if (ctx->va_rc_mode == VA_RC_CQP) {
794         priv->fixed_qp_p = opt->qp;
795         if (avctx->i_quant_factor > 0.0)
796             priv->fixed_qp_idr = (int)((priv->fixed_qp_p * avctx->i_quant_factor +
797                                         avctx->i_quant_offset) + 0.5);
798         else
799             priv->fixed_qp_idr = priv->fixed_qp_p;
800         if (avctx->b_quant_factor > 0.0)
801             priv->fixed_qp_b = (int)((priv->fixed_qp_p * avctx->b_quant_factor +
802                                       avctx->b_quant_offset) + 0.5);
803         else
804             priv->fixed_qp_b = priv->fixed_qp_p;
805
806         opt->sei &= ~SEI_TIMING;
807
808         av_log(avctx, AV_LOG_DEBUG, "Using fixed QP = "
809                "%d / %d / %d for IDR- / P- / B-frames.\n",
810                priv->fixed_qp_idr, priv->fixed_qp_p, priv->fixed_qp_b);
811
812     } else if (ctx->va_rc_mode == VA_RC_CBR ||
813                ctx->va_rc_mode == VA_RC_VBR) {
814         // These still need to be  set for pic_init_qp/slice_qp_delta.
815         priv->fixed_qp_idr = 26;
816         priv->fixed_qp_p   = 26;
817         priv->fixed_qp_b   = 26;
818
819         av_log(avctx, AV_LOG_DEBUG, "Using %s-bitrate = %"PRId64" bps.\n",
820                ctx->va_rc_mode == VA_RC_CBR ? "constant" : "variable",
821                avctx->bit_rate);
822
823     } else {
824         av_assert0(0 && "Invalid RC mode.");
825     }
826
827     if (avctx->compression_level == FF_COMPRESSION_DEFAULT)
828         avctx->compression_level = opt->quality;
829
830     if (opt->sei & SEI_IDENTIFIER) {
831         const char *lavc  = LIBAVCODEC_IDENT;
832         const char *vaapi = VA_VERSION_S;
833         const char *driver;
834         int len;
835
836         memcpy(priv->identifier.uuid_iso_iec_11578,
837                vaapi_encode_h264_sei_identifier_uuid,
838                sizeof(priv->identifier.uuid_iso_iec_11578));
839
840         driver = vaQueryVendorString(ctx->hwctx->display);
841         if (!driver)
842             driver = "unknown driver";
843
844         len = snprintf(NULL, 0, "%s / VAAPI %s / %s", lavc, vaapi, driver);
845         if (len >= 0) {
846             priv->identifier_string = av_malloc(len + 1);
847             if (!priv->identifier_string)
848                 return AVERROR(ENOMEM);
849
850             snprintf(priv->identifier_string, len + 1,
851                      "%s / VAAPI %s / %s", lavc, vaapi, driver);
852
853             priv->identifier.data = priv->identifier_string;
854             priv->identifier.data_length = len + 1;
855         }
856     }
857
858     return 0;
859 }
860
861 static const VAAPIEncodeType vaapi_encode_type_h264 = {
862     .priv_data_size        = sizeof(VAAPIEncodeH264Context),
863
864     .configure             = &vaapi_encode_h264_configure,
865
866     .sequence_params_size  = sizeof(VAEncSequenceParameterBufferH264),
867     .init_sequence_params  = &vaapi_encode_h264_init_sequence_params,
868
869     .picture_params_size   = sizeof(VAEncPictureParameterBufferH264),
870     .init_picture_params   = &vaapi_encode_h264_init_picture_params,
871
872     .slice_params_size     = sizeof(VAEncSliceParameterBufferH264),
873     .init_slice_params     = &vaapi_encode_h264_init_slice_params,
874
875     .sequence_header_type  = VAEncPackedHeaderSequence,
876     .write_sequence_header = &vaapi_encode_h264_write_sequence_header,
877
878     .slice_header_type     = VAEncPackedHeaderH264_Slice,
879     .write_slice_header    = &vaapi_encode_h264_write_slice_header,
880
881     .write_extra_header    = &vaapi_encode_h264_write_extra_header,
882 };
883
884 static av_cold int vaapi_encode_h264_init(AVCodecContext *avctx)
885 {
886     VAAPIEncodeContext     *ctx = avctx->priv_data;
887     VAAPIEncodeH264Options *opt =
888         (VAAPIEncodeH264Options*)ctx->codec_options_data;
889
890     ctx->codec = &vaapi_encode_type_h264;
891
892     if (avctx->profile == FF_PROFILE_UNKNOWN)
893         avctx->profile = opt->profile;
894     if (avctx->level == FF_LEVEL_UNKNOWN)
895         avctx->level = opt->level;
896
897     switch (avctx->profile) {
898     case FF_PROFILE_H264_BASELINE:
899         av_log(avctx, AV_LOG_WARNING, "H.264 baseline profile is not "
900                "supported, using constrained baseline profile instead.\n");
901         avctx->profile = FF_PROFILE_H264_CONSTRAINED_BASELINE;
902     case FF_PROFILE_H264_CONSTRAINED_BASELINE:
903         ctx->va_profile = VAProfileH264ConstrainedBaseline;
904         if (avctx->max_b_frames != 0) {
905             avctx->max_b_frames = 0;
906             av_log(avctx, AV_LOG_WARNING, "H.264 constrained baseline profile "
907                    "doesn't support encoding with B frames, disabling them.\n");
908         }
909         break;
910     case FF_PROFILE_H264_MAIN:
911         ctx->va_profile = VAProfileH264Main;
912         break;
913     case FF_PROFILE_H264_EXTENDED:
914         av_log(avctx, AV_LOG_ERROR, "H.264 extended profile "
915                "is not supported.\n");
916         return AVERROR_PATCHWELCOME;
917     case FF_PROFILE_UNKNOWN:
918     case FF_PROFILE_H264_HIGH:
919         ctx->va_profile = VAProfileH264High;
920         break;
921     case FF_PROFILE_H264_HIGH_10:
922     case FF_PROFILE_H264_HIGH_10_INTRA:
923         av_log(avctx, AV_LOG_ERROR, "H.264 10-bit profiles "
924                "are not supported.\n");
925         return AVERROR_PATCHWELCOME;
926     case FF_PROFILE_H264_HIGH_422:
927     case FF_PROFILE_H264_HIGH_422_INTRA:
928     case FF_PROFILE_H264_HIGH_444:
929     case FF_PROFILE_H264_HIGH_444_PREDICTIVE:
930     case FF_PROFILE_H264_HIGH_444_INTRA:
931     case FF_PROFILE_H264_CAVLC_444:
932         av_log(avctx, AV_LOG_ERROR, "H.264 non-4:2:0 profiles "
933                "are not supported.\n");
934         return AVERROR_PATCHWELCOME;
935     default:
936         av_log(avctx, AV_LOG_ERROR, "Unknown H.264 profile %d.\n",
937                avctx->profile);
938         return AVERROR(EINVAL);
939     }
940     if (opt->low_power) {
941 #if VA_CHECK_VERSION(0, 39, 2)
942         ctx->va_entrypoint = VAEntrypointEncSliceLP;
943 #else
944         av_log(avctx, AV_LOG_ERROR, "Low-power encoding is not "
945                "supported with this VAAPI version.\n");
946         return AVERROR(EINVAL);
947 #endif
948     } else {
949         ctx->va_entrypoint = VAEntrypointEncSlice;
950     }
951
952     // Only 8-bit encode is supported.
953     ctx->va_rt_format = VA_RT_FORMAT_YUV420;
954
955     if (avctx->bit_rate > 0) {
956         if (avctx->rc_max_rate == avctx->bit_rate)
957             ctx->va_rc_mode = VA_RC_CBR;
958         else
959             ctx->va_rc_mode = VA_RC_VBR;
960     } else
961         ctx->va_rc_mode = VA_RC_CQP;
962
963     ctx->va_packed_headers =
964         VA_ENC_PACKED_HEADER_SEQUENCE | // SPS and PPS.
965         VA_ENC_PACKED_HEADER_SLICE    | // Slice headers.
966         VA_ENC_PACKED_HEADER_MISC;      // SEI.
967
968     ctx->surface_width  = FFALIGN(avctx->width,  16);
969     ctx->surface_height = FFALIGN(avctx->height, 16);
970
971     return ff_vaapi_encode_init(avctx);
972 }
973
974 static av_cold int vaapi_encode_h264_close(AVCodecContext *avctx)
975 {
976     VAAPIEncodeContext *ctx = avctx->priv_data;
977     VAAPIEncodeH264Context *priv = ctx->priv_data;
978
979     if (priv) {
980         ff_cbs_close(&priv->cbc);
981         av_freep(&priv->identifier_string);
982     }
983
984     return ff_vaapi_encode_close(avctx);
985 }
986
987 #define OFFSET(x) (offsetof(VAAPIEncodeContext, codec_options_data) + \
988                    offsetof(VAAPIEncodeH264Options, x))
989 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
990 static const AVOption vaapi_encode_h264_options[] = {
991     { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
992       OFFSET(qp), AV_OPT_TYPE_INT, { .i64 = 20 }, 0, 52, FLAGS },
993     { "quality", "Set encode quality (trades off against speed, higher is faster)",
994       OFFSET(quality), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8, FLAGS },
995     { "low_power", "Use low-power encoding mode (experimental: only supported "
996       "on some platforms, does not support all features)",
997       OFFSET(low_power), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS },
998     { "coder", "Entropy coder type",
999       OFFSET(coder), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, FLAGS, "coder" },
1000         { "cavlc", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS, "coder" },
1001         { "cabac", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, FLAGS, "coder" },
1002         { "vlc",   NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS, "coder" },
1003         { "ac",    NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, FLAGS, "coder" },
1004
1005     { "aud", "Include AUD",
1006       OFFSET(aud), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS },
1007
1008     { "sei", "Set SEI to include",
1009       OFFSET(sei), AV_OPT_TYPE_FLAGS,
1010       { .i64 = SEI_IDENTIFIER | SEI_TIMING | SEI_RECOVERY_POINT },
1011       0, INT_MAX, FLAGS, "sei" },
1012     { "identifier", "Include encoder version identifier",
1013       0, AV_OPT_TYPE_CONST, { .i64 = SEI_IDENTIFIER },
1014       INT_MIN, INT_MAX, FLAGS, "sei" },
1015     { "timing", "Include timing parameters (buffering_period and pic_timing)",
1016       0, AV_OPT_TYPE_CONST, { .i64 = SEI_TIMING },
1017       INT_MIN, INT_MAX, FLAGS, "sei" },
1018     { "recovery_point", "Include recovery points where appropriate",
1019       0, AV_OPT_TYPE_CONST, { .i64 = SEI_RECOVERY_POINT },
1020       INT_MIN, INT_MAX, FLAGS, "sei" },
1021
1022     { "profile", "Set profile (profile_idc and constraint_set*_flag)",
1023       OFFSET(profile), AV_OPT_TYPE_INT,
1024       { .i64 = FF_PROFILE_H264_HIGH }, 0x0000, 0xffff, FLAGS, "profile" },
1025
1026 #define PROFILE(name, value)  name, NULL, 0, AV_OPT_TYPE_CONST, \
1027       { .i64 = value }, 0, 0, FLAGS, "profile"
1028     { PROFILE("constrained_baseline", FF_PROFILE_H264_CONSTRAINED_BASELINE) },
1029     { PROFILE("main",                 FF_PROFILE_H264_MAIN) },
1030     { PROFILE("high",                 FF_PROFILE_H264_HIGH) },
1031 #undef PROFILE
1032
1033     { "level", "Set level (level_idc)",
1034       OFFSET(level), AV_OPT_TYPE_INT,
1035       { .i64 = 51 }, 0x00, 0xff, FLAGS, "level" },
1036
1037 #define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
1038       { .i64 = value }, 0, 0, FLAGS, "level"
1039     { LEVEL("1",   10) },
1040     { LEVEL("1.1", 11) },
1041     { LEVEL("1.2", 12) },
1042     { LEVEL("1.3", 13) },
1043     { LEVEL("2",   20) },
1044     { LEVEL("2.1", 21) },
1045     { LEVEL("2.2", 22) },
1046     { LEVEL("3",   30) },
1047     { LEVEL("3.1", 31) },
1048     { LEVEL("3.2", 32) },
1049     { LEVEL("4",   40) },
1050     { LEVEL("4.1", 41) },
1051     { LEVEL("4.2", 42) },
1052     { LEVEL("5",   50) },
1053     { LEVEL("5.1", 51) },
1054     { LEVEL("5.2", 52) },
1055     { LEVEL("6",   60) },
1056     { LEVEL("6.1", 61) },
1057     { LEVEL("6.2", 62) },
1058 #undef LEVEL
1059
1060     { NULL },
1061 };
1062
1063 static const AVCodecDefault vaapi_encode_h264_defaults[] = {
1064     { "b",              "0"   },
1065     { "bf",             "2"   },
1066     { "g",              "120" },
1067     { "i_qfactor",      "1"   },
1068     { "i_qoffset",      "0"   },
1069     { "b_qfactor",      "6/5" },
1070     { "b_qoffset",      "0"   },
1071     { "qmin",           "0"   },
1072     { NULL },
1073 };
1074
1075 static const AVClass vaapi_encode_h264_class = {
1076     .class_name = "h264_vaapi",
1077     .item_name  = av_default_item_name,
1078     .option     = vaapi_encode_h264_options,
1079     .version    = LIBAVUTIL_VERSION_INT,
1080 };
1081
1082 AVCodec ff_h264_vaapi_encoder = {
1083     .name           = "h264_vaapi",
1084     .long_name      = NULL_IF_CONFIG_SMALL("H.264/AVC (VAAPI)"),
1085     .type           = AVMEDIA_TYPE_VIDEO,
1086     .id             = AV_CODEC_ID_H264,
1087     .priv_data_size = (sizeof(VAAPIEncodeContext) +
1088                        sizeof(VAAPIEncodeH264Options)),
1089     .init           = &vaapi_encode_h264_init,
1090     .encode2        = &ff_vaapi_encode2,
1091     .close          = &vaapi_encode_h264_close,
1092     .priv_class     = &vaapi_encode_h264_class,
1093     .capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,
1094     .defaults       = vaapi_encode_h264_defaults,
1095     .pix_fmts = (const enum AVPixelFormat[]) {
1096         AV_PIX_FMT_VAAPI,
1097         AV_PIX_FMT_NONE,
1098     },
1099     .wrapper_name   = "vaapi",
1100 };