vaXXXenc: fix potential race condition

VA encoders, at reconfiguration, have to check if the rate-control was changed
by the user, but since user parameters setting are in another thread, the
comparison was racy.

This patch locks the object to compare the current rate-control with the one set
by the user.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9480>
This commit is contained in:
Víctor Manuel Jáquez Leal 2025-08-01 11:52:17 +02:00 committed by GStreamer Marge Bot
parent c81c19bfdc
commit f170eff6bb
5 changed files with 32 additions and 12 deletions

View File

@ -2778,7 +2778,7 @@ gst_va_av1_enc_reconfig (GstVaBaseEnc * base)
GstVideoCodecState *output_state;
GstVideoFormat format, reconf_format = GST_VIDEO_FORMAT_UNKNOWN;
VAProfile profile;
gboolean do_renegotiation = TRUE, do_reopen, need_negotiation;
gboolean do_renegotiation = TRUE, do_reopen, need_negotiation, rc_same;
guint max_ref_frames, max_surfaces = 0,
rt_format, depth = 0, chrome = 0, codedbuf_size, latency_num;
gint width, height;
@ -2810,11 +2810,15 @@ gst_va_av1_enc_reconfig (GstVaBaseEnc * base)
if (profile == VAProfileNone)
return FALSE;
GST_OBJECT_LOCK (self);
rc_same = (self->prop.rc_ctrl == self->rc.rc_ctrl_mode);
GST_OBJECT_UNLOCK (self);
/* first check */
do_reopen = !(base->profile == profile && base->rt_format == rt_format
&& format == reconf_format && width == base->width
&& height == base->height && self->prop.rc_ctrl == self->rc.rc_ctrl_mode
&& depth == self->depth && chrome == self->chrome);
&& height == base->height && rc_same && depth == self->depth
&& chrome == self->chrome);
if (do_reopen && gst_va_encoder_is_open (base->encoder))
gst_va_encoder_close (base->encoder);

View File

@ -1584,7 +1584,7 @@ gst_va_h264_enc_reconfig (GstVaBaseEnc * base)
GstVideoCodecState *output_state = NULL;
GstVideoFormat format, reconf_format = GST_VIDEO_FORMAT_UNKNOWN;
VAProfile profile = VAProfileNone;
gboolean do_renegotiation = TRUE, do_reopen, need_negotiation;
gboolean do_renegotiation = TRUE, do_reopen, need_negotiation, rc_same;
guint max_ref_frames, max_surfaces = 0, rt_format = 0,
codedbuf_size, latency_num;
gint width, height;
@ -1609,10 +1609,14 @@ gst_va_h264_enc_reconfig (GstVaBaseEnc * base)
if (!_decide_profile (self, &profile, &rt_format))
return FALSE;
GST_OBJECT_LOCK (self);
rc_same = (self->prop.rc_ctrl == self->rc.rc_ctrl_mode);
GST_OBJECT_UNLOCK (self);
/* first check */
do_reopen = !(base->profile == profile && base->rt_format == rt_format
&& format == reconf_format && width == base->width
&& height == base->height && self->prop.rc_ctrl == self->rc.rc_ctrl_mode);
&& height == base->height && rc_same);
if (do_reopen && gst_va_encoder_is_open (base->encoder))
gst_va_encoder_close (base->encoder);

View File

@ -4504,7 +4504,7 @@ gst_va_h265_enc_reconfig (GstVaBaseEnc * base)
GstVideoCodecState *output_state = NULL;
GstVideoFormat format, reconf_format = GST_VIDEO_FORMAT_UNKNOWN;
VAProfile profile = VAProfileNone;
gboolean do_renegotiation = TRUE, do_reopen, need_negotiation;
gboolean do_renegotiation = TRUE, do_reopen, need_negotiation, rc_same;
guint max_ref_frames, max_surfaces = 0, rt_format = 0,
codedbuf_size, latency_num;
gint width, height;
@ -4530,10 +4530,14 @@ gst_va_h265_enc_reconfig (GstVaBaseEnc * base)
if (!_h265_decide_profile (self, &profile, &rt_format))
return FALSE;
GST_OBJECT_LOCK (self);
rc_same = (self->prop.rc_ctrl == self->rc.rc_ctrl_mode);
GST_OBJECT_UNLOCK (self);
/* first check */
do_reopen = !(base->profile == profile && base->rt_format == rt_format
&& format == reconf_format && width == base->width
&& height == base->height && self->prop.rc_ctrl == self->rc.rc_ctrl_mode);
&& height == base->height && rc_same);
if (do_reopen && gst_va_encoder_is_open (base->encoder))
gst_va_encoder_close (base->encoder);

View File

@ -577,7 +577,7 @@ gst_va_vp8_enc_reconfig (GstVaBaseEnc * base)
GstVideoCodecState *output_state;
GstVideoFormat format, reconf_format = GST_VIDEO_FORMAT_UNKNOWN;
const GstVideoFormatInfo *format_info;
gboolean do_renegotiation = TRUE, do_reopen, need_negotiation;
gboolean do_renegotiation = TRUE, do_reopen, need_negotiation, rc_same;
guint max_ref_frames, max_surfaces = 0, codedbuf_size, latency_num;
gint width, height;
GstClockTime latency;
@ -605,9 +605,13 @@ gst_va_vp8_enc_reconfig (GstVaBaseEnc * base)
reconf_format = GST_VIDEO_INFO_FORMAT (&vi);
}
GST_OBJECT_LOCK (self);
rc_same = (self->prop.rc_ctrl == self->rc.rc_ctrl_mode);
GST_OBJECT_UNLOCK (self);
/* First check */
do_reopen = !(format == reconf_format && width == base->width
&& height == base->height && self->prop.rc_ctrl == self->rc.rc_ctrl_mode);
&& height == base->height && rc_same);
if (do_reopen && gst_va_encoder_is_open (base->encoder))
gst_va_encoder_close (base->encoder);

View File

@ -2095,7 +2095,7 @@ gst_va_vp9_enc_reconfig (GstVaBaseEnc * base)
GstVideoCodecState *output_state;
GstVideoFormat format, reconf_format = GST_VIDEO_FORMAT_UNKNOWN;
VAProfile profile;
gboolean do_renegotiation = TRUE, do_reopen, need_negotiation;
gboolean do_renegotiation = TRUE, do_reopen, need_negotiation, rc_same;
guint max_ref_frames, max_surfaces = 0,
rt_format, depth = 0, chrome = 0, codedbuf_size, latency_num;
gint width, height;
@ -2127,11 +2127,15 @@ gst_va_vp9_enc_reconfig (GstVaBaseEnc * base)
if (profile == VAProfileNone)
return FALSE;
GST_OBJECT_LOCK (self);
rc_same = (self->prop.rc_ctrl == self->rc.rc_ctrl_mode);
GST_OBJECT_UNLOCK (self);
/* first check */
do_reopen = !(base->profile == profile && base->rt_format == rt_format
&& format == reconf_format && width == base->width
&& height == base->height && self->prop.rc_ctrl == self->rc.rc_ctrl_mode
&& depth == self->depth && chrome == self->chrome);
&& height == base->height && rc_same && depth == self->depth
&& chrome == self->chrome);
if (do_reopen && gst_va_encoder_is_open (base->encoder))
gst_va_encoder_close (base->encoder);