diff options
author | He Junyan <junyan.he@hotmail.com> | 2020-03-05 16:21:24 +0800 |
---|---|---|
committer | He Junyan <junyan.he@hotmail.com> | 2020-06-05 19:27:26 +0800 |
commit | bc1c97c7550165b05993e344a2247be2f9497884 (patch) | |
tree | 2f96fc102b606bffd3c38bb355b7f4cc5d023412 | |
parent | 6c76e81cb6d08d54ae57b112c46541b6116ea9d3 (diff) |
libs: encoder: h265: extract slice creation from add_slice_headers
extract slice creation details from add_slice_headers, and let the
add_slice_headers just focuses on calculating slice start address
and CTU number.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/-/merge_requests/294>
-rw-r--r-- | gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 180 |
1 files changed, 99 insertions, 81 deletions
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index c5712efe..8c0de32b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1811,6 +1811,97 @@ fill_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, return TRUE; } +static GstVaapiEncSlice * +create_and_fill_one_slice (GstVaapiEncoderH265 * encoder, + GstVaapiEncPicture * picture, + GstVaapiEncoderH265Ref ** reflist_0, guint reflist_0_count, + GstVaapiEncoderH265Ref ** reflist_1, guint reflist_1_count) +{ + VAEncSliceParameterBufferHEVC *slice_param; + GstVaapiEncSlice *slice; + guint i_ref; + + slice = GST_VAAPI_ENC_SLICE_NEW (HEVC, encoder); + g_assert (slice && slice->param_id != VA_INVALID_ID); + slice_param = slice->param; + memset (slice_param, 0, sizeof (VAEncSliceParameterBufferHEVC)); + + slice_param->slice_type = h265_get_slice_type (picture->type); + if (encoder->low_delay_b && slice_param->slice_type == GST_H265_P_SLICE) { + slice_param->slice_type = GST_H265_B_SLICE; + } + slice_param->slice_pic_parameter_set_id = 0; + + slice_param->slice_fields.bits.num_ref_idx_active_override_flag = + reflist_0_count || reflist_1_count; + if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0) + slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1; + else + slice_param->num_ref_idx_l0_active_minus1 = 0; + if (picture->type == GST_VAAPI_PICTURE_TYPE_B && reflist_1_count > 0) + slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1; + else + slice_param->num_ref_idx_l1_active_minus1 = 0; + if (picture->type == GST_VAAPI_PICTURE_TYPE_P && encoder->low_delay_b) + slice_param->num_ref_idx_l1_active_minus1 = + slice_param->num_ref_idx_l0_active_minus1; + + i_ref = 0; + if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { + for (; i_ref < reflist_0_count; ++i_ref) { + slice_param->ref_pic_list0[i_ref].picture_id = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic); + slice_param->ref_pic_list0[i_ref].pic_order_cnt = reflist_0[i_ref]->poc; + } + } + for (; i_ref < G_N_ELEMENTS (slice_param->ref_pic_list0); ++i_ref) { + slice_param->ref_pic_list0[i_ref].picture_id = VA_INVALID_SURFACE; + slice_param->ref_pic_list0[i_ref].flags = VA_PICTURE_HEVC_INVALID; + } + + i_ref = 0; + if (picture->type == GST_VAAPI_PICTURE_TYPE_B) { + for (; i_ref < reflist_1_count; ++i_ref) { + slice_param->ref_pic_list1[i_ref].picture_id = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic); + slice_param->ref_pic_list1[i_ref].pic_order_cnt = reflist_1[i_ref]->poc; + } + } else if (picture->type == GST_VAAPI_PICTURE_TYPE_P && encoder->low_delay_b) { + for (; i_ref < reflist_0_count; ++i_ref) { + slice_param->ref_pic_list1[i_ref].picture_id = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic); + slice_param->ref_pic_list1[i_ref].pic_order_cnt = reflist_0[i_ref]->poc; + } + } + for (; i_ref < G_N_ELEMENTS (slice_param->ref_pic_list1); ++i_ref) { + slice_param->ref_pic_list1[i_ref].picture_id = VA_INVALID_SURFACE; + slice_param->ref_pic_list1[i_ref].flags = VA_PICTURE_HEVC_INVALID; + } + + slice_param->max_num_merge_cand = 5; /* MaxNumMergeCand */ + slice_param->slice_qp_delta = encoder->qp_i - encoder->init_qp; + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) { + if (picture->type == GST_VAAPI_PICTURE_TYPE_P) { + slice_param->slice_qp_delta += encoder->qp_ip; + } else if (picture->type == GST_VAAPI_PICTURE_TYPE_B) { + slice_param->slice_qp_delta += encoder->qp_ib; + } + if ((gint) encoder->init_qp + slice_param->slice_qp_delta < + (gint) encoder->min_qp) { + slice_param->slice_qp_delta = encoder->min_qp - encoder->init_qp; + } + if ((gint) encoder->init_qp + slice_param->slice_qp_delta > + (gint) encoder->max_qp) { + slice_param->slice_qp_delta = encoder->max_qp - encoder->init_qp; + } + } + + slice_param->slice_fields.bits.slice_loop_filter_across_slices_enabled_flag = + TRUE; + + return slice; +} + /* Adds slice headers to picture */ static gboolean add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, @@ -1823,7 +1914,7 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, guint ctu_size; guint ctu_width_round_factor; guint last_ctu_index; - guint i_slice, i_ref; + guint i_slice; g_assert (picture); @@ -1842,6 +1933,10 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, --slice_mod_ctus; } + slice = create_and_fill_one_slice (encoder, picture, + reflist_0, reflist_0_count, reflist_1, reflist_1_count); + slice_param = slice->param; + /* Work-around for satisfying the VA-Intel driver. * The driver only support multi slice begin from row start address */ ctu_width_round_factor = @@ -1850,11 +1945,6 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, if ((last_ctu_index + cur_slice_ctus) > ctu_size) cur_slice_ctus = ctu_size - last_ctu_index; - slice = GST_VAAPI_ENC_SLICE_NEW (HEVC, encoder); - g_assert (slice && slice->param_id != VA_INVALID_ID); - slice_param = slice->param; - - memset (slice_param, 0, sizeof (VAEncSliceParameterBufferHEVC)); if (i_slice == 0) { encoder->first_slice_segment_in_pic_flag = TRUE; slice_param->slice_segment_address = 0; @@ -1863,79 +1953,6 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, slice_param->slice_segment_address = last_ctu_index; } slice_param->num_ctu_in_slice = cur_slice_ctus; - slice_param->slice_type = h265_get_slice_type (picture->type); - if (encoder->low_delay_b && slice_param->slice_type == GST_H265_P_SLICE) { - slice_param->slice_type = GST_H265_B_SLICE; - } - slice_param->slice_pic_parameter_set_id = 0; - - slice_param->slice_fields.bits.num_ref_idx_active_override_flag = - reflist_0_count || reflist_1_count; - if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0) - slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1; - else - slice_param->num_ref_idx_l0_active_minus1 = 0; - if (picture->type == GST_VAAPI_PICTURE_TYPE_B && reflist_1_count > 0) - slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1; - else - slice_param->num_ref_idx_l1_active_minus1 = 0; - if (picture->type == GST_VAAPI_PICTURE_TYPE_P && encoder->low_delay_b) - slice_param->num_ref_idx_l1_active_minus1 = - slice_param->num_ref_idx_l0_active_minus1; - - i_ref = 0; - if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { - for (; i_ref < reflist_0_count; ++i_ref) { - slice_param->ref_pic_list0[i_ref].picture_id = - GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic); - slice_param->ref_pic_list0[i_ref].pic_order_cnt = reflist_0[i_ref]->poc; - } - } - for (; i_ref < G_N_ELEMENTS (slice_param->ref_pic_list0); ++i_ref) { - slice_param->ref_pic_list0[i_ref].picture_id = VA_INVALID_SURFACE; - slice_param->ref_pic_list0[i_ref].flags = VA_PICTURE_HEVC_INVALID; - } - - i_ref = 0; - if (picture->type == GST_VAAPI_PICTURE_TYPE_B) { - for (; i_ref < reflist_1_count; ++i_ref) { - slice_param->ref_pic_list1[i_ref].picture_id = - GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic); - slice_param->ref_pic_list1[i_ref].pic_order_cnt = reflist_1[i_ref]->poc; - } - } else if (picture->type == GST_VAAPI_PICTURE_TYPE_P - && encoder->low_delay_b) { - for (; i_ref < reflist_0_count; ++i_ref) { - slice_param->ref_pic_list1[i_ref].picture_id = - GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic); - slice_param->ref_pic_list1[i_ref].pic_order_cnt = reflist_0[i_ref]->poc; - } - } - for (; i_ref < G_N_ELEMENTS (slice_param->ref_pic_list1); ++i_ref) { - slice_param->ref_pic_list1[i_ref].picture_id = VA_INVALID_SURFACE; - slice_param->ref_pic_list1[i_ref].flags = VA_PICTURE_HEVC_INVALID; - } - - slice_param->max_num_merge_cand = 5; /* MaxNumMergeCand */ - slice_param->slice_qp_delta = encoder->qp_i - encoder->init_qp; - if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) { - if (picture->type == GST_VAAPI_PICTURE_TYPE_P) { - slice_param->slice_qp_delta += encoder->qp_ip; - } else if (picture->type == GST_VAAPI_PICTURE_TYPE_B) { - slice_param->slice_qp_delta += encoder->qp_ib; - } - if ((gint) encoder->init_qp + slice_param->slice_qp_delta < - (gint) encoder->min_qp) { - slice_param->slice_qp_delta = encoder->min_qp - encoder->init_qp; - } - if ((gint) encoder->init_qp + slice_param->slice_qp_delta > - (gint) encoder->max_qp) { - slice_param->slice_qp_delta = encoder->max_qp - encoder->init_qp; - } - } - - slice_param->slice_fields.bits. - slice_loop_filter_across_slices_enabled_flag = TRUE; /* set calculation for next slice */ last_ctu_index += cur_slice_ctus; @@ -1951,10 +1968,11 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, gst_vaapi_enc_picture_add_slice (picture, slice); gst_vaapi_codec_object_replace (&slice, NULL); } + if (i_slice < encoder->num_slices) GST_WARNING - ("Using less number of slices than requested, Number of slices per pictures is %d", - i_slice); + ("Using less number of slices than requested, Number of slices per" + " pictures is %d", i_slice); g_assert (last_ctu_index == ctu_size); return TRUE; |