From e7adf2250b437165bc30c3b277bfce50875a0909 Mon Sep 17 00:00:00 2001 From: Jun Zhao Date: Fri, 25 Aug 2017 15:56:51 +0800 Subject: [PATCH 1/5] vaapi_h265: Enable VBR mode To match vaapi_h264. From ffmpeg commit 385cafb07ac1e46433931ea9749a134efd7350be. Signed-off-by: Mark Thompson --- libavcodec/vaapi_encode_h265.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c index 477065e2ce..0e5958d531 100644 --- a/libavcodec/vaapi_encode_h265.c +++ b/libavcodec/vaapi_encode_h265.c @@ -839,13 +839,15 @@ static av_cold int vaapi_encode_h265_configure(AVCodecContext *avctx) "%d / %d / %d for IDR- / P- / B-frames.\n", priv->fixed_qp_idr, priv->fixed_qp_p, priv->fixed_qp_b); - } else if (ctx->va_rc_mode == VA_RC_CBR) { + } else if (ctx->va_rc_mode == VA_RC_CBR || + ctx->va_rc_mode == VA_RC_VBR) { // These still need to be set for pic_init_qp/slice_qp_delta. priv->fixed_qp_idr = 30; priv->fixed_qp_p = 30; priv->fixed_qp_b = 30; - av_log(avctx, AV_LOG_DEBUG, "Using constant-bitrate = %d bps.\n", + av_log(avctx, AV_LOG_DEBUG, "Using %s-bitrate = %d bps.\n", + ctx->va_rc_mode == VA_RC_CBR ? "constant" : "variable", avctx->bit_rate); } else { @@ -905,9 +907,12 @@ static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx) } ctx->va_entrypoint = VAEntrypointEncSlice; - if (avctx->bit_rate > 0) - ctx->va_rc_mode = VA_RC_CBR; - else + if (avctx->bit_rate > 0) { + if (avctx->rc_max_rate == avctx->bit_rate) + ctx->va_rc_mode = VA_RC_CBR; + else + ctx->va_rc_mode = VA_RC_VBR; + } else ctx->va_rc_mode = VA_RC_CQP; ctx->va_packed_headers = From 4b57f064477cd39e7236897bbbb90b909e6deed2 Mon Sep 17 00:00:00 2001 From: Jun Zhao Date: Tue, 24 Oct 2017 13:25:21 +0800 Subject: [PATCH 2/5] vaapi_h264: Fix VUI max_dec_frame_buffering This should refer to the existing SPS structure, not the VAAPI sequence parameter buffer (which is not yet initialised). From ffmpeg commit f31478ba1472afe5c1eed60f219ae331816425a2. Signed-off-by: Mark Thompson --- libavcodec/vaapi_encode_h264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index 03605b05b2..e6a166698b 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -453,7 +453,7 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) sps->vui.log2_max_mv_length_horizontal = 16; sps->vui.log2_max_mv_length_vertical = 16; sps->vui.max_num_reorder_frames = (ctx->b_per_p > 0); - sps->vui.max_dec_frame_buffering = vseq->max_num_ref_frames; + sps->vui.max_dec_frame_buffering = sps->max_num_ref_frames; pps->nal_unit_header.nal_ref_idc = 3; pps->nal_unit_header.nal_unit_type = H264_NAL_PPS; From e171022c24c42b1e88a51bb3b4c27f13c87c85cb Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Thu, 9 Nov 2017 01:04:44 +0000 Subject: [PATCH 3/5] vaapi: Make the decode profile matching more explicit Also fixes a bug where it could attempt to decode with an unsupported codec if allow-profile-mismatch was set. --- libavcodec/vaapi_decode.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c index 02304191ff..cc79875ef1 100644 --- a/libavcodec/vaapi_decode.c +++ b/libavcodec/vaapi_decode.c @@ -284,8 +284,8 @@ static int vaapi_decode_make_config(AVCodecContext *avctx, VAStatus vas; int err, i, j; const AVCodecDescriptor *codec_desc; - VAProfile profile, *profile_list = NULL; - int profile_count, exact_match, alt_profile; + VAProfile *profile_list = NULL, matched_va_profile; + int profile_count, exact_match, matched_ff_profile; const AVPixFmtDescriptor *sw_desc, *desc; AVHWDeviceContext *device = (AVHWDeviceContext*)device_ref->data; @@ -314,7 +314,7 @@ static int vaapi_decode_make_config(AVCodecContext *avctx, goto fail; } - profile = VAProfileNone; + matched_va_profile = VAProfileNone; exact_match = 0; for (i = 0; i < FF_ARRAY_ELEMS(vaapi_profile_map); i++) { @@ -324,22 +324,22 @@ static int vaapi_decode_make_config(AVCodecContext *avctx, if (avctx->profile == vaapi_profile_map[i].codec_profile || vaapi_profile_map[i].codec_profile == FF_PROFILE_UNKNOWN) profile_match = 1; - profile = vaapi_profile_map[i].va_profile; for (j = 0; j < profile_count; j++) { - if (profile == profile_list[j]) { + if (vaapi_profile_map[i].va_profile == profile_list[j]) { exact_match = profile_match; break; } } if (j < profile_count) { + matched_va_profile = vaapi_profile_map[i].va_profile; + matched_ff_profile = vaapi_profile_map[i].codec_profile; if (exact_match) break; - alt_profile = vaapi_profile_map[i].codec_profile; } } av_freep(&profile_list); - if (profile == VAProfileNone) { + if (matched_va_profile == VAProfileNone) { av_log(avctx, AV_LOG_ERROR, "No support for codec %s " "profile %d.\n", codec_desc->name, avctx->profile); err = AVERROR(ENOSYS); @@ -353,7 +353,7 @@ static int vaapi_decode_make_config(AVCodecContext *avctx, codec_desc->name, avctx->profile); av_log(avctx, AV_LOG_WARNING, "Using possibly-" "incompatible profile %d instead.\n", - alt_profile); + matched_ff_profile); } else { av_log(avctx, AV_LOG_VERBOSE, "Codec %s profile %d not " "supported for hardware decode.\n", @@ -363,7 +363,7 @@ static int vaapi_decode_make_config(AVCodecContext *avctx, } } - vas = vaCreateConfig(hwctx->display, profile, + vas = vaCreateConfig(hwctx->display, matched_va_profile, VAEntrypointVLD, NULL, 0, va_config); if (vas != VA_STATUS_SUCCESS) { From 6679654efe15af7156a94e9abc754098dfccd10e Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Wed, 29 Nov 2017 21:31:11 +0000 Subject: [PATCH 4/5] vaapi_h264: Add named options for setting profile and level --- libavcodec/vaapi_encode_h264.c | 48 ++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index e6a166698b..6b47d932b6 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -91,6 +91,8 @@ typedef struct VAAPIEncodeH264Options { int low_power; int aud; int sei; + int profile; + int level; } VAAPIEncodeH264Options; @@ -882,6 +884,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 " @@ -995,12 +1002,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" }, From 3ff8fbbf5a7bc40c09db74d4952364997fd3c611 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Wed, 29 Nov 2017 21:31:53 +0000 Subject: [PATCH 5/5] vaapi_h265: Add named options for setting profile and level Also fixes the default, which previously contained a nonsense value. --- libavcodec/vaapi_encode_h265.c | 44 +++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c index 0e5958d531..8fa277bf94 100644 --- a/libavcodec/vaapi_encode_h265.c +++ b/libavcodec/vaapi_encode_h265.c @@ -63,6 +63,8 @@ typedef struct VAAPIEncodeH265Context { typedef struct VAAPIEncodeH265Options { int qp; int aud; + int profile; + int level; } VAAPIEncodeH265Options; @@ -880,10 +882,17 @@ static const VAAPIEncodeType vaapi_encode_type_h265 = { static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx) { - VAAPIEncodeContext *ctx = avctx->priv_data; + VAAPIEncodeContext *ctx = avctx->priv_data; + VAAPIEncodeH265Options *opt = + (VAAPIEncodeH265Options*)ctx->codec_options_data; ctx->codec = &vaapi_encode_type_h265; + 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_HEVC_MAIN: case FF_PROFILE_UNKNOWN: @@ -946,12 +955,41 @@ static const AVOption vaapi_encode_h265_options[] = { { "aud", "Include AUD", OFFSET(aud), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS }, + { "profile", "Set profile (general_profile_idc)", + OFFSET(profile), AV_OPT_TYPE_INT, + { .i64 = FF_PROFILE_HEVC_MAIN }, 0x00, 0xff, FLAGS, "profile" }, + +#define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \ + { .i64 = value }, 0, 0, FLAGS, "profile" + { PROFILE("main", FF_PROFILE_HEVC_MAIN) }, + { PROFILE("main10", FF_PROFILE_HEVC_MAIN_10) }, +#undef PROFILE + + { "level", "Set level (general_level_idc)", + OFFSET(level), AV_OPT_TYPE_INT, + { .i64 = 153 }, 0x00, 0xff, FLAGS, "level" }, + +#define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \ + { .i64 = value }, 0, 0, FLAGS, "level" + { LEVEL("1", 30) }, + { LEVEL("2", 60) }, + { LEVEL("2.1", 63) }, + { LEVEL("3", 90) }, + { LEVEL("3.1", 93) }, + { LEVEL("4", 120) }, + { LEVEL("4.1", 123) }, + { LEVEL("5", 150) }, + { LEVEL("5.1", 153) }, + { LEVEL("5.2", 156) }, + { LEVEL("6", 180) }, + { LEVEL("6.1", 183) }, + { LEVEL("6.2", 186) }, +#undef LEVEL + { NULL }, }; static const AVCodecDefault vaapi_encode_h265_defaults[] = { - { "profile", "1" }, - { "level", "51" }, { "b", "0" }, { "bf", "2" }, { "g", "120" },