1/* 2 * This file is part of FFmpeg. 3 * 4 * FFmpeg is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * FFmpeg is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with FFmpeg; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19#include <string.h> 20 21#include <va/va.h> 22#include <va/va_enc_h264.h> 23 24#include "libavutil/avassert.h" 25#include "libavutil/common.h" 26#include "libavutil/internal.h" 27#include "libavutil/opt.h" 28 29#include "avcodec.h" 30#include "cbs.h" 31#include "cbs_h264.h" 32#include "codec_internal.h" 33#include "h264.h" 34#include "h264_levels.h" 35#include "h264_sei.h" 36#include "vaapi_encode.h" 37#include "version.h" 38 39enum { 40 SEI_TIMING = 0x01, 41 SEI_IDENTIFIER = 0x02, 42 SEI_RECOVERY_POINT = 0x04, 43}; 44 45// Random (version 4) ISO 11578 UUID. 46static const uint8_t vaapi_encode_h264_sei_identifier_uuid[16] = { 47 0x59, 0x94, 0x8b, 0x28, 0x11, 0xec, 0x45, 0xaf, 48 0x96, 0x75, 0x19, 0xd4, 0x1f, 0xea, 0xa9, 0x4d, 49}; 50 51typedef struct VAAPIEncodeH264Picture { 52 int frame_num; 53 int pic_order_cnt; 54 55 int64_t last_idr_frame; 56 uint16_t idr_pic_id; 57 58 int primary_pic_type; 59 int slice_type; 60 61 int cpb_delay; 62 int dpb_delay; 63} VAAPIEncodeH264Picture; 64 65typedef struct VAAPIEncodeH264Context { 66 VAAPIEncodeContext common; 67 68 // User options. 69 int qp; 70 int quality; 71 int coder; 72 int aud; 73 int sei; 74 int profile; 75 int level; 76 77 // Derived settings. 78 int mb_width; 79 int mb_height; 80 81 int fixed_qp_idr; 82 int fixed_qp_p; 83 int fixed_qp_b; 84 85 int dpb_frames; 86 87 // Writer structures. 88 CodedBitstreamContext *cbc; 89 CodedBitstreamFragment current_access_unit; 90 91 H264RawAUD raw_aud; 92 H264RawSPS raw_sps; 93 H264RawPPS raw_pps; 94 H264RawSlice raw_slice; 95 96 H264RawSEIBufferingPeriod sei_buffering_period; 97 H264RawSEIPicTiming sei_pic_timing; 98 H264RawSEIRecoveryPoint sei_recovery_point; 99 SEIRawUserDataUnregistered sei_identifier; 100 char *sei_identifier_string; 101 102 int aud_needed; 103 int sei_needed; 104 int sei_cbr_workaround_needed; 105} VAAPIEncodeH264Context; 106 107 108static int vaapi_encode_h264_write_access_unit(AVCodecContext *avctx, 109 char *data, size_t *data_len, 110 CodedBitstreamFragment *au) 111{ 112 VAAPIEncodeH264Context *priv = avctx->priv_data; 113 int err; 114 115 err = ff_cbs_write_fragment_data(priv->cbc, au); 116 if (err < 0) { 117 av_log(avctx, AV_LOG_ERROR, "Failed to write packed header.\n"); 118 return err; 119 } 120 121 if (*data_len < 8 * au->data_size - au->data_bit_padding) { 122 av_log(avctx, AV_LOG_ERROR, "Access unit too large: " 123 "%zu < %zu.\n", *data_len, 124 8 * au->data_size - au->data_bit_padding); 125 return AVERROR(ENOSPC); 126 } 127 128 memcpy(data, au->data, au->data_size); 129 *data_len = 8 * au->data_size - au->data_bit_padding; 130 131 return 0; 132} 133 134static int vaapi_encode_h264_add_nal(AVCodecContext *avctx, 135 CodedBitstreamFragment *au, 136 void *nal_unit) 137{ 138 H264RawNALUnitHeader *header = nal_unit; 139 int err; 140 141 err = ff_cbs_insert_unit_content(au, -1, 142 header->nal_unit_type, nal_unit, NULL); 143 if (err < 0) { 144 av_log(avctx, AV_LOG_ERROR, "Failed to add NAL unit: " 145 "type = %d.\n", header->nal_unit_type); 146 return err; 147 } 148 149 return 0; 150} 151 152static int vaapi_encode_h264_write_sequence_header(AVCodecContext *avctx, 153 char *data, size_t *data_len) 154{ 155 VAAPIEncodeH264Context *priv = avctx->priv_data; 156 CodedBitstreamFragment *au = &priv->current_access_unit; 157 int err; 158 159 if (priv->aud_needed) { 160 err = vaapi_encode_h264_add_nal(avctx, au, &priv->raw_aud); 161 if (err < 0) 162 goto fail; 163 priv->aud_needed = 0; 164 } 165 166 err = vaapi_encode_h264_add_nal(avctx, au, &priv->raw_sps); 167 if (err < 0) 168 goto fail; 169 170 err = vaapi_encode_h264_add_nal(avctx, au, &priv->raw_pps); 171 if (err < 0) 172 goto fail; 173 174 err = vaapi_encode_h264_write_access_unit(avctx, data, data_len, au); 175fail: 176 ff_cbs_fragment_reset(au); 177 return err; 178} 179 180static int vaapi_encode_h264_write_slice_header(AVCodecContext *avctx, 181 VAAPIEncodePicture *pic, 182 VAAPIEncodeSlice *slice, 183 char *data, size_t *data_len) 184{ 185 VAAPIEncodeH264Context *priv = avctx->priv_data; 186 CodedBitstreamFragment *au = &priv->current_access_unit; 187 int err; 188 189 if (priv->aud_needed) { 190 err = vaapi_encode_h264_add_nal(avctx, au, &priv->raw_aud); 191 if (err < 0) 192 goto fail; 193 priv->aud_needed = 0; 194 } 195 196 err = vaapi_encode_h264_add_nal(avctx, au, &priv->raw_slice); 197 if (err < 0) 198 goto fail; 199 200 err = vaapi_encode_h264_write_access_unit(avctx, data, data_len, au); 201fail: 202 ff_cbs_fragment_reset(au); 203 return err; 204} 205 206static int vaapi_encode_h264_write_extra_header(AVCodecContext *avctx, 207 VAAPIEncodePicture *pic, 208 int index, int *type, 209 char *data, size_t *data_len) 210{ 211 VAAPIEncodeH264Context *priv = avctx->priv_data; 212 CodedBitstreamFragment *au = &priv->current_access_unit; 213 int err; 214 215 if (priv->sei_needed) { 216 if (priv->aud_needed) { 217 err = vaapi_encode_h264_add_nal(avctx, au, &priv->raw_aud); 218 if (err < 0) 219 goto fail; 220 priv->aud_needed = 0; 221 } 222 223 if (priv->sei_needed & SEI_IDENTIFIER) { 224 err = ff_cbs_sei_add_message(priv->cbc, au, 1, 225 SEI_TYPE_USER_DATA_UNREGISTERED, 226 &priv->sei_identifier, NULL); 227 if (err < 0) 228 goto fail; 229 } 230 if (priv->sei_needed & SEI_TIMING) { 231 if (pic->type == PICTURE_TYPE_IDR) { 232 err = ff_cbs_sei_add_message(priv->cbc, au, 1, 233 SEI_TYPE_BUFFERING_PERIOD, 234 &priv->sei_buffering_period, NULL); 235 if (err < 0) 236 goto fail; 237 } 238 err = ff_cbs_sei_add_message(priv->cbc, au, 1, 239 SEI_TYPE_PIC_TIMING, 240 &priv->sei_pic_timing, NULL); 241 if (err < 0) 242 goto fail; 243 } 244 if (priv->sei_needed & SEI_RECOVERY_POINT) { 245 err = ff_cbs_sei_add_message(priv->cbc, au, 1, 246 SEI_TYPE_RECOVERY_POINT, 247 &priv->sei_recovery_point, NULL); 248 if (err < 0) 249 goto fail; 250 } 251 252 priv->sei_needed = 0; 253 254 err = vaapi_encode_h264_write_access_unit(avctx, data, data_len, au); 255 if (err < 0) 256 goto fail; 257 258 ff_cbs_fragment_reset(au); 259 260 *type = VAEncPackedHeaderRawData; 261 return 0; 262 263#if !CONFIG_VAAPI_1 264 } else if (priv->sei_cbr_workaround_needed) { 265 // Insert a zero-length header using the old SEI type. This is 266 // required to avoid triggering broken behaviour on Intel platforms 267 // in CBR mode where an invalid SEI message is generated by the 268 // driver and inserted into the stream. 269 *data_len = 0; 270 *type = VAEncPackedHeaderH264_SEI; 271 priv->sei_cbr_workaround_needed = 0; 272 return 0; 273#endif 274 275 } else { 276 return AVERROR_EOF; 277 } 278 279fail: 280 ff_cbs_fragment_reset(au); 281 return err; 282} 283 284static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) 285{ 286 VAAPIEncodeContext *ctx = avctx->priv_data; 287 VAAPIEncodeH264Context *priv = avctx->priv_data; 288 H264RawSPS *sps = &priv->raw_sps; 289 H264RawPPS *pps = &priv->raw_pps; 290 VAEncSequenceParameterBufferH264 *vseq = ctx->codec_sequence_params; 291 VAEncPictureParameterBufferH264 *vpic = ctx->codec_picture_params; 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 301 if (avctx->profile == FF_PROFILE_H264_CONSTRAINED_BASELINE || 302 avctx->profile == FF_PROFILE_H264_MAIN) 303 sps->constraint_set1_flag = 1; 304 305 if (avctx->profile == FF_PROFILE_H264_HIGH) 306 sps->constraint_set3_flag = ctx->gop_size == 1; 307 308 if (avctx->profile == FF_PROFILE_H264_MAIN || 309 avctx->profile == FF_PROFILE_H264_HIGH) { 310 sps->constraint_set4_flag = 1; 311 sps->constraint_set5_flag = ctx->b_per_p == 0; 312 } 313 314 if (ctx->gop_size == 1) 315 priv->dpb_frames = 0; 316 else 317 priv->dpb_frames = 1 + ctx->max_b_depth; 318 319 if (avctx->level != FF_LEVEL_UNKNOWN) { 320 sps->level_idc = avctx->level; 321 } else { 322 const H264LevelDescriptor *level; 323 int framerate; 324 325 if (avctx->framerate.num > 0 && avctx->framerate.den > 0) 326 framerate = avctx->framerate.num / avctx->framerate.den; 327 else 328 framerate = 0; 329 330 level = ff_h264_guess_level(sps->profile_idc, 331 avctx->bit_rate, 332 framerate, 333 priv->mb_width * 16, 334 priv->mb_height * 16, 335 priv->dpb_frames); 336 if (level) { 337 av_log(avctx, AV_LOG_VERBOSE, "Using level %s.\n", level->name); 338 if (level->constraint_set3_flag) 339 sps->constraint_set3_flag = 1; 340 sps->level_idc = level->level_idc; 341 } else { 342 av_log(avctx, AV_LOG_WARNING, "Stream will not conform " 343 "to any level: using level 6.2.\n"); 344 sps->level_idc = 62; 345 } 346 } 347 348 sps->seq_parameter_set_id = 0; 349 sps->chroma_format_idc = 1; 350 351 sps->log2_max_frame_num_minus4 = 4; 352 sps->pic_order_cnt_type = 0; 353 sps->log2_max_pic_order_cnt_lsb_minus4 = 4; 354 355 sps->max_num_ref_frames = priv->dpb_frames; 356 357 sps->pic_width_in_mbs_minus1 = priv->mb_width - 1; 358 sps->pic_height_in_map_units_minus1 = priv->mb_height - 1; 359 360 sps->frame_mbs_only_flag = 1; 361 sps->direct_8x8_inference_flag = 1; 362 363 if (avctx->width != 16 * priv->mb_width || 364 avctx->height != 16 * priv->mb_height) { 365 sps->frame_cropping_flag = 1; 366 367 sps->frame_crop_left_offset = 0; 368 sps->frame_crop_right_offset = 369 (16 * priv->mb_width - avctx->width) / 2; 370 sps->frame_crop_top_offset = 0; 371 sps->frame_crop_bottom_offset = 372 (16 * priv->mb_height - avctx->height) / 2; 373 } else { 374 sps->frame_cropping_flag = 0; 375 } 376 377 sps->vui_parameters_present_flag = 1; 378 379 if (avctx->sample_aspect_ratio.num != 0 && 380 avctx->sample_aspect_ratio.den != 0) { 381 static const AVRational sar_idc[] = { 382 { 0, 0 }, 383 { 1, 1 }, { 12, 11 }, { 10, 11 }, { 16, 11 }, 384 { 40, 33 }, { 24, 11 }, { 20, 11 }, { 32, 11 }, 385 { 80, 33 }, { 18, 11 }, { 15, 11 }, { 64, 33 }, 386 { 160, 99 }, { 4, 3 }, { 3, 2 }, { 2, 1 }, 387 }; 388 int num, den, i; 389 av_reduce(&num, &den, avctx->sample_aspect_ratio.num, 390 avctx->sample_aspect_ratio.den, 65535); 391 for (i = 0; i < FF_ARRAY_ELEMS(sar_idc); i++) { 392 if (num == sar_idc[i].num && 393 den == sar_idc[i].den) { 394 sps->vui.aspect_ratio_idc = i; 395 break; 396 } 397 } 398 if (i >= FF_ARRAY_ELEMS(sar_idc)) { 399 sps->vui.aspect_ratio_idc = 255; 400 sps->vui.sar_width = num; 401 sps->vui.sar_height = den; 402 } 403 sps->vui.aspect_ratio_info_present_flag = 1; 404 } 405 406 // Unspecified video format, from table E-2. 407 sps->vui.video_format = 5; 408 sps->vui.video_full_range_flag = 409 avctx->color_range == AVCOL_RANGE_JPEG; 410 sps->vui.colour_primaries = avctx->color_primaries; 411 sps->vui.transfer_characteristics = avctx->color_trc; 412 sps->vui.matrix_coefficients = avctx->colorspace; 413 if (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED || 414 avctx->color_trc != AVCOL_TRC_UNSPECIFIED || 415 avctx->colorspace != AVCOL_SPC_UNSPECIFIED) 416 sps->vui.colour_description_present_flag = 1; 417 if (avctx->color_range != AVCOL_RANGE_UNSPECIFIED || 418 sps->vui.colour_description_present_flag) 419 sps->vui.video_signal_type_present_flag = 1; 420 421 if (avctx->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED) { 422 sps->vui.chroma_loc_info_present_flag = 1; 423 sps->vui.chroma_sample_loc_type_top_field = 424 sps->vui.chroma_sample_loc_type_bottom_field = 425 avctx->chroma_sample_location - 1; 426 } 427 428 sps->vui.timing_info_present_flag = 1; 429 if (avctx->framerate.num > 0 && avctx->framerate.den > 0) { 430 sps->vui.num_units_in_tick = avctx->framerate.den; 431 sps->vui.time_scale = 2 * avctx->framerate.num; 432 sps->vui.fixed_frame_rate_flag = 1; 433 } else { 434 sps->vui.num_units_in_tick = avctx->time_base.num; 435 sps->vui.time_scale = 2 * avctx->time_base.den; 436 sps->vui.fixed_frame_rate_flag = 0; 437 } 438 439 if (priv->sei & SEI_TIMING) { 440 H264RawHRD *hrd = &sps->vui.nal_hrd_parameters; 441 H264RawSEIBufferingPeriod *bp = &priv->sei_buffering_period; 442 443 sps->vui.nal_hrd_parameters_present_flag = 1; 444 445 hrd->cpb_cnt_minus1 = 0; 446 447 // Try to scale these to a sensible range so that the 448 // golomb encode of the value is not overlong. 449 hrd->bit_rate_scale = 450 av_clip_uintp2(av_log2(ctx->va_bit_rate) - 15 - 6, 4); 451 hrd->bit_rate_value_minus1[0] = 452 (ctx->va_bit_rate >> hrd->bit_rate_scale + 6) - 1; 453 454 hrd->cpb_size_scale = 455 av_clip_uintp2(av_log2(ctx->hrd_params.buffer_size) - 15 - 4, 4); 456 hrd->cpb_size_value_minus1[0] = 457 (ctx->hrd_params.buffer_size >> hrd->cpb_size_scale + 4) - 1; 458 459 // CBR mode as defined for the HRD cannot be achieved without filler 460 // data, so this flag cannot be set even with VAAPI CBR modes. 461 hrd->cbr_flag[0] = 0; 462 463 hrd->initial_cpb_removal_delay_length_minus1 = 23; 464 hrd->cpb_removal_delay_length_minus1 = 23; 465 hrd->dpb_output_delay_length_minus1 = 7; 466 hrd->time_offset_length = 0; 467 468 bp->seq_parameter_set_id = sps->seq_parameter_set_id; 469 470 // This calculation can easily overflow 32 bits. 471 bp->nal.initial_cpb_removal_delay[0] = 90000 * 472 (uint64_t)ctx->hrd_params.initial_buffer_fullness / 473 ctx->hrd_params.buffer_size; 474 bp->nal.initial_cpb_removal_delay_offset[0] = 0; 475 } else { 476 sps->vui.nal_hrd_parameters_present_flag = 0; 477 sps->vui.low_delay_hrd_flag = 1 - sps->vui.fixed_frame_rate_flag; 478 } 479 480 sps->vui.bitstream_restriction_flag = 1; 481 sps->vui.motion_vectors_over_pic_boundaries_flag = 1; 482 sps->vui.log2_max_mv_length_horizontal = 15; 483 sps->vui.log2_max_mv_length_vertical = 15; 484 sps->vui.max_num_reorder_frames = ctx->max_b_depth; 485 sps->vui.max_dec_frame_buffering = ctx->max_b_depth + 1; 486 487 pps->nal_unit_header.nal_ref_idc = 3; 488 pps->nal_unit_header.nal_unit_type = H264_NAL_PPS; 489 490 pps->pic_parameter_set_id = 0; 491 pps->seq_parameter_set_id = 0; 492 493 pps->entropy_coding_mode_flag = 494 !(sps->profile_idc == FF_PROFILE_H264_BASELINE || 495 sps->profile_idc == FF_PROFILE_H264_EXTENDED || 496 sps->profile_idc == FF_PROFILE_H264_CAVLC_444); 497 if (!priv->coder && pps->entropy_coding_mode_flag) 498 pps->entropy_coding_mode_flag = 0; 499 500 pps->num_ref_idx_l0_default_active_minus1 = 0; 501 pps->num_ref_idx_l1_default_active_minus1 = 0; 502 503 pps->pic_init_qp_minus26 = priv->fixed_qp_idr - 26; 504 505 if (sps->profile_idc == FF_PROFILE_H264_BASELINE || 506 sps->profile_idc == FF_PROFILE_H264_EXTENDED || 507 sps->profile_idc == FF_PROFILE_H264_MAIN) { 508 pps->more_rbsp_data = 0; 509 } else { 510 pps->more_rbsp_data = 1; 511 512 pps->transform_8x8_mode_flag = 1; 513 } 514 515 *vseq = (VAEncSequenceParameterBufferH264) { 516 .seq_parameter_set_id = sps->seq_parameter_set_id, 517 .level_idc = sps->level_idc, 518 .intra_period = ctx->gop_size, 519 .intra_idr_period = ctx->gop_size, 520 .ip_period = ctx->b_per_p + 1, 521 522 .bits_per_second = ctx->va_bit_rate, 523 .max_num_ref_frames = sps->max_num_ref_frames, 524 .picture_width_in_mbs = sps->pic_width_in_mbs_minus1 + 1, 525 .picture_height_in_mbs = sps->pic_height_in_map_units_minus1 + 1, 526 527 .seq_fields.bits = { 528 .chroma_format_idc = sps->chroma_format_idc, 529 .frame_mbs_only_flag = sps->frame_mbs_only_flag, 530 .mb_adaptive_frame_field_flag = sps->mb_adaptive_frame_field_flag, 531 .seq_scaling_matrix_present_flag = sps->seq_scaling_matrix_present_flag, 532 .direct_8x8_inference_flag = sps->direct_8x8_inference_flag, 533 .log2_max_frame_num_minus4 = sps->log2_max_frame_num_minus4, 534 .pic_order_cnt_type = sps->pic_order_cnt_type, 535 .log2_max_pic_order_cnt_lsb_minus4 = sps->log2_max_pic_order_cnt_lsb_minus4, 536 .delta_pic_order_always_zero_flag = sps->delta_pic_order_always_zero_flag, 537 }, 538 539 .bit_depth_luma_minus8 = sps->bit_depth_luma_minus8, 540 .bit_depth_chroma_minus8 = sps->bit_depth_chroma_minus8, 541 542 .frame_cropping_flag = sps->frame_cropping_flag, 543 .frame_crop_left_offset = sps->frame_crop_left_offset, 544 .frame_crop_right_offset = sps->frame_crop_right_offset, 545 .frame_crop_top_offset = sps->frame_crop_top_offset, 546 .frame_crop_bottom_offset = sps->frame_crop_bottom_offset, 547 548 .vui_parameters_present_flag = sps->vui_parameters_present_flag, 549 550 .vui_fields.bits = { 551 .aspect_ratio_info_present_flag = sps->vui.aspect_ratio_info_present_flag, 552 .timing_info_present_flag = sps->vui.timing_info_present_flag, 553 .bitstream_restriction_flag = sps->vui.bitstream_restriction_flag, 554 .log2_max_mv_length_horizontal = sps->vui.log2_max_mv_length_horizontal, 555 .log2_max_mv_length_vertical = sps->vui.log2_max_mv_length_vertical, 556 }, 557 558 .aspect_ratio_idc = sps->vui.aspect_ratio_idc, 559 .sar_width = sps->vui.sar_width, 560 .sar_height = sps->vui.sar_height, 561 .num_units_in_tick = sps->vui.num_units_in_tick, 562 .time_scale = sps->vui.time_scale, 563 }; 564 565 *vpic = (VAEncPictureParameterBufferH264) { 566 .CurrPic = { 567 .picture_id = VA_INVALID_ID, 568 .flags = VA_PICTURE_H264_INVALID, 569 }, 570 571 .coded_buf = VA_INVALID_ID, 572 573 .pic_parameter_set_id = pps->pic_parameter_set_id, 574 .seq_parameter_set_id = pps->seq_parameter_set_id, 575 576 .pic_init_qp = pps->pic_init_qp_minus26 + 26, 577 .num_ref_idx_l0_active_minus1 = pps->num_ref_idx_l0_default_active_minus1, 578 .num_ref_idx_l1_active_minus1 = pps->num_ref_idx_l1_default_active_minus1, 579 580 .chroma_qp_index_offset = pps->chroma_qp_index_offset, 581 .second_chroma_qp_index_offset = pps->second_chroma_qp_index_offset, 582 583 .pic_fields.bits = { 584 .entropy_coding_mode_flag = pps->entropy_coding_mode_flag, 585 .weighted_pred_flag = pps->weighted_pred_flag, 586 .weighted_bipred_idc = pps->weighted_bipred_idc, 587 .constrained_intra_pred_flag = pps->constrained_intra_pred_flag, 588 .transform_8x8_mode_flag = pps->transform_8x8_mode_flag, 589 .deblocking_filter_control_present_flag = 590 pps->deblocking_filter_control_present_flag, 591 .redundant_pic_cnt_present_flag = pps->redundant_pic_cnt_present_flag, 592 .pic_order_present_flag = 593 pps->bottom_field_pic_order_in_frame_present_flag, 594 .pic_scaling_matrix_present_flag = pps->pic_scaling_matrix_present_flag, 595 }, 596 }; 597 598 return 0; 599} 600 601static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, 602 VAAPIEncodePicture *pic) 603{ 604 VAAPIEncodeContext *ctx = avctx->priv_data; 605 VAAPIEncodeH264Context *priv = avctx->priv_data; 606 VAAPIEncodeH264Picture *hpic = pic->priv_data; 607 VAAPIEncodePicture *prev = pic->prev; 608 VAAPIEncodeH264Picture *hprev = prev ? prev->priv_data : NULL; 609 VAEncPictureParameterBufferH264 *vpic = pic->codec_picture_params; 610 int i; 611 612 if (pic->type == PICTURE_TYPE_IDR) { 613 av_assert0(pic->display_order == pic->encode_order); 614 615 hpic->frame_num = 0; 616 hpic->last_idr_frame = pic->display_order; 617 hpic->idr_pic_id = hprev ? hprev->idr_pic_id + 1 : 0; 618 619 hpic->primary_pic_type = 0; 620 hpic->slice_type = 7; 621 } else { 622 av_assert0(prev); 623 624 hpic->frame_num = hprev->frame_num + prev->is_reference; 625 626 hpic->last_idr_frame = hprev->last_idr_frame; 627 hpic->idr_pic_id = hprev->idr_pic_id; 628 629 if (pic->type == PICTURE_TYPE_I) { 630 hpic->slice_type = 7; 631 hpic->primary_pic_type = 0; 632 } else if (pic->type == PICTURE_TYPE_P) { 633 hpic->slice_type = 5; 634 hpic->primary_pic_type = 1; 635 } else { 636 hpic->slice_type = 6; 637 hpic->primary_pic_type = 2; 638 } 639 } 640 hpic->pic_order_cnt = pic->display_order - hpic->last_idr_frame; 641 hpic->dpb_delay = pic->display_order - pic->encode_order + ctx->max_b_depth; 642 hpic->cpb_delay = pic->encode_order - hpic->last_idr_frame; 643 644 if (priv->aud) { 645 priv->aud_needed = 1; 646 priv->raw_aud = (H264RawAUD) { 647 .nal_unit_header = { 648 .nal_unit_type = H264_NAL_AUD, 649 }, 650 .primary_pic_type = hpic->primary_pic_type, 651 }; 652 } else { 653 priv->aud_needed = 0; 654 } 655 656 priv->sei_needed = 0; 657 658 if (priv->sei & SEI_IDENTIFIER && pic->encode_order == 0) 659 priv->sei_needed |= SEI_IDENTIFIER; 660#if !CONFIG_VAAPI_1 661 if (ctx->va_rc_mode == VA_RC_CBR) 662 priv->sei_cbr_workaround_needed = 1; 663#endif 664 665 if (priv->sei & SEI_TIMING) { 666 priv->sei_pic_timing = (H264RawSEIPicTiming) { 667 .cpb_removal_delay = 2 * hpic->cpb_delay, 668 .dpb_output_delay = 2 * hpic->dpb_delay, 669 }; 670 671 priv->sei_needed |= SEI_TIMING; 672 } 673 674 if (priv->sei & SEI_RECOVERY_POINT && pic->type == PICTURE_TYPE_I) { 675 priv->sei_recovery_point = (H264RawSEIRecoveryPoint) { 676 .recovery_frame_cnt = 0, 677 .exact_match_flag = 1, 678 .broken_link_flag = ctx->b_per_p > 0, 679 }; 680 681 priv->sei_needed |= SEI_RECOVERY_POINT; 682 } 683 684 vpic->CurrPic = (VAPictureH264) { 685 .picture_id = pic->recon_surface, 686 .frame_idx = hpic->frame_num, 687 .flags = 0, 688 .TopFieldOrderCnt = hpic->pic_order_cnt, 689 .BottomFieldOrderCnt = hpic->pic_order_cnt, 690 }; 691 692 for (i = 0; i < pic->nb_refs; i++) { 693 VAAPIEncodePicture *ref = pic->refs[i]; 694 VAAPIEncodeH264Picture *href; 695 696 av_assert0(ref && ref->encode_order < pic->encode_order); 697 href = ref->priv_data; 698 699 vpic->ReferenceFrames[i] = (VAPictureH264) { 700 .picture_id = ref->recon_surface, 701 .frame_idx = href->frame_num, 702 .flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE, 703 .TopFieldOrderCnt = href->pic_order_cnt, 704 .BottomFieldOrderCnt = href->pic_order_cnt, 705 }; 706 } 707 for (; i < FF_ARRAY_ELEMS(vpic->ReferenceFrames); i++) { 708 vpic->ReferenceFrames[i] = (VAPictureH264) { 709 .picture_id = VA_INVALID_ID, 710 .flags = VA_PICTURE_H264_INVALID, 711 }; 712 } 713 714 vpic->coded_buf = pic->output_buffer; 715 716 vpic->frame_num = hpic->frame_num; 717 718 vpic->pic_fields.bits.idr_pic_flag = (pic->type == PICTURE_TYPE_IDR); 719 vpic->pic_fields.bits.reference_pic_flag = (pic->type != PICTURE_TYPE_B); 720 721 return 0; 722} 723 724static void vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx, 725 VAAPIEncodePicture *pic, 726 VAAPIEncodePicture **rpl0, 727 VAAPIEncodePicture **rpl1, 728 int *rpl_size) 729{ 730 VAAPIEncodePicture *prev; 731 VAAPIEncodeH264Picture *hp, *hn, *hc; 732 int i, j, n = 0; 733 734 prev = pic->prev; 735 av_assert0(prev); 736 hp = pic->priv_data; 737 738 for (i = 0; i < pic->prev->nb_dpb_pics; i++) { 739 hn = prev->dpb[i]->priv_data; 740 av_assert0(hn->frame_num < hp->frame_num); 741 742 if (pic->type == PICTURE_TYPE_P) { 743 for (j = n; j > 0; j--) { 744 hc = rpl0[j - 1]->priv_data; 745 av_assert0(hc->frame_num != hn->frame_num); 746 if (hc->frame_num > hn->frame_num) 747 break; 748 rpl0[j] = rpl0[j - 1]; 749 } 750 rpl0[j] = prev->dpb[i]; 751 752 } else if (pic->type == PICTURE_TYPE_B) { 753 for (j = n; j > 0; j--) { 754 hc = rpl0[j - 1]->priv_data; 755 av_assert0(hc->pic_order_cnt != hp->pic_order_cnt); 756 if (hc->pic_order_cnt < hp->pic_order_cnt) { 757 if (hn->pic_order_cnt > hp->pic_order_cnt || 758 hn->pic_order_cnt < hc->pic_order_cnt) 759 break; 760 } else { 761 if (hn->pic_order_cnt > hc->pic_order_cnt) 762 break; 763 } 764 rpl0[j] = rpl0[j - 1]; 765 } 766 rpl0[j] = prev->dpb[i]; 767 768 for (j = n; j > 0; j--) { 769 hc = rpl1[j - 1]->priv_data; 770 av_assert0(hc->pic_order_cnt != hp->pic_order_cnt); 771 if (hc->pic_order_cnt > hp->pic_order_cnt) { 772 if (hn->pic_order_cnt < hp->pic_order_cnt || 773 hn->pic_order_cnt > hc->pic_order_cnt) 774 break; 775 } else { 776 if (hn->pic_order_cnt < hc->pic_order_cnt) 777 break; 778 } 779 rpl1[j] = rpl1[j - 1]; 780 } 781 rpl1[j] = prev->dpb[i]; 782 } 783 784 ++n; 785 } 786 787 if (pic->type == PICTURE_TYPE_B) { 788 for (i = 0; i < n; i++) { 789 if (rpl0[i] != rpl1[i]) 790 break; 791 } 792 if (i == n) 793 FFSWAP(VAAPIEncodePicture*, rpl1[0], rpl1[1]); 794 } 795 796 if (pic->type == PICTURE_TYPE_P || 797 pic->type == PICTURE_TYPE_B) { 798 av_log(avctx, AV_LOG_DEBUG, "Default RefPicList0 for fn=%d/poc=%d:", 799 hp->frame_num, hp->pic_order_cnt); 800 for (i = 0; i < n; i++) { 801 hn = rpl0[i]->priv_data; 802 av_log(avctx, AV_LOG_DEBUG, " fn=%d/poc=%d", 803 hn->frame_num, hn->pic_order_cnt); 804 } 805 av_log(avctx, AV_LOG_DEBUG, "\n"); 806 } 807 if (pic->type == PICTURE_TYPE_B) { 808 av_log(avctx, AV_LOG_DEBUG, "Default RefPicList1 for fn=%d/poc=%d:", 809 hp->frame_num, hp->pic_order_cnt); 810 for (i = 0; i < n; i++) { 811 hn = rpl1[i]->priv_data; 812 av_log(avctx, AV_LOG_DEBUG, " fn=%d/poc=%d", 813 hn->frame_num, hn->pic_order_cnt); 814 } 815 av_log(avctx, AV_LOG_DEBUG, "\n"); 816 } 817 818 *rpl_size = n; 819} 820 821static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx, 822 VAAPIEncodePicture *pic, 823 VAAPIEncodeSlice *slice) 824{ 825 VAAPIEncodeH264Context *priv = avctx->priv_data; 826 VAAPIEncodeH264Picture *hpic = pic->priv_data; 827 VAAPIEncodePicture *prev = pic->prev; 828 H264RawSPS *sps = &priv->raw_sps; 829 H264RawPPS *pps = &priv->raw_pps; 830 H264RawSliceHeader *sh = &priv->raw_slice.header; 831 VAEncPictureParameterBufferH264 *vpic = pic->codec_picture_params; 832 VAEncSliceParameterBufferH264 *vslice = slice->codec_slice_params; 833 int i, j; 834 835 if (pic->type == PICTURE_TYPE_IDR) { 836 sh->nal_unit_header.nal_unit_type = H264_NAL_IDR_SLICE; 837 sh->nal_unit_header.nal_ref_idc = 3; 838 } else { 839 sh->nal_unit_header.nal_unit_type = H264_NAL_SLICE; 840 sh->nal_unit_header.nal_ref_idc = pic->is_reference; 841 } 842 843 sh->first_mb_in_slice = slice->block_start; 844 sh->slice_type = hpic->slice_type; 845 846 sh->pic_parameter_set_id = pps->pic_parameter_set_id; 847 848 sh->frame_num = hpic->frame_num & 849 ((1 << (4 + sps->log2_max_frame_num_minus4)) - 1); 850 sh->idr_pic_id = hpic->idr_pic_id; 851 sh->pic_order_cnt_lsb = hpic->pic_order_cnt & 852 ((1 << (4 + sps->log2_max_pic_order_cnt_lsb_minus4)) - 1); 853 854 sh->direct_spatial_mv_pred_flag = 1; 855 856 if (pic->type == PICTURE_TYPE_B) 857 sh->slice_qp_delta = priv->fixed_qp_b - (pps->pic_init_qp_minus26 + 26); 858 else if (pic->type == PICTURE_TYPE_P) 859 sh->slice_qp_delta = priv->fixed_qp_p - (pps->pic_init_qp_minus26 + 26); 860 else 861 sh->slice_qp_delta = priv->fixed_qp_idr - (pps->pic_init_qp_minus26 + 26); 862 863 if (pic->is_reference && pic->type != PICTURE_TYPE_IDR) { 864 VAAPIEncodePicture *discard_list[MAX_DPB_SIZE]; 865 int discard = 0, keep = 0; 866 867 // Discard everything which is in the DPB of the previous frame but 868 // not in the DPB of this one. 869 for (i = 0; i < prev->nb_dpb_pics; i++) { 870 for (j = 0; j < pic->nb_dpb_pics; j++) { 871 if (prev->dpb[i] == pic->dpb[j]) 872 break; 873 } 874 if (j == pic->nb_dpb_pics) { 875 discard_list[discard] = prev->dpb[i]; 876 ++discard; 877 } else { 878 ++keep; 879 } 880 } 881 av_assert0(keep <= priv->dpb_frames); 882 883 if (discard == 0) { 884 sh->adaptive_ref_pic_marking_mode_flag = 0; 885 } else { 886 sh->adaptive_ref_pic_marking_mode_flag = 1; 887 for (i = 0; i < discard; i++) { 888 VAAPIEncodeH264Picture *old = discard_list[i]->priv_data; 889 av_assert0(old->frame_num < hpic->frame_num); 890 sh->mmco[i].memory_management_control_operation = 1; 891 sh->mmco[i].difference_of_pic_nums_minus1 = 892 hpic->frame_num - old->frame_num - 1; 893 } 894 sh->mmco[i].memory_management_control_operation = 0; 895 } 896 } 897 898 // If the intended references are not the first entries of RefPicListN 899 // by default, use ref-pic-list-modification to move them there. 900 if (pic->type == PICTURE_TYPE_P || pic->type == PICTURE_TYPE_B) { 901 VAAPIEncodePicture *def_l0[MAX_DPB_SIZE], *def_l1[MAX_DPB_SIZE]; 902 VAAPIEncodeH264Picture *href; 903 int n; 904 905 vaapi_encode_h264_default_ref_pic_list(avctx, pic, 906 def_l0, def_l1, &n); 907 908 if (pic->type == PICTURE_TYPE_P) { 909 int need_rplm = 0; 910 for (i = 0; i < pic->nb_refs; i++) { 911 av_assert0(pic->refs[i]); 912 if (pic->refs[i] != def_l0[i]) 913 need_rplm = 1; 914 } 915 916 sh->ref_pic_list_modification_flag_l0 = need_rplm; 917 if (need_rplm) { 918 int pic_num = hpic->frame_num; 919 for (i = 0; i < pic->nb_refs; i++) { 920 href = pic->refs[i]->priv_data; 921 av_assert0(href->frame_num != pic_num); 922 if (href->frame_num < pic_num) { 923 sh->rplm_l0[i].modification_of_pic_nums_idc = 0; 924 sh->rplm_l0[i].abs_diff_pic_num_minus1 = 925 pic_num - href->frame_num - 1; 926 } else { 927 sh->rplm_l0[i].modification_of_pic_nums_idc = 1; 928 sh->rplm_l0[i].abs_diff_pic_num_minus1 = 929 href->frame_num - pic_num - 1; 930 } 931 pic_num = href->frame_num; 932 } 933 sh->rplm_l0[i].modification_of_pic_nums_idc = 3; 934 } 935 936 } else { 937 int need_rplm_l0 = 0, need_rplm_l1 = 0; 938 int n0 = 0, n1 = 0; 939 for (i = 0; i < pic->nb_refs; i++) { 940 av_assert0(pic->refs[i]); 941 href = pic->refs[i]->priv_data; 942 av_assert0(href->pic_order_cnt != hpic->pic_order_cnt); 943 if (href->pic_order_cnt < hpic->pic_order_cnt) { 944 if (pic->refs[i] != def_l0[n0]) 945 need_rplm_l0 = 1; 946 ++n0; 947 } else { 948 if (pic->refs[i] != def_l1[n1]) 949 need_rplm_l1 = 1; 950 ++n1; 951 } 952 } 953 954 sh->ref_pic_list_modification_flag_l0 = need_rplm_l0; 955 if (need_rplm_l0) { 956 int pic_num = hpic->frame_num; 957 for (i = j = 0; i < pic->nb_refs; i++) { 958 href = pic->refs[i]->priv_data; 959 if (href->pic_order_cnt > hpic->pic_order_cnt) 960 continue; 961 av_assert0(href->frame_num != pic_num); 962 if (href->frame_num < pic_num) { 963 sh->rplm_l0[j].modification_of_pic_nums_idc = 0; 964 sh->rplm_l0[j].abs_diff_pic_num_minus1 = 965 pic_num - href->frame_num - 1; 966 } else { 967 sh->rplm_l0[j].modification_of_pic_nums_idc = 1; 968 sh->rplm_l0[j].abs_diff_pic_num_minus1 = 969 href->frame_num - pic_num - 1; 970 } 971 pic_num = href->frame_num; 972 ++j; 973 } 974 av_assert0(j == n0); 975 sh->rplm_l0[j].modification_of_pic_nums_idc = 3; 976 } 977 978 sh->ref_pic_list_modification_flag_l1 = need_rplm_l1; 979 if (need_rplm_l1) { 980 int pic_num = hpic->frame_num; 981 for (i = j = 0; i < pic->nb_refs; i++) { 982 href = pic->refs[i]->priv_data; 983 if (href->pic_order_cnt < hpic->pic_order_cnt) 984 continue; 985 av_assert0(href->frame_num != pic_num); 986 if (href->frame_num < pic_num) { 987 sh->rplm_l1[j].modification_of_pic_nums_idc = 0; 988 sh->rplm_l1[j].abs_diff_pic_num_minus1 = 989 pic_num - href->frame_num - 1; 990 } else { 991 sh->rplm_l1[j].modification_of_pic_nums_idc = 1; 992 sh->rplm_l1[j].abs_diff_pic_num_minus1 = 993 href->frame_num - pic_num - 1; 994 } 995 pic_num = href->frame_num; 996 ++j; 997 } 998 av_assert0(j == n1); 999 sh->rplm_l1[j].modification_of_pic_nums_idc = 3; 1000 } 1001 } 1002 } 1003 1004 vslice->macroblock_address = slice->block_start; 1005 vslice->num_macroblocks = slice->block_size; 1006 1007 vslice->macroblock_info = VA_INVALID_ID; 1008 1009 vslice->slice_type = sh->slice_type % 5; 1010 vslice->pic_parameter_set_id = sh->pic_parameter_set_id; 1011 vslice->idr_pic_id = sh->idr_pic_id; 1012 1013 vslice->pic_order_cnt_lsb = sh->pic_order_cnt_lsb; 1014 1015 vslice->direct_spatial_mv_pred_flag = sh->direct_spatial_mv_pred_flag; 1016 1017 for (i = 0; i < FF_ARRAY_ELEMS(vslice->RefPicList0); i++) { 1018 vslice->RefPicList0[i].picture_id = VA_INVALID_ID; 1019 vslice->RefPicList0[i].flags = VA_PICTURE_H264_INVALID; 1020 vslice->RefPicList1[i].picture_id = VA_INVALID_ID; 1021 vslice->RefPicList1[i].flags = VA_PICTURE_H264_INVALID; 1022 } 1023 1024 av_assert0(pic->nb_refs <= 2); 1025 if (pic->nb_refs >= 1) { 1026 // Backward reference for P- or B-frame. 1027 av_assert0(pic->type == PICTURE_TYPE_P || 1028 pic->type == PICTURE_TYPE_B); 1029 vslice->RefPicList0[0] = vpic->ReferenceFrames[0]; 1030 } 1031 if (pic->nb_refs >= 2) { 1032 // Forward reference for B-frame. 1033 av_assert0(pic->type == PICTURE_TYPE_B); 1034 vslice->RefPicList1[0] = vpic->ReferenceFrames[1]; 1035 } 1036 1037 vslice->slice_qp_delta = sh->slice_qp_delta; 1038 1039 return 0; 1040} 1041 1042static av_cold int vaapi_encode_h264_configure(AVCodecContext *avctx) 1043{ 1044 VAAPIEncodeContext *ctx = avctx->priv_data; 1045 VAAPIEncodeH264Context *priv = avctx->priv_data; 1046 int err; 1047 1048 err = ff_cbs_init(&priv->cbc, AV_CODEC_ID_H264, avctx); 1049 if (err < 0) 1050 return err; 1051 1052 priv->mb_width = FFALIGN(avctx->width, 16) / 16; 1053 priv->mb_height = FFALIGN(avctx->height, 16) / 16; 1054 1055 if (ctx->va_rc_mode == VA_RC_CQP) { 1056 priv->fixed_qp_p = av_clip(ctx->rc_quality, 1, 51); 1057 if (avctx->i_quant_factor > 0.0) 1058 priv->fixed_qp_idr = 1059 av_clip((avctx->i_quant_factor * priv->fixed_qp_p + 1060 avctx->i_quant_offset) + 0.5, 1, 51); 1061 else 1062 priv->fixed_qp_idr = priv->fixed_qp_p; 1063 if (avctx->b_quant_factor > 0.0) 1064 priv->fixed_qp_b = 1065 av_clip((avctx->b_quant_factor * priv->fixed_qp_p + 1066 avctx->b_quant_offset) + 0.5, 1, 51); 1067 else 1068 priv->fixed_qp_b = priv->fixed_qp_p; 1069 1070 av_log(avctx, AV_LOG_DEBUG, "Using fixed QP = " 1071 "%d / %d / %d for IDR- / P- / B-frames.\n", 1072 priv->fixed_qp_idr, priv->fixed_qp_p, priv->fixed_qp_b); 1073 1074 } else { 1075 // These still need to be set for pic_init_qp/slice_qp_delta. 1076 priv->fixed_qp_idr = 26; 1077 priv->fixed_qp_p = 26; 1078 priv->fixed_qp_b = 26; 1079 } 1080 1081 if (!ctx->rc_mode->hrd) { 1082 // Timing SEI requires a mode respecting HRD parameters. 1083 priv->sei &= ~SEI_TIMING; 1084 } 1085 1086 if (priv->sei & SEI_IDENTIFIER) { 1087 const char *lavc = LIBAVCODEC_IDENT; 1088 const char *vaapi = VA_VERSION_S; 1089 const char *driver; 1090 int len; 1091 1092 memcpy(priv->sei_identifier.uuid_iso_iec_11578, 1093 vaapi_encode_h264_sei_identifier_uuid, 1094 sizeof(priv->sei_identifier.uuid_iso_iec_11578)); 1095 1096 driver = vaQueryVendorString(ctx->hwctx->display); 1097 if (!driver) 1098 driver = "unknown driver"; 1099 1100 len = snprintf(NULL, 0, "%s / VAAPI %s / %s", lavc, vaapi, driver); 1101 if (len >= 0) { 1102 priv->sei_identifier_string = av_malloc(len + 1); 1103 if (!priv->sei_identifier_string) 1104 return AVERROR(ENOMEM); 1105 1106 snprintf(priv->sei_identifier_string, len + 1, 1107 "%s / VAAPI %s / %s", lavc, vaapi, driver); 1108 1109 priv->sei_identifier.data = priv->sei_identifier_string; 1110 priv->sei_identifier.data_length = len + 1; 1111 } 1112 } 1113 1114 ctx->roi_quant_range = 51 + 6 * (ctx->profile->depth - 8); 1115 1116 return 0; 1117} 1118 1119static const VAAPIEncodeProfile vaapi_encode_h264_profiles[] = { 1120 { FF_PROFILE_H264_HIGH, 8, 3, 1, 1, VAProfileH264High }, 1121 { FF_PROFILE_H264_MAIN, 8, 3, 1, 1, VAProfileH264Main }, 1122 { FF_PROFILE_H264_CONSTRAINED_BASELINE, 1123 8, 3, 1, 1, VAProfileH264ConstrainedBaseline }, 1124 { FF_PROFILE_UNKNOWN } 1125}; 1126 1127static const VAAPIEncodeType vaapi_encode_type_h264 = { 1128 .profiles = vaapi_encode_h264_profiles, 1129 1130 .flags = FLAG_SLICE_CONTROL | 1131 FLAG_B_PICTURES | 1132 FLAG_B_PICTURE_REFERENCES | 1133 FLAG_NON_IDR_KEY_PICTURES, 1134 1135 .default_quality = 20, 1136 1137 .configure = &vaapi_encode_h264_configure, 1138 1139 .picture_priv_data_size = sizeof(VAAPIEncodeH264Picture), 1140 1141 .sequence_params_size = sizeof(VAEncSequenceParameterBufferH264), 1142 .init_sequence_params = &vaapi_encode_h264_init_sequence_params, 1143 1144 .picture_params_size = sizeof(VAEncPictureParameterBufferH264), 1145 .init_picture_params = &vaapi_encode_h264_init_picture_params, 1146 1147 .slice_params_size = sizeof(VAEncSliceParameterBufferH264), 1148 .init_slice_params = &vaapi_encode_h264_init_slice_params, 1149 1150 .sequence_header_type = VAEncPackedHeaderSequence, 1151 .write_sequence_header = &vaapi_encode_h264_write_sequence_header, 1152 1153 .slice_header_type = VAEncPackedHeaderH264_Slice, 1154 .write_slice_header = &vaapi_encode_h264_write_slice_header, 1155 1156 .write_extra_header = &vaapi_encode_h264_write_extra_header, 1157}; 1158 1159static av_cold int vaapi_encode_h264_init(AVCodecContext *avctx) 1160{ 1161 VAAPIEncodeContext *ctx = avctx->priv_data; 1162 VAAPIEncodeH264Context *priv = avctx->priv_data; 1163 1164 ctx->codec = &vaapi_encode_type_h264; 1165 1166 if (avctx->profile == FF_PROFILE_UNKNOWN) 1167 avctx->profile = priv->profile; 1168 if (avctx->level == FF_LEVEL_UNKNOWN) 1169 avctx->level = priv->level; 1170 if (avctx->compression_level == FF_COMPRESSION_DEFAULT) 1171 avctx->compression_level = priv->quality; 1172 1173 // Reject unsupported profiles. 1174 switch (avctx->profile) { 1175 case FF_PROFILE_H264_BASELINE: 1176 av_log(avctx, AV_LOG_WARNING, "H.264 baseline profile is not " 1177 "supported, using constrained baseline profile instead.\n"); 1178 avctx->profile = FF_PROFILE_H264_CONSTRAINED_BASELINE; 1179 break; 1180 case FF_PROFILE_H264_EXTENDED: 1181 av_log(avctx, AV_LOG_ERROR, "H.264 extended profile " 1182 "is not supported.\n"); 1183 return AVERROR_PATCHWELCOME; 1184 case FF_PROFILE_H264_HIGH_10: 1185 case FF_PROFILE_H264_HIGH_10_INTRA: 1186 av_log(avctx, AV_LOG_ERROR, "H.264 10-bit profiles " 1187 "are not supported.\n"); 1188 return AVERROR_PATCHWELCOME; 1189 case FF_PROFILE_H264_HIGH_422: 1190 case FF_PROFILE_H264_HIGH_422_INTRA: 1191 case FF_PROFILE_H264_HIGH_444: 1192 case FF_PROFILE_H264_HIGH_444_PREDICTIVE: 1193 case FF_PROFILE_H264_HIGH_444_INTRA: 1194 case FF_PROFILE_H264_CAVLC_444: 1195 av_log(avctx, AV_LOG_ERROR, "H.264 non-4:2:0 profiles " 1196 "are not supported.\n"); 1197 return AVERROR_PATCHWELCOME; 1198 } 1199 1200 if (avctx->level != FF_LEVEL_UNKNOWN && avctx->level & ~0xff) { 1201 av_log(avctx, AV_LOG_ERROR, "Invalid level %d: must fit " 1202 "in 8-bit unsigned integer.\n", avctx->level); 1203 return AVERROR(EINVAL); 1204 } 1205 1206 ctx->desired_packed_headers = 1207 VA_ENC_PACKED_HEADER_SEQUENCE | // SPS and PPS. 1208 VA_ENC_PACKED_HEADER_SLICE | // Slice headers. 1209 VA_ENC_PACKED_HEADER_MISC; // SEI. 1210 1211 ctx->surface_width = FFALIGN(avctx->width, 16); 1212 ctx->surface_height = FFALIGN(avctx->height, 16); 1213 1214 ctx->slice_block_height = ctx->slice_block_width = 16; 1215 1216 if (priv->qp > 0) 1217 ctx->explicit_qp = priv->qp; 1218 1219 return ff_vaapi_encode_init(avctx); 1220} 1221 1222static av_cold int vaapi_encode_h264_close(AVCodecContext *avctx) 1223{ 1224 VAAPIEncodeH264Context *priv = avctx->priv_data; 1225 1226 ff_cbs_fragment_free(&priv->current_access_unit); 1227 ff_cbs_close(&priv->cbc); 1228 av_freep(&priv->sei_identifier_string); 1229 1230 return ff_vaapi_encode_close(avctx); 1231} 1232 1233#define OFFSET(x) offsetof(VAAPIEncodeH264Context, x) 1234#define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM) 1235static const AVOption vaapi_encode_h264_options[] = { 1236 VAAPI_ENCODE_COMMON_OPTIONS, 1237 VAAPI_ENCODE_RC_OPTIONS, 1238 1239 { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)", 1240 OFFSET(qp), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 52, FLAGS }, 1241 { "quality", "Set encode quality (trades off against speed, higher is faster)", 1242 OFFSET(quality), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, FLAGS }, 1243 { "coder", "Entropy coder type", 1244 OFFSET(coder), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, FLAGS, "coder" }, 1245 { "cavlc", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS, "coder" }, 1246 { "cabac", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, FLAGS, "coder" }, 1247 { "vlc", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS, "coder" }, 1248 { "ac", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, FLAGS, "coder" }, 1249 1250 { "aud", "Include AUD", 1251 OFFSET(aud), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, 1252 1253 { "sei", "Set SEI to include", 1254 OFFSET(sei), AV_OPT_TYPE_FLAGS, 1255 { .i64 = SEI_IDENTIFIER | SEI_TIMING | SEI_RECOVERY_POINT }, 1256 0, INT_MAX, FLAGS, "sei" }, 1257 { "identifier", "Include encoder version identifier", 1258 0, AV_OPT_TYPE_CONST, { .i64 = SEI_IDENTIFIER }, 1259 INT_MIN, INT_MAX, FLAGS, "sei" }, 1260 { "timing", "Include timing parameters (buffering_period and pic_timing)", 1261 0, AV_OPT_TYPE_CONST, { .i64 = SEI_TIMING }, 1262 INT_MIN, INT_MAX, FLAGS, "sei" }, 1263 { "recovery_point", "Include recovery points where appropriate", 1264 0, AV_OPT_TYPE_CONST, { .i64 = SEI_RECOVERY_POINT }, 1265 INT_MIN, INT_MAX, FLAGS, "sei" }, 1266 1267 { "profile", "Set profile (profile_idc and constraint_set*_flag)", 1268 OFFSET(profile), AV_OPT_TYPE_INT, 1269 { .i64 = FF_PROFILE_UNKNOWN }, FF_PROFILE_UNKNOWN, 0xffff, FLAGS, "profile" }, 1270 1271#define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \ 1272 { .i64 = value }, 0, 0, FLAGS, "profile" 1273 { PROFILE("constrained_baseline", FF_PROFILE_H264_CONSTRAINED_BASELINE) }, 1274 { PROFILE("main", FF_PROFILE_H264_MAIN) }, 1275 { PROFILE("high", FF_PROFILE_H264_HIGH) }, 1276#undef PROFILE 1277 1278 { "level", "Set level (level_idc)", 1279 OFFSET(level), AV_OPT_TYPE_INT, 1280 { .i64 = FF_LEVEL_UNKNOWN }, FF_LEVEL_UNKNOWN, 0xff, FLAGS, "level" }, 1281 1282#define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \ 1283 { .i64 = value }, 0, 0, FLAGS, "level" 1284 { LEVEL("1", 10) }, 1285 { LEVEL("1.1", 11) }, 1286 { LEVEL("1.2", 12) }, 1287 { LEVEL("1.3", 13) }, 1288 { LEVEL("2", 20) }, 1289 { LEVEL("2.1", 21) }, 1290 { LEVEL("2.2", 22) }, 1291 { LEVEL("3", 30) }, 1292 { LEVEL("3.1", 31) }, 1293 { LEVEL("3.2", 32) }, 1294 { LEVEL("4", 40) }, 1295 { LEVEL("4.1", 41) }, 1296 { LEVEL("4.2", 42) }, 1297 { LEVEL("5", 50) }, 1298 { LEVEL("5.1", 51) }, 1299 { LEVEL("5.2", 52) }, 1300 { LEVEL("6", 60) }, 1301 { LEVEL("6.1", 61) }, 1302 { LEVEL("6.2", 62) }, 1303#undef LEVEL 1304 1305 { NULL }, 1306}; 1307 1308static const FFCodecDefault vaapi_encode_h264_defaults[] = { 1309 { "b", "0" }, 1310 { "bf", "2" }, 1311 { "g", "120" }, 1312 { "i_qfactor", "1" }, 1313 { "i_qoffset", "0" }, 1314 { "b_qfactor", "6/5" }, 1315 { "b_qoffset", "0" }, 1316 { "qmin", "-1" }, 1317 { "qmax", "-1" }, 1318 { NULL }, 1319}; 1320 1321static const AVClass vaapi_encode_h264_class = { 1322 .class_name = "h264_vaapi", 1323 .item_name = av_default_item_name, 1324 .option = vaapi_encode_h264_options, 1325 .version = LIBAVUTIL_VERSION_INT, 1326}; 1327 1328const FFCodec ff_h264_vaapi_encoder = { 1329 .p.name = "h264_vaapi", 1330 .p.long_name = NULL_IF_CONFIG_SMALL("H.264/AVC (VAAPI)"), 1331 .p.type = AVMEDIA_TYPE_VIDEO, 1332 .p.id = AV_CODEC_ID_H264, 1333 .priv_data_size = sizeof(VAAPIEncodeH264Context), 1334 .init = &vaapi_encode_h264_init, 1335 FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet), 1336 .close = &vaapi_encode_h264_close, 1337 .p.priv_class = &vaapi_encode_h264_class, 1338 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | 1339 AV_CODEC_CAP_DR1, 1340 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, 1341 .defaults = vaapi_encode_h264_defaults, 1342 .p.pix_fmts = (const enum AVPixelFormat[]) { 1343 AV_PIX_FMT_VAAPI, 1344 AV_PIX_FMT_NONE, 1345 }, 1346 .hw_configs = ff_vaapi_encode_hw_configs, 1347 .p.wrapper_name = "vaapi", 1348}; 1349