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