va: enc : checking surface alignment attribute

Apply surface alignment attribute when availalbe,
also fix frame cropping issue for va h265 encoder.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6399>
This commit is contained in:
Ruijing Dong 2024-03-06 15:39:33 -05:00 committed by Tim-Philipp Müller
parent c8f42ab3af
commit b547c8eebb
3 changed files with 60 additions and 4 deletions

View file

@ -262,6 +262,51 @@ gst_va_encoder_close (GstVaEncoder * self)
return TRUE;
}
/* for querying the customized surface alignment */
guint
gst_va_encoder_get_surface_alignment (GstVaDisplay * display,
VAProfile profile, VAEntrypoint entrypoint)
{
guint alignment = 0;
#if VA_CHECK_VERSION(1, 21, 0)
VAConfigAttrib *attrib = NULL;
VASurfaceAttrib *attr_list;
guint i, count;
VAConfigID config;
VADisplay dpy;
VAStatus status;
dpy = gst_va_display_get_va_dpy (display);
status = vaCreateConfig (dpy, profile, entrypoint, attrib, 0, &config);
if (status != VA_STATUS_SUCCESS) {
GST_ERROR_OBJECT (display, "vaCreateConfig: %s", vaErrorStr (status));
return alignment;
}
attr_list = gst_va_get_surface_attribs (display, config, &count);
if (!attr_list)
goto bail;
for (i = 0; i < count; i++) {
if (attr_list[i].type == VASurfaceAttribAlignmentSize) {
alignment = attr_list[i].value.value.i;
GST_INFO_OBJECT (display,
"Using customized surface alignment [%dx%d]\n",
1 << (alignment & 0xf), 1 << ((alignment & 0xf0) >> 4));
break;
}
}
g_free (attr_list);
bail:
status = vaDestroyConfig (dpy, config);
if (status != VA_STATUS_SUCCESS) {
GST_ERROR_OBJECT (display, "vaDestroyConfig: %s", vaErrorStr (status));
return alignment;
}
#endif
return alignment;
}
static GArray *
_get_surface_formats (GstVaDisplay * display, VAConfigID config)
{

View file

@ -119,5 +119,7 @@ GstVaEncodePicture * gst_va_encode_picture_new (GstVaEncoder * self,
void gst_va_encode_picture_free (GstVaEncodePicture * pic);
VASurfaceID gst_va_encode_picture_get_raw_surface (GstVaEncodePicture * pic);
VASurfaceID gst_va_encode_picture_get_reconstruct_surface (GstVaEncodePicture * pic);
guint gst_va_encoder_get_surface_alignment (GstVaDisplay *display,
VAProfile profile,
VAEntrypoint entrypoint);
G_END_DECLS

View file

@ -4410,6 +4410,7 @@ gst_va_h265_enc_reconfig (GstVaBaseEnc * base)
gboolean do_renegotiation = TRUE, do_reopen, need_negotiation;
guint max_ref_frames, max_surfaces = 0, rt_format = 0, codedbuf_size;
gint width, height;
guint alignment;
width = GST_VIDEO_INFO_WIDTH (&base->in_info);
height = GST_VIDEO_INFO_HEIGHT (&base->in_info);
@ -4444,11 +4445,19 @@ gst_va_h265_enc_reconfig (GstVaBaseEnc * base)
base->width = width;
base->height = height;
alignment = gst_va_encoder_get_surface_alignment (base->display,
profile, klass->entrypoint);
if (alignment) {
self->luma_width = GST_ROUND_UP_N (base->width, 1 << (alignment & 0xf));
self->luma_height =
GST_ROUND_UP_N (base->height, 1 << ((alignment & 0xf0) >> 4));
} else {
self->luma_width = GST_ROUND_UP_16 (base->width);
self->luma_height = GST_ROUND_UP_16 (base->height);
}
/* Frame Cropping */
if ((base->width & 15) || (base->height & 15)) {
if (self->luma_width != base->width || self->luma_height != base->height) {
/* 6.1, Table 6-1 */
static const guint SubWidthC[] = { 1, 2, 2, 1 };
static const guint SubHeightC[] = { 1, 2, 1, 1 };