X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fvaapi_encode_h264.c;h=a7f9a602533beb746204b748262db39bfc4434f8;hb=439fbb9c8b2a90e97c44c7c57245e01ca84c865d;hp=1d43e934ef0152a3d13aadea5294ee4b0ed294f0;hpb=17126f126838676f833fbf4cad8e4feaef2ecc17;p=ffmpeg diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index 1d43e934ef0..a7f9a602533 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -82,6 +82,7 @@ typedef struct VAAPIEncodeH264Context { CodedBitstreamFragment current_access_unit; int aud_needed; int sei_needed; + int sei_cbr_workaround_needed; } VAAPIEncodeH264Context; typedef struct VAAPIEncodeH264Options { @@ -92,6 +93,8 @@ typedef struct VAAPIEncodeH264Options { int coder; int aud; int sei; + int profile; + int level; } VAAPIEncodeH264Options; @@ -258,6 +261,19 @@ static int vaapi_encode_h264_write_extra_header(AVCodecContext *avctx, *type = VAEncPackedHeaderRawData; return 0; + +#if !CONFIG_VAAPI_1 + } else if (priv->sei_cbr_workaround_needed) { + // Insert a zero-length header using the old SEI type. This is + // required to avoid triggering broken behaviour on Intel platforms + // in CBR mode where an invalid SEI message is generated by the + // driver and inserted into the stream. + *data_len = 0; + *type = VAEncPackedHeaderH264_SEI; + priv->sei_cbr_workaround_needed = 0; + return 0; +#endif + } else { return AVERROR_EOF; } @@ -614,6 +630,10 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, if (opt->sei & SEI_IDENTIFIER && pic->encode_order == 0) priv->sei_needed = 1; +#if !CONFIG_VAAPI_1 + if (ctx->va_rc_mode == VA_RC_CBR) + priv->sei_cbr_workaround_needed = 1; +#endif if (opt->sei & SEI_TIMING) { memset(&priv->pic_timing, 0, sizeof(priv->pic_timing)); @@ -868,6 +888,11 @@ static av_cold int vaapi_encode_h264_init(AVCodecContext *avctx) ctx->codec = &vaapi_encode_type_h264; + if (avctx->profile == FF_PROFILE_UNKNOWN) + avctx->profile = opt->profile; + if (avctx->level == FF_LEVEL_UNKNOWN) + avctx->level = opt->level; + switch (avctx->profile) { case FF_PROFILE_H264_BASELINE: av_log(avctx, AV_LOG_WARNING, "H.264 baseline profile is not " @@ -992,12 +1017,49 @@ static const AVOption vaapi_encode_h264_options[] = { { "recovery_point", "Include recovery points where appropriate", 0, AV_OPT_TYPE_CONST, { .i64 = SEI_RECOVERY_POINT }, INT_MIN, INT_MAX, FLAGS, "sei" }, + + { "profile", "Set profile (profile_idc and constraint_set*_flag)", + OFFSET(profile), AV_OPT_TYPE_INT, + { .i64 = FF_PROFILE_H264_HIGH }, 0x0000, 0xffff, FLAGS, "profile" }, + +#define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \ + { .i64 = value }, 0, 0, FLAGS, "profile" + { PROFILE("constrained_baseline", FF_PROFILE_H264_CONSTRAINED_BASELINE) }, + { PROFILE("main", FF_PROFILE_H264_MAIN) }, + { PROFILE("high", FF_PROFILE_H264_HIGH) }, +#undef PROFILE + + { "level", "Set level (level_idc)", + OFFSET(level), AV_OPT_TYPE_INT, + { .i64 = 51 }, 0x00, 0xff, FLAGS, "level" }, + +#define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \ + { .i64 = value }, 0, 0, FLAGS, "level" + { LEVEL("1", 10) }, + { LEVEL("1.1", 11) }, + { LEVEL("1.2", 12) }, + { LEVEL("1.3", 13) }, + { LEVEL("2", 20) }, + { LEVEL("2.1", 21) }, + { LEVEL("2.2", 22) }, + { LEVEL("3", 30) }, + { LEVEL("3.1", 31) }, + { LEVEL("3.2", 32) }, + { LEVEL("4", 40) }, + { LEVEL("4.1", 41) }, + { LEVEL("4.2", 42) }, + { LEVEL("5", 50) }, + { LEVEL("5.1", 51) }, + { LEVEL("5.2", 52) }, + { LEVEL("6", 60) }, + { LEVEL("6.1", 61) }, + { LEVEL("6.2", 62) }, +#undef LEVEL + { NULL }, }; static const AVCodecDefault vaapi_encode_h264_defaults[] = { - { "profile", "100" }, - { "level", "51" }, { "b", "0" }, { "bf", "2" }, { "g", "120" }, @@ -1027,10 +1089,11 @@ AVCodec ff_h264_vaapi_encoder = { .encode2 = &ff_vaapi_encode2, .close = &vaapi_encode_h264_close, .priv_class = &vaapi_encode_h264_class, - .capabilities = AV_CODEC_CAP_DELAY, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE, .defaults = vaapi_encode_h264_defaults, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_VAAPI, AV_PIX_FMT_NONE, }, + .wrapper_name = "vaapi", };