mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-03 14:08:56 +00:00
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:
parent
3fadf4807c
commit
80bb69ba66
1 changed files with 11 additions and 5 deletions
|
@ -685,6 +685,7 @@ gst_vtdec_negotiate (GstVideoDecoder * decoder)
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_vtdec_set_format (GstVideoDecoder * decoder, GstVideoCodecState * state)
|
gst_vtdec_set_format (GstVideoDecoder * decoder, GstVideoCodecState * state)
|
||||||
{
|
{
|
||||||
|
gboolean negotiate_now = TRUE;
|
||||||
GstStructure *structure;
|
GstStructure *structure;
|
||||||
CMVideoCodecType cm_format = 0;
|
CMVideoCodecType cm_format = 0;
|
||||||
CMFormatDescriptionRef format_description = NULL;
|
CMFormatDescriptionRef format_description = NULL;
|
||||||
|
@ -718,15 +719,20 @@ gst_vtdec_set_format (GstVideoDecoder * decoder, GstVideoCodecState * state)
|
||||||
if ((cm_format == kCMVideoCodecType_H264
|
if ((cm_format == kCMVideoCodecType_H264
|
||||||
|| cm_format == kCMVideoCodecType_HEVC)
|
|| cm_format == kCMVideoCodecType_HEVC)
|
||||||
&& state->codec_data == NULL) {
|
&& state->codec_data == NULL) {
|
||||||
GST_INFO_OBJECT (vtdec, "no codec data, wait for one");
|
GST_INFO_OBJECT (vtdec, "waiting for codec_data before negotiation");
|
||||||
return TRUE;
|
negotiate_now = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_video_info_from_caps (&vtdec->video_info, state->caps);
|
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;
|
return FALSE;
|
||||||
gst_vtdec_set_latency (vtdec);
|
}
|
||||||
|
|
||||||
|
if (negotiate_now)
|
||||||
|
gst_vtdec_set_latency (vtdec);
|
||||||
|
|
||||||
if (state->codec_data) {
|
if (state->codec_data) {
|
||||||
format_description = create_format_description_from_codec_data (vtdec,
|
format_description = create_format_description_from_codec_data (vtdec,
|
||||||
|
@ -743,7 +749,7 @@ gst_vtdec_set_format (GstVideoDecoder * decoder, GstVideoCodecState * state)
|
||||||
gst_video_codec_state_unref (vtdec->input_state);
|
gst_video_codec_state_unref (vtdec->input_state);
|
||||||
vtdec->input_state = gst_video_codec_state_ref (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
|
static gboolean
|
||||||
|
|
Loading…
Reference in a new issue