mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 16:26:39 +00:00
encoder: hevc: fix bug in multi slice encoding.
This is a work-around for satisfying the VA-Intel driver. The driver only support slices begin from CTU row start address. Multi-Slice encoding also requires a fix in va-intel-driver: http://lists.freedesktop.org/archives/libva/2015-May/003351.html https://bugzilla.gnome.org/show_bug.cgi?id=749854 Signed-off-by: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
This commit is contained in:
parent
5abd2b90b6
commit
55775c6203
1 changed files with 22 additions and 5 deletions
|
@ -1588,6 +1588,7 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture,
|
||||||
GstVaapiEncSlice *slice;
|
GstVaapiEncSlice *slice;
|
||||||
guint slice_of_ctus, slice_mod_ctus, cur_slice_ctus;
|
guint slice_of_ctus, slice_mod_ctus, cur_slice_ctus;
|
||||||
guint ctu_size;
|
guint ctu_size;
|
||||||
|
guint ctu_width_round_factor;
|
||||||
guint last_ctu_index;
|
guint last_ctu_index;
|
||||||
guint i_slice, i_ref;
|
guint i_slice, i_ref;
|
||||||
|
|
||||||
|
@ -1599,12 +1600,23 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture,
|
||||||
slice_of_ctus = ctu_size / encoder->num_slices;
|
slice_of_ctus = ctu_size / encoder->num_slices;
|
||||||
slice_mod_ctus = ctu_size % encoder->num_slices;
|
slice_mod_ctus = ctu_size % encoder->num_slices;
|
||||||
last_ctu_index = 0;
|
last_ctu_index = 0;
|
||||||
for (i_slice = 0; i_slice < encoder->num_slices; ++i_slice) {
|
|
||||||
|
for (i_slice = 0;
|
||||||
|
i_slice < encoder->num_slices && (last_ctu_index < ctu_size); ++i_slice) {
|
||||||
cur_slice_ctus = slice_of_ctus;
|
cur_slice_ctus = slice_of_ctus;
|
||||||
if (slice_mod_ctus) {
|
if (slice_mod_ctus) {
|
||||||
++cur_slice_ctus;
|
++cur_slice_ctus;
|
||||||
--slice_mod_ctus;
|
--slice_mod_ctus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Work-around for satisfying the VA-Intel driver.
|
||||||
|
* The driver only support multi slice begin from row start address */
|
||||||
|
ctu_width_round_factor =
|
||||||
|
encoder->ctu_width - (cur_slice_ctus % encoder->ctu_width);
|
||||||
|
cur_slice_ctus += ctu_width_round_factor;
|
||||||
|
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);
|
slice = GST_VAAPI_ENC_SLICE_NEW (HEVC, encoder);
|
||||||
g_assert (slice && slice->param_id != VA_INVALID_ID);
|
g_assert (slice && slice->param_id != VA_INVALID_ID);
|
||||||
slice_param = slice->param;
|
slice_param = slice->param;
|
||||||
|
@ -1664,14 +1676,16 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture,
|
||||||
slice_param->slice_qp_delta = encoder->init_qp - encoder->min_qp;
|
slice_param->slice_qp_delta = encoder->init_qp - encoder->min_qp;
|
||||||
|
|
||||||
slice_param->slice_fields.value = 0;
|
slice_param->slice_fields.value = 0;
|
||||||
if (i_slice == encoder->num_slices - 1)
|
|
||||||
slice_param->slice_fields.bits.last_slice_of_pic_flag = 1;
|
|
||||||
|
|
||||||
slice_param->slice_fields.
|
slice_param->slice_fields.
|
||||||
bits.slice_loop_filter_across_slices_enabled_flag = TRUE;
|
bits.slice_loop_filter_across_slices_enabled_flag = TRUE;
|
||||||
|
|
||||||
/* set calculation for next slice */
|
/* set calculation for next slice */
|
||||||
last_ctu_index += cur_slice_ctus;
|
last_ctu_index += cur_slice_ctus;
|
||||||
|
|
||||||
|
if ((i_slice == encoder->num_slices - 1) || (last_ctu_index == ctu_size))
|
||||||
|
slice_param->slice_fields.bits.last_slice_of_pic_flag = 1;
|
||||||
|
|
||||||
if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) &
|
if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) &
|
||||||
VAEncPackedHeaderHEVC_Slice)
|
VAEncPackedHeaderHEVC_Slice)
|
||||||
&& !add_packed_slice_header (encoder, picture, slice))
|
&& !add_packed_slice_header (encoder, picture, slice))
|
||||||
|
@ -1680,7 +1694,12 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture,
|
||||||
gst_vaapi_enc_picture_add_slice (picture, slice);
|
gst_vaapi_enc_picture_add_slice (picture, slice);
|
||||||
gst_vaapi_codec_object_replace (&slice, NULL);
|
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);
|
||||||
g_assert (last_ctu_index == ctu_size);
|
g_assert (last_ctu_index == ctu_size);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
error_create_packed_slice_hdr:
|
error_create_packed_slice_hdr:
|
||||||
|
@ -2387,8 +2406,6 @@ gst_vaapi_encoder_h265_set_property (GstVaapiEncoder * base_encoder,
|
||||||
break;
|
break;
|
||||||
case GST_VAAPI_ENCODER_H265_PROP_NUM_SLICES:
|
case GST_VAAPI_ENCODER_H265_PROP_NUM_SLICES:
|
||||||
encoder->num_slices = g_value_get_uint (value);
|
encoder->num_slices = g_value_get_uint (value);
|
||||||
if (encoder->num_slices > 1)
|
|
||||||
GST_ERROR ("Mulit-slice encoding is not yet functional!");
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER;
|
return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER;
|
||||||
|
|
Loading…
Reference in a new issue