vaapi_h264: Do not use deprecated header type
[libav.git] / libavcodec / vaapi_encode_h264.c
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
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 int aud;
93 int sei;
94 } VAAPIEncodeH264Options;
95
96
97 static int vaapi_encode_h264_write_access_unit(AVCodecContext *avctx,
98 char *data, size_t *data_len,
99 CodedBitstreamFragment *au)
100 {
101 VAAPIEncodeContext *ctx = avctx->priv_data;
102 VAAPIEncodeH264Context *priv = ctx->priv_data;
103 int err;
104
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;
109 }
110
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);
116 }
117
118 memcpy(data, au->data, au->data_size);
119 *data_len = 8 * au->data_size - au->data_bit_padding;
120
121 return 0;
122 }
123
124 static int vaapi_encode_h264_add_nal(AVCodecContext *avctx,
125 CodedBitstreamFragment *au,
126 void *nal_unit)
127 {
128 VAAPIEncodeContext *ctx = avctx->priv_data;
129 VAAPIEncodeH264Context *priv = ctx->priv_data;
130 H264RawNALUnitHeader *header = nal_unit;
131 int err;
132
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;
139 }
140
141 return 0;
142 }
143
144 static int vaapi_encode_h264_write_sequence_header(AVCodecContext *avctx,
145 char *data, size_t *data_len)
146 {
147 VAAPIEncodeContext *ctx = avctx->priv_data;
148 VAAPIEncodeH264Context *priv = ctx->priv_data;
149 CodedBitstreamFragment *au = &priv->current_access_unit;
150 int err;
151
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
159 err = vaapi_encode_h264_add_nal(avctx, au, &priv->sps);
160 if (err < 0)
161 goto fail;
162
163 err = vaapi_encode_h264_add_nal(avctx, au, &priv->pps);
164 if (err < 0)
165 goto fail;
166
167 err = vaapi_encode_h264_write_access_unit(avctx, data, data_len, au);
168 fail:
169 ff_cbs_fragment_uninit(&priv->cbc, au);
170 return err;
171 }
172
173 static int vaapi_encode_h264_write_slice_header(AVCodecContext *avctx,
174 VAAPIEncodePicture *pic,
175 VAAPIEncodeSlice *slice,
176 char *data, size_t *data_len)
177 {
178 VAAPIEncodeContext *ctx = avctx->priv_data;
179 VAAPIEncodeH264Context *priv = ctx->priv_data;
180 CodedBitstreamFragment *au = &priv->current_access_unit;
181 int err;
182
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
190 err = vaapi_encode_h264_add_nal(avctx, au, &priv->slice);
191 if (err < 0)
192 goto fail;
193
194 err = vaapi_encode_h264_write_access_unit(avctx, data, data_len, au);
195 fail:
196 ff_cbs_fragment_uninit(&priv->cbc, au);
197 return err;
198 }
199
200 static 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 {
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) {
212 if (priv->aud_needed) {
213 vaapi_encode_h264_add_nal(avctx, au, &priv->aud);
214 priv->aud_needed = 0;
215 }
216
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 }
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 }
241
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;
249
250 err = vaapi_encode_h264_write_access_unit(avctx, data, data_len, au);
251 if (err < 0)
252 goto fail;
253
254 ff_cbs_fragment_uninit(&priv->cbc, au);
255
256 *type = VAEncPackedHeaderRawData;
257 return 0;
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
271 } else {
272 return AVERROR_EOF;
273 }
274
275 fail:
276 ff_cbs_fragment_uninit(&priv->cbc, au);
277 return err;
278 }
279
280 static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)
281 {
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;
289
290 memset(&priv->current_access_unit, 0,
291 sizeof(priv->current_access_unit));
292
293 memset(sps, 0, sizeof(*sps));
294 memset(pps, 0, sizeof(*pps));
295
296 sps->nal_unit_header.nal_ref_idc = 3;
297 sps->nal_unit_header.nal_unit_type = H264_NAL_SPS;
298
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);
304
305 sps->level_idc = avctx->level;
306
307 sps->seq_parameter_set_id = 0;
308 sps->chroma_format_idc = 1;
309
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;
324
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;
356 }
357 }
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
375 if (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED ||
376 avctx->color_trc != AVCOL_TRC_UNSPECIFIED ||
377 avctx->colorspace != AVCOL_SPC_UNSPECIFIED) {
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;
382 }
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 }
390
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 }
397
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 }
408
409 if (opt->sei & SEI_TIMING) {
410 H264RawHRD *hrd = &sps->vui.nal_hrd_parameters;
411
412 sps->vui.nal_hrd_parameters_present_flag = 1;
413
414 hrd->cpb_cnt_minus1 = 0;
415
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;
422
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;
427
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;
431
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;
436
437 priv->buffering_period.seq_parameter_set_id = sps->seq_parameter_set_id;
438
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;
447 }
448
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;
455
456 pps->nal_unit_header.nal_ref_idc = 3;
457 pps->nal_unit_header.nal_unit_type = H264_NAL_PPS;
458
459 pps->pic_parameter_set_id = 0;
460 pps->seq_parameter_set_id = 0;
461
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);
466
467 pps->num_ref_idx_l0_default_active_minus1 = 0;
468 pps->num_ref_idx_l1_default_active_minus1 = 0;
469
470 pps->pic_init_qp_minus26 = priv->fixed_qp_idr - 26;
471
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 };
531
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 };
564
565 return 0;
566 }
567
568 static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx,
569 VAAPIEncodePicture *pic)
570 {
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;
576 int i;
577
578 memset(&priv->current_access_unit, 0,
579 sizeof(priv->current_access_unit));
580
581 if (pic->type == PICTURE_TYPE_IDR) {
582 av_assert0(pic->display_order == pic->encode_order);
583 priv->frame_num = 0;
584 priv->next_frame_num = 1;
585 priv->cpb_delay = 0;
586 priv->last_idr_frame = pic->display_order;
587 ++priv->idr_pic_count;
588
589 priv->slice_type = 7;
590 priv->primary_pic_type = 0;
591 } else {
592 priv->frame_num = priv->next_frame_num;
593
594 if (pic->type != PICTURE_TYPE_B) {
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);
598 }
599 ++priv->cpb_delay;
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 }
611 }
612 priv->pic_order_cnt = pic->display_order - priv->last_idr_frame;
613 priv->dpb_delay = pic->display_order - pic->encode_order + 1;
614
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
623 if (opt->sei & SEI_IDENTIFIER && pic->encode_order == 0)
624 priv->sei_needed = 1;
625 #if !HAVE_VAAPI_1
626 if (ctx->va_rc_mode == VA_RC_CBR)
627 priv->sei_cbr_workaround_needed = 1;
628 #endif
629
630 if (opt->sei & SEI_TIMING) {
631 memset(&priv->pic_timing, 0, sizeof(priv->pic_timing));
632
633 priv->pic_timing.cpb_removal_delay = 2 * priv->cpb_delay;
634 priv->pic_timing.dpb_output_delay = 2 * priv->dpb_delay;
635
636 priv->sei_needed = 1;
637 }
638
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
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 };
654
655 for (i = 0; i < pic->nb_refs; i++) {
656 VAAPIEncodePicture *ref = pic->refs[i];
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
661 av_assert0(ref && ref->encode_order < pic->encode_order);
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 };
669 }
670 for (; i < FF_ARRAY_ELEMS(vpic->ReferenceFrames); i++) {
671 vpic->ReferenceFrames[i] = (VAPictureH264) {
672 .picture_id = VA_INVALID_ID,
673 .flags = VA_PICTURE_H264_INVALID,
674 };
675 }
676
677 vpic->coded_buf = pic->output_buffer;
678
679 vpic->frame_num = priv->frame_num;
680
681 vpic->pic_fields.bits.idr_pic_flag = (pic->type == PICTURE_TYPE_IDR);
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
689 static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx,
690 VAAPIEncodePicture *pic,
691 VAAPIEncodeSlice *slice)
692 {
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;
700 int i;
701
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;
715
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);
728 else
729 sh->slice_qp_delta = priv->fixed_qp_idr - (pps->pic_init_qp_minus26 + 26);
730
731
732 vslice->macroblock_address = sh->first_mb_in_slice;
733 vslice->num_macroblocks = priv->mb_width * priv->mb_height;
734
735 vslice->macroblock_info = VA_INVALID_ID;
736
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;
742
743 vslice->direct_spatial_mv_pred_flag = sh->direct_spatial_mv_pred_flag;
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) {
754 // Backward reference for P- or B-frame.
755 av_assert0(pic->type == PICTURE_TYPE_P ||
756 pic->type == PICTURE_TYPE_B);
757 vslice->RefPicList0[0] = vpic->ReferenceFrames[0];
758 }
759 if (pic->nb_refs >= 2) {
760 // Forward reference for B-frame.
761 av_assert0(pic->type == PICTURE_TYPE_B);
762 vslice->RefPicList1[0] = vpic->ReferenceFrames[1];
763 }
764
765 vslice->slice_qp_delta = sh->slice_qp_delta;
766
767 return 0;
768 }
769
770 static av_cold int vaapi_encode_h264_configure(AVCodecContext *avctx)
771 {
772 VAAPIEncodeContext *ctx = avctx->priv_data;
773 VAAPIEncodeH264Context *priv = ctx->priv_data;
774 VAAPIEncodeH264Options *opt = ctx->codec_options;
775 int err;
776
777 err = ff_cbs_init(&priv->cbc, AV_CODEC_ID_H264, avctx);
778 if (err < 0)
779 return err;
780
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
797 opt->sei &= ~SEI_TIMING;
798
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
803 } else if (ctx->va_rc_mode == VA_RC_CBR ||
804 ctx->va_rc_mode == VA_RC_VBR) {
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
810 av_log(avctx, AV_LOG_DEBUG, "Using %s-bitrate = %d bps.\n",
811 ctx->va_rc_mode == VA_RC_CBR ? "constant" : "variable",
812 avctx->bit_rate);
813
814 } else {
815 av_assert0(0 && "Invalid RC mode.");
816 }
817
818 if (avctx->compression_level == FF_COMPRESSION_DEFAULT)
819 avctx->compression_level = opt->quality;
820
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
849 return 0;
850 }
851
852 static 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
875 static av_cold int vaapi_encode_h264_init(AVCodecContext *avctx)
876 {
877 VAAPIEncodeContext *ctx = avctx->priv_data;
878 VAAPIEncodeH264Options *opt =
879 (VAAPIEncodeH264Options*)ctx->codec_options_data;
880
881 ctx->codec = &vaapi_encode_type_h264;
882
883 switch (avctx->profile) {
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;
888 case FF_PROFILE_H264_CONSTRAINED_BASELINE:
889 ctx->va_profile = VAProfileH264ConstrainedBaseline;
890 break;
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 }
921 if (opt->low_power) {
922 #if VA_CHECK_VERSION(0, 39, 2)
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 }
932
933 // Only 8-bit encode is supported.
934 ctx->va_rt_format = VA_RT_FORMAT_YUV420;
935
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
942 ctx->va_rc_mode = VA_RC_CQP;
943
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.
948
949 ctx->surface_width = FFALIGN(avctx->width, 16);
950 ctx->surface_height = FFALIGN(avctx->height, 16);
951
952 return ff_vaapi_encode_init(avctx);
953 }
954
955 static 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
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)
971 static const AVOption vaapi_encode_h264_options[] = {
972 { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
973 OFFSET(qp), AV_OPT_TYPE_INT, { .i64 = 20 }, 0, 52, FLAGS },
974 { "quality", "Set encode quality (trades off against speed, higher is faster)",
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 },
979
980 { "aud", "Include AUD",
981 OFFSET(aud), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS },
982
983 { "sei", "Set SEI to include",
984 OFFSET(sei), AV_OPT_TYPE_FLAGS,
985 { .i64 = SEI_IDENTIFIER | SEI_TIMING | SEI_RECOVERY_POINT },
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" },
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" },
996 { NULL },
997 };
998
999 static const AVCodecDefault vaapi_encode_h264_defaults[] = {
1000 { "profile", "100" },
1001 { "level", "51" },
1002 { "b", "0" },
1003 { "bf", "2" },
1004 { "g", "120" },
1005 { "i_qfactor", "1.0" },
1006 { "i_qoffset", "0.0" },
1007 { "b_qfactor", "1.2" },
1008 { "b_qoffset", "0.0" },
1009 { "qmin", "0" },
1010 { NULL },
1011 };
1012
1013 static const AVClass vaapi_encode_h264_class = {
1014 .class_name = "h264_vaapi",
1015 .item_name = av_default_item_name,
1016 .option = vaapi_encode_h264_options,
1017 .version = LIBAVUTIL_VERSION_INT,
1018 };
1019
1020 AVCodec 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,
1025 .priv_data_size = (sizeof(VAAPIEncodeContext) +
1026 sizeof(VAAPIEncodeH264Options)),
1027 .init = &vaapi_encode_h264_init,
1028 .encode2 = &ff_vaapi_encode2,
1029 .close = &vaapi_encode_h264_close,
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 };