[FFmpeg-devel] [PATCH 3/3] lavc/vaapi_encode_h265: respect "slices" option in h265 vaapi encoder
Jun Zhao
mypopydev at gmail.com
Mon Jul 30 14:42:40 EEST 2018
Enable multi-slice support in HEVC/H.265 vaapi encoder.
Signed-off-by: Wang, Yi A <yi.a.wang at intel.com>
Signed-off-by: Jun Zhao <jun.zhao at intel.com>
---
libavcodec/vaapi_encode_h265.c | 30 ++++++++++++++++++++++++------
1 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c
index bbba2b8..cfdbeae 100644
--- a/libavcodec/vaapi_encode_h265.c
+++ b/libavcodec/vaapi_encode_h265.c
@@ -618,6 +618,7 @@ static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx,
VAAPIEncodeH265Options *opt = ctx->codec_options;
VAEncPictureParameterBufferHEVC *vpic = pic->codec_picture_params;
int i;
+ int slices;
if (pic->type == PICTURE_TYPE_IDR) {
av_assert0(pic->display_order == pic->encode_order);
@@ -788,7 +789,17 @@ static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx,
av_assert0(0 && "invalid picture type");
}
- pic->nb_slices = 1;
+ slices = 1;
+ if (ctx->max_slices) {
+ if (avctx->slices <= FFMIN(ctx->max_slices, priv->ctu_height)) {
+ slices = FFMAX(avctx->slices, slices);
+ } else {
+ av_log(avctx, AV_LOG_ERROR, "The max slices number per frame "
+ "cannot more than %d.\n", FFMIN(ctx->max_slices, priv->ctu_height));
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ pic->nb_slices = slices;
return 0;
}
@@ -814,9 +825,8 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
sh->slice_pic_parameter_set_id = pps->pps_pic_parameter_set_id;
- // Currently we only support one slice per frame.
- sh->first_slice_segment_in_pic_flag = 1;
- sh->slice_segment_address = 0;
+ sh->first_slice_segment_in_pic_flag = !!(slice->index == 0);
+ sh->slice_segment_address = slice->index * priv->ctu_width * (priv->ctu_height / pic->nb_slices);
sh->slice_type = priv->slice_type;
@@ -906,7 +916,6 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
*vslice = (VAEncSliceParameterBufferHEVC) {
.slice_segment_address = sh->slice_segment_address,
- .num_ctu_in_slice = priv->ctu_width * priv->ctu_height,
.slice_type = sh->slice_type,
.slice_pic_parameter_set_id = sh->slice_pic_parameter_set_id,
@@ -927,7 +936,6 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
.slice_tc_offset_div2 = sh->slice_tc_offset_div2,
.slice_fields.bits = {
- .last_slice_of_pic_flag = 1,
.dependent_slice_segment_flag = sh->dependent_slice_segment_flag,
.colour_plane_id = sh->colour_plane_id,
.slice_temporal_mvp_enabled_flag =
@@ -945,6 +953,12 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
.collocated_from_l0_flag = sh->collocated_from_l0_flag,
},
};
+ if (slice->index == pic->nb_slices - 1) {
+ vslice->num_ctu_in_slice = priv->ctu_width * priv->ctu_height
+ - slice->index * priv->ctu_width * (priv->ctu_height / pic->nb_slices);
+ vslice->slice_fields.bits.last_slice_of_pic_flag = 1;
+ } else
+ vslice->num_ctu_in_slice = priv->ctu_width * (priv->ctu_height / pic->nb_slices);
for (i = 0; i < FF_ARRAY_ELEMS(vslice->ref_pic_list0); i++) {
vslice->ref_pic_list0[i].picture_id = VA_INVALID_ID;
@@ -1019,6 +1033,10 @@ static av_cold int vaapi_encode_h265_configure(AVCodecContext *avctx)
av_assert0(0 && "Invalid RC mode.");
}
+ if (!ctx->max_slices && avctx->slices > 0)
+ av_log(avctx, AV_LOG_WARNING, "The encode slice option is not "
+ "supported with the driver.\n");
+
return 0;
}
--
1.7.1
More information about the ffmpeg-devel
mailing list