Allow user to choose between I/P/B frames: - normal Ordinary IB..BPB..B GOP structure. - low delay B-frames: Allows forward-predict only for all B frames, L0 == L1, supported on ICL+ platforms, required by VDENC(low_power). - reference B-frames: Convert P-frames to low delay B-frames, normal B frames still have 2 different ref_lists and allow bi-prediction.
Low delay B: <http://what-when-how.com/Tutorial/topic-397pct9eq3/High-Efficiency-Video-Coding-HEVC-288.html> There is an on-going work in libva and media-driver to add querys support for low delay b, would add it once it's ready: https://github.com/intel/libva/pull/220 https://github.com/intel/libva/pull/364 https://github.com/intel/media-driver/issues/721 Signed-off-by: Linjie Fu <linjie...@intel.com> --- Further step for low delay B would be refining the reference management to enable support for more forward-references in same ref_list. doc/encoders.texi | 16 ++++++++++++++++ libavcodec/vaapi_encode.c | 20 +++++++++++++++----- libavcodec/vaapi_encode.h | 1 + libavcodec/vaapi_encode_h265.c | 32 +++++++++++++++++++++++++++++++- 4 files changed, 63 insertions(+), 6 deletions(-) diff --git a/doc/encoders.texi b/doc/encoders.texi index e23b6b3..1fb5ecf 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -3089,6 +3089,22 @@ Some combination of the following values: Include HDR metadata if the input frames have it (@emph{mastering_display_colour_volume} and @emph{content_light_level} messages). + +@item b_strategy +Allow user to choose between I/P/B frames and specify the type of B-frames. +@table @samp +@item normal +Normal IBBPBB strategy. + +@item low_delay_b +Allows forward-predict only for all B frames, ref_list0 equals to ref_list1, +supported on ICL+ platforms, required by VDENC(low_power). + +@item ref_b +Convert P-frames to low delay B-frames as references, while normal B frames +still have 2 different ref_lists and allow bi-prediction. +@end table + @end table @end table diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index 8ff720e..ea7efb6 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -1792,15 +1792,25 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx) "reference frames.\n"); return AVERROR(EINVAL); } else if (!(ctx->codec->flags & FLAG_B_PICTURES) || - ref_l1 < 1 || avctx->max_b_frames < 1) { - av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames " - "(supported references: %d / %d).\n", ref_l0, ref_l1); + ref_l1 < 1 || avctx->max_b_frames < 1 || + ctx->b_frame_strategy == 1) { + if (ctx->b_frame_strategy == 1) + av_log(avctx, AV_LOG_VERBOSE, "Using intra and B -frames " + "(low delay) (supported references: %d / %d).\n", + ref_l0, ref_l1); + else + av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames " + "(supported references: %d / %d).\n", ref_l0, ref_l1); ctx->gop_size = avctx->gop_size; ctx->p_per_i = INT_MAX; ctx->b_per_p = 0; } else { - av_log(avctx, AV_LOG_VERBOSE, "Using intra, P- and B-frames " - "(supported references: %d / %d).\n", ref_l0, ref_l1); + if (ctx->b_frame_strategy == 2) + av_log(avctx, AV_LOG_VERBOSE, "Using intra, P- and B-frames " + "(supported references: %d / %d).\n", ref_l0, ref_l1); + else + av_log(avctx, AV_LOG_VERBOSE, "Using intra, P- and B-frames " + "(supported references: %d / %d).\n", ref_l0, ref_l1); ctx->gop_size = avctx->gop_size; ctx->p_per_i = INT_MAX; ctx->b_per_p = avctx->max_b_frames; diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h index b9a3def..1feca6c 100644 --- a/libavcodec/vaapi_encode.h +++ b/libavcodec/vaapi_encode.h @@ -310,6 +310,7 @@ typedef struct VAAPIEncodeContext { int idr_counter; int gop_counter; int end_of_stream; + int b_frame_strategy; // Whether the driver supports ROI at all. int roi_allowed; diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c index 97dc5a7..cecde73 100644 --- a/libavcodec/vaapi_encode_h265.c +++ b/libavcodec/vaapi_encode_h265.c @@ -62,6 +62,7 @@ typedef struct VAAPIEncodeH265Context { int tier; int level; int sei; + int b_frame_strategy; // Derived settings. int fixed_qp_idr; @@ -894,6 +895,9 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx, sh->slice_type = hpic->slice_type; + if (sh->slice_type == HEVC_SLICE_P && priv->b_frame_strategy) + sh->slice_type = HEVC_SLICE_B; + sh->slice_pic_order_cnt_lsb = hpic->pic_order_cnt & (1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4)) - 1; @@ -1052,10 +1056,13 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx, av_assert0(pic->type == PICTURE_TYPE_P || pic->type == PICTURE_TYPE_B); vslice->ref_pic_list0[0] = vpic->reference_frames[0]; + if (priv->b_frame_strategy == 1 && pic->type == PICTURE_TYPE_P) + // Reference for low delay B-frame, L0 == L1 + vslice->ref_pic_list1[0] = vpic->reference_frames[0]; } if (pic->nb_refs >= 2) { - // Forward reference for B-frame. av_assert0(pic->type == PICTURE_TYPE_B); + // Forward reference for B-frame. vslice->ref_pic_list1[0] = vpic->reference_frames[1]; } @@ -1181,6 +1188,21 @@ static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx) if (priv->qp > 0) ctx->explicit_qp = priv->qp; + // Low delay B-frames is required for low power encoding. + if (ctx->low_power && priv->b_frame_strategy != 1) { + priv->b_frame_strategy = 1; + av_log(avctx, AV_LOG_WARNING, "Low delay B-frames required " + "for low power encoding.\n"); + } + + if (priv->b_frame_strategy) { + ctx->b_frame_strategy = priv->b_frame_strategy; + if (ctx->b_frame_strategy == 1) + av_log(avctx, AV_LOG_VERBOSE, "Low delay B-frames enabled.\n"); + else + av_log(avctx, AV_LOG_VERBOSE, "Reference B-frames enabled.\n"); + } + return ff_vaapi_encode_init(avctx); } @@ -1256,6 +1278,14 @@ static const AVOption vaapi_encode_h265_options[] = { 0, AV_OPT_TYPE_CONST, { .i64 = SEI_MASTERING_DISPLAY | SEI_CONTENT_LIGHT_LEVEL }, INT_MIN, INT_MAX, FLAGS, "sei" }, + { "b_strategy", "Strategy to choose between I/P/B-frames", + OFFSET(b_frame_strategy), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, FLAGS, "b_strategy" }, + { "normal", "Normal IB..BPB..B strategy", + 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS, "b_strategy" }, + { "low_delay_b", "Use low delay B-frames with forward-prediction only", + 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, FLAGS, "b_strategy" }, + { "ref_b", "Only convert P-frames to low delay B-frames as references", + 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, FLAGS, "b_strategy" }, { NULL }, }; -- 2.7.4 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".