From: Sebastian Dröge Date: Thu, 6 Oct 2022 12:02:22 +0000 (+0300) Subject: rtspsrc: Retry SETUP with non-compliant URL resolution on "Bad Request" and "Not... X-Git-Tag: 1.22.0~834 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bacd92274dccbea39dd9224c393f3ef0c5ded36a;p=platform%2Fupstream%2Fgstreamer.git rtspsrc: Retry SETUP with non-compliant URL resolution on "Bad Request" and "Not found" Various RTSP servers/cameras assume base and control URL to be simply appended instead of being resolved according to the relative URL resolution algorithm as mandated by the RTSP specification. To work around this, try using such a non-compliant control URL if the server didn't like the URL used in the first SETUP request. Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1447 Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/issues/922 Part-of: --- diff --git a/subprojects/gst-plugins-good/gst/rtsp/gstrtspsrc.c b/subprojects/gst-plugins-good/gst/rtsp/gstrtspsrc.c index a6eec43..fe34dd2 100644 --- a/subprojects/gst-plugins-good/gst/rtsp/gstrtspsrc.c +++ b/subprojects/gst-plugins-good/gst/rtsp/gstrtspsrc.c @@ -7402,6 +7402,7 @@ gst_rtspsrc_setup_streams_start (GstRTSPSrc * src, gboolean async) GstRTSPConnInfo *conninfo; gchar *transports; gint retry = 0; + gboolean tried_non_compliant_url = FALSE; guint mask = 0; gboolean selected; GstCaps *caps; @@ -7594,6 +7595,47 @@ gst_rtspsrc_setup_streams_start (GstRTSPSrc * src, gboolean async) continue; else goto retry; + case GST_RTSP_STS_BAD_REQUEST: + case GST_RTSP_STS_NOT_FOUND: + /* There are various non-compliant servers that don't require control + * URLs that are not resolved correctly but instead are just appended. + * See e.g. + * https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/issues/922 + * https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1447 + */ + if (!tried_non_compliant_url && stream->control_url + && !g_str_has_prefix (stream->control_url, "rtsp://")) { + const gchar *base; + + gst_rtsp_message_unset (&request); + gst_rtsp_message_unset (&response); + gst_rtspsrc_stream_free_udp (stream); + + g_free (stream->conninfo.location); + base = get_aggregate_control (src); + + /* Make sure to not accumulate too many `/` */ + if ((g_str_has_suffix (base, "/") + && !g_str_has_suffix (stream->control_url, "/")) + || (!g_str_has_suffix (base, "/") + && g_str_has_suffix (stream->control_url, "/")) + ) + stream->conninfo.location = + g_strconcat (base, stream->control_url, NULL); + else if (g_str_has_suffix (base, "/") + && g_str_has_suffix (stream->control_url, "/")) + stream->conninfo.location = + g_strconcat (base, stream->control_url + 1, NULL); + else + stream->conninfo.location = + g_strconcat (base, "/", stream->control_url, NULL); + + tried_non_compliant_url = TRUE; + + goto retry; + } + + /* fall through */ default: /* cleanup of leftover transport and move to the next stream */ gst_rtspsrc_stream_free_udp (stream);