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