[FFmpeg-devel] [PATCH, RFC] lavc/vaapi_encode_h265: add support for low power mode for HEVC encode
Linjie Fu
linjie.fu at intel.com
Thu Mar 5 09:41:00 EET 2020
Enable hevc_vaapi vdenc:
- media-driver require CTU size must be set as 64x64 at low power mode
- cu_qp_delta_enabled_flag should be enabled for low power mode
- diff_cu_qp_delta_depth == log2_diff_max_min_luma_coding_block_size
- low delay B to replace P frame
- same ref_pic_list0/ref_pic_list1
Signed-off-by: Linjie Fu <linjie.fu at intel.com>
---
This should be rebased after the encoding query is supported in [1] and
low delay B support [2] for HEVC in media driver.
Sent out and request for comments.
[1] https://patchwork.ffmpeg.org/project/ffmpeg/patch/20200305002528.11418-3-sw@jkqxz.net/
[2] https://github.com/intel/libva/commit/f094de317b4f498b57d47d8b0823a2a24cb125e1
libavcodec/vaapi_encode_h265.c | 34 ++++++++++++++++++++++++++++------
1 file changed, 28 insertions(+), 6 deletions(-)
diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c
index 538862a..12f0e6f 100644
--- a/libavcodec/vaapi_encode_h265.c
+++ b/libavcodec/vaapi_encode_h265.c
@@ -437,9 +437,12 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
// These have to come from the capabilities of the encoder. We have no
// way to query them, so just hardcode parameters which work on the Intel
// driver.
- // CTB size from 8x8 to 32x32.
+ // CTB size from 8x8 to 32x32. (64x64 when using low power mode for hw limitation)
sps->log2_min_luma_coding_block_size_minus3 = 0;
- sps->log2_diff_max_min_luma_coding_block_size = 2;
+ if (ctx->low_power)
+ sps->log2_diff_max_min_luma_coding_block_size = 3;
+ else
+ sps->log2_diff_max_min_luma_coding_block_size = 2;
// Transform size from 4x4 to 32x32.
sps->log2_min_luma_transform_block_size_minus2 = 0;
sps->log2_diff_max_min_luma_transform_block_size = 3;
@@ -553,8 +556,10 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
pps->init_qp_minus26 = priv->fixed_qp_idr - 26;
- pps->cu_qp_delta_enabled_flag = (ctx->va_rc_mode != VA_RC_CQP);
- pps->diff_cu_qp_delta_depth = 0;
+ // driver requires enablement of cu_qp_delta_enabled_flag for low power mode encoding
+ pps->cu_qp_delta_enabled_flag = (ctx->va_rc_mode != VA_RC_CQP || ctx->low_power);
+ pps->diff_cu_qp_delta_depth = pps->cu_qp_delta_enabled_flag && ctx->low_power ?
+ sps->log2_diff_max_min_luma_coding_block_size : 0;
pps->pps_loop_filter_across_slices_enabled_flag = 1;
@@ -873,6 +878,7 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
VAAPIEncodeSlice *slice)
{
VAAPIEncodeH265Context *priv = avctx->priv_data;
+ VAAPIEncodeContext *ctx = avctx->priv_data;
VAAPIEncodeH265Picture *hpic = pic->priv_data;
const H265RawSPS *sps = &priv->raw_sps;
const H265RawPPS *pps = &priv->raw_pps;
@@ -893,6 +899,9 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
sh->slice_segment_address = slice->block_start;
sh->slice_type = hpic->slice_type;
+ // driver requires low delay B frame in low power mode
+ if (sh->slice_type == HEVC_SLICE_P && ctx->low_power)
+ 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;
@@ -1059,6 +1068,16 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
vslice->ref_pic_list1[0] = vpic->reference_frames[1];
}
+ // Driver requires low delay B frame and matched ref_pic_list0/1[]
+ // for low power mode
+ if (pic->type == PICTURE_TYPE_P && ctx->low_power) {
+ vslice->slice_type = HEVC_SLICE_B;
+ for (i = 0; i < FF_ARRAY_ELEMS(vslice->ref_pic_list0); i++) {
+ vslice->ref_pic_list1[i].picture_id = vslice->ref_pic_list0[i].picture_id;
+ vslice->ref_pic_list1[i].flags = vslice->ref_pic_list0[i].flags;
+ }
+ }
+
return 0;
}
@@ -1175,8 +1194,11 @@ static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx)
ctx->surface_width = FFALIGN(avctx->width, 16);
ctx->surface_height = FFALIGN(avctx->height, 16);
- // CTU size is currently hard-coded to 32.
- ctx->slice_block_width = ctx->slice_block_height = 32;
+ // CTU size is currently hard-coded to 32. (64 x 64 when using low power mode)
+ if (ctx->low_power)
+ ctx->slice_block_width = ctx->slice_block_height = 64;
+ else
+ ctx->slice_block_width = ctx->slice_block_height = 32;
if (priv->qp > 0)
ctx->explicit_qp = priv->qp;
--
2.7.4
More information about the ffmpeg-devel
mailing list