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