vtdec: Set input formats when we get incomplete caps

In some cases, decodebin3 will send us incomplete caps (not containing
codec_data), and then a GAP event, which will force a negotiation.
This segfaults due to a null pointer deref because self->input_state
is NULL.

The only possible fix is to avoid negotiating when we get incomplete
caps (to avoid re-negotiationg immediately afterwards, which isn't
supported by some muxers), but also set as much input state as
possible so that a renegotiation triggered by a GAP event can complete
successfully.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7634>
This commit is contained in:
Nirbheek Chauhan 2024-10-04 23:37:35 +05:30 committed by GStreamer Marge Bot
parent 3fadf4807c
commit 80bb69ba66

View file

@ -685,6 +685,7 @@ gst_vtdec_negotiate (GstVideoDecoder * decoder)
static gboolean
gst_vtdec_set_format (GstVideoDecoder * decoder, GstVideoCodecState * state)
{
gboolean negotiate_now = TRUE;
GstStructure *structure;
CMVideoCodecType cm_format = 0;
CMFormatDescriptionRef format_description = NULL;
@ -718,14 +719,19 @@ gst_vtdec_set_format (GstVideoDecoder * decoder, GstVideoCodecState * state)
if ((cm_format == kCMVideoCodecType_H264
|| cm_format == kCMVideoCodecType_HEVC)
&& state->codec_data == NULL) {
GST_INFO_OBJECT (vtdec, "no codec data, wait for one");
return TRUE;
GST_INFO_OBJECT (vtdec, "waiting for codec_data before negotiation");
negotiate_now = FALSE;
}
gst_video_info_from_caps (&vtdec->video_info, state->caps);
if (!gst_vtdec_compute_dpb_size (vtdec, cm_format, state->codec_data))
if (negotiate_now &&
!gst_vtdec_compute_dpb_size (vtdec, cm_format, state->codec_data)) {
GST_INFO_OBJECT (vtdec, "Failed to compute DPB size");
return FALSE;
}
if (negotiate_now)
gst_vtdec_set_latency (vtdec);
if (state->codec_data) {
@ -743,7 +749,7 @@ gst_vtdec_set_format (GstVideoDecoder * decoder, GstVideoCodecState * state)
gst_video_codec_state_unref (vtdec->input_state);
vtdec->input_state = gst_video_codec_state_ref (state);
return gst_vtdec_negotiate (decoder);
return negotiate_now ? gst_vtdec_negotiate (decoder) : TRUE;
}
static gboolean