mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 19:21:06 +00:00
rtspsrc: expose property for forcing usage of non-compliant URLs
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7346>
This commit is contained in:
parent
c29f2e8632
commit
6500fc7666
3 changed files with 77 additions and 21 deletions
|
@ -21407,6 +21407,18 @@
|
||||||
"type": "GstStructure",
|
"type": "GstStructure",
|
||||||
"writable": true
|
"writable": true
|
||||||
},
|
},
|
||||||
|
"force-non-compliant-url": {
|
||||||
|
"blurb": "Revert to old non-compliant method of constructing URLs",
|
||||||
|
"conditionally-available": false,
|
||||||
|
"construct": false,
|
||||||
|
"construct-only": false,
|
||||||
|
"controllable": false,
|
||||||
|
"default": "false",
|
||||||
|
"mutable": "null",
|
||||||
|
"readable": true,
|
||||||
|
"type": "gboolean",
|
||||||
|
"writable": true
|
||||||
|
},
|
||||||
"ignore-x-server-reply": {
|
"ignore-x-server-reply": {
|
||||||
"blurb": "Whether to ignore the x-server-ip-address server header reply",
|
"blurb": "Whether to ignore the x-server-ip-address server header reply",
|
||||||
"conditionally-available": false,
|
"conditionally-available": false,
|
||||||
|
|
|
@ -314,6 +314,7 @@ gst_rtsp_backchannel_get_type (void)
|
||||||
#define DEFAULT_ONVIF_RATE_CONTROL TRUE
|
#define DEFAULT_ONVIF_RATE_CONTROL TRUE
|
||||||
#define DEFAULT_IS_LIVE TRUE
|
#define DEFAULT_IS_LIVE TRUE
|
||||||
#define DEFAULT_IGNORE_X_SERVER_REPLY FALSE
|
#define DEFAULT_IGNORE_X_SERVER_REPLY FALSE
|
||||||
|
#define DEFAULT_FORCE_NON_COMPLIANT_URL FALSE
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -365,6 +366,7 @@ enum
|
||||||
PROP_IS_LIVE,
|
PROP_IS_LIVE,
|
||||||
PROP_IGNORE_X_SERVER_REPLY,
|
PROP_IGNORE_X_SERVER_REPLY,
|
||||||
PROP_EXTRA_HTTP_REQUEST_HEADERS,
|
PROP_EXTRA_HTTP_REQUEST_HEADERS,
|
||||||
|
PROP_FORCE_NON_COMPLIANT_URL,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GST_TYPE_RTSP_NAT_METHOD (gst_rtsp_nat_method_get_type())
|
#define GST_TYPE_RTSP_NAT_METHOD (gst_rtsp_nat_method_get_type())
|
||||||
|
@ -1117,6 +1119,26 @@ gst_rtspsrc_class_init (GstRTSPSrcClass * klass)
|
||||||
"Extra headers to append to HTTP requests when in tunneled mode",
|
"Extra headers to append to HTTP requests when in tunneled mode",
|
||||||
GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstRTSPSrc:force-non-compliant-url
|
||||||
|
*
|
||||||
|
* There are various non-compliant servers that don't require control URLs
|
||||||
|
* that are not resolved correctly but instead are just appended.
|
||||||
|
*
|
||||||
|
* As some of these servers will nevertheless reply OK to SETUP requests
|
||||||
|
* even if they didn't handle URIs correctly, this property can be set to
|
||||||
|
* revert to the old non-compliant method for constructing URLs.
|
||||||
|
*
|
||||||
|
* Since: 1.24.7
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_FORCE_NON_COMPLIANT_URL,
|
||||||
|
g_param_spec_boolean ("force-non-compliant-url",
|
||||||
|
"Force non-compliant URL",
|
||||||
|
"Revert to old non-compliant method of constructing URLs",
|
||||||
|
DEFAULT_FORCE_NON_COMPLIANT_URL,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstRTSPSrc::handle-request:
|
* GstRTSPSrc::handle-request:
|
||||||
* @rtspsrc: a #GstRTSPSrc
|
* @rtspsrc: a #GstRTSPSrc
|
||||||
|
@ -1548,6 +1570,7 @@ gst_rtspsrc_init (GstRTSPSrc * src)
|
||||||
src->group_id = GST_GROUP_ID_INVALID;
|
src->group_id = GST_GROUP_ID_INVALID;
|
||||||
src->prop_extra_http_request_headers =
|
src->prop_extra_http_request_headers =
|
||||||
gst_structure_new_empty ("extra-http-request-headers");
|
gst_structure_new_empty ("extra-http-request-headers");
|
||||||
|
src->force_non_compliant_url = DEFAULT_FORCE_NON_COMPLIANT_URL;
|
||||||
|
|
||||||
/* get a list of all extensions */
|
/* get a list of all extensions */
|
||||||
src->extensions = gst_rtsp_ext_list_get ();
|
src->extensions = gst_rtsp_ext_list_get ();
|
||||||
|
@ -1908,6 +1931,9 @@ gst_rtspsrc_set_property (GObject * object, guint prop_id, const GValue * value,
|
||||||
gst_structure_new_empty ("extra-http-request-headers");
|
gst_structure_new_empty ("extra-http-request-headers");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case PROP_FORCE_NON_COMPLIANT_URL:
|
||||||
|
rtspsrc->force_non_compliant_url = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -2084,6 +2110,9 @@ gst_rtspsrc_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
case PROP_EXTRA_HTTP_REQUEST_HEADERS:
|
case PROP_EXTRA_HTTP_REQUEST_HEADERS:
|
||||||
gst_value_set_structure (value, rtspsrc->prop_extra_http_request_headers);
|
gst_value_set_structure (value, rtspsrc->prop_extra_http_request_headers);
|
||||||
break;
|
break;
|
||||||
|
case PROP_FORCE_NON_COMPLIANT_URL:
|
||||||
|
g_value_set_boolean (value, rtspsrc->force_non_compliant_url);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -7577,6 +7606,31 @@ gst_rtspsrc_setup_streams_end (GstRTSPSrc * src, gboolean async)
|
||||||
return GST_RTSP_OK;
|
return GST_RTSP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
try_non_compliant_url (GstRTSPSrc * src, GstRTSPStream * stream)
|
||||||
|
{
|
||||||
|
const gchar *base;
|
||||||
|
|
||||||
|
base = get_aggregate_control (src);
|
||||||
|
|
||||||
|
g_free (stream->conninfo.location);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
|
||||||
/* Perform the SETUP request for all the streams.
|
/* Perform the SETUP request for all the streams.
|
||||||
*
|
*
|
||||||
* We ask the server for a specific transport, which initially includes all the
|
* We ask the server for a specific transport, which initially includes all the
|
||||||
|
@ -7640,7 +7694,7 @@ gst_rtspsrc_setup_streams_start (GstRTSPSrc * src, gboolean async)
|
||||||
GstRTSPConnInfo *conninfo;
|
GstRTSPConnInfo *conninfo;
|
||||||
gchar *transports;
|
gchar *transports;
|
||||||
gint retry = 0;
|
gint retry = 0;
|
||||||
gboolean tried_non_compliant_url = FALSE;
|
gboolean tried_non_compliant_url;
|
||||||
guint mask = 0;
|
guint mask = 0;
|
||||||
gboolean selected;
|
gboolean selected;
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
|
@ -7722,6 +7776,14 @@ gst_rtspsrc_setup_streams_start (GstRTSPSrc * src, gboolean async)
|
||||||
if (!protocol_masks[mask])
|
if (!protocol_masks[mask])
|
||||||
goto no_protocols;
|
goto no_protocols;
|
||||||
|
|
||||||
|
if (src->force_non_compliant_url) {
|
||||||
|
try_non_compliant_url (src, stream);
|
||||||
|
|
||||||
|
tried_non_compliant_url = TRUE;
|
||||||
|
} else {
|
||||||
|
tried_non_compliant_url = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
GST_DEBUG_OBJECT (src, "protocols = 0x%x, protocol mask = 0x%x", protocols,
|
GST_DEBUG_OBJECT (src, "protocols = 0x%x, protocol mask = 0x%x", protocols,
|
||||||
protocol_masks[mask]);
|
protocol_masks[mask]);
|
||||||
|
@ -7846,30 +7908,11 @@ gst_rtspsrc_setup_streams_start (GstRTSPSrc * src, gboolean async)
|
||||||
*/
|
*/
|
||||||
if (!tried_non_compliant_url && stream->control_url
|
if (!tried_non_compliant_url && stream->control_url
|
||||||
&& !gst_uri_is_valid (stream->control_url)) {
|
&& !gst_uri_is_valid (stream->control_url)) {
|
||||||
const gchar *base;
|
|
||||||
|
|
||||||
gst_rtsp_message_unset (&request);
|
gst_rtsp_message_unset (&request);
|
||||||
gst_rtsp_message_unset (&response);
|
gst_rtsp_message_unset (&response);
|
||||||
gst_rtspsrc_stream_free_udp (stream);
|
gst_rtspsrc_stream_free_udp (stream);
|
||||||
|
|
||||||
g_free (stream->conninfo.location);
|
try_non_compliant_url (src, stream);
|
||||||
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;
|
tried_non_compliant_url = TRUE;
|
||||||
|
|
||||||
|
|
|
@ -281,6 +281,7 @@ struct _GstRTSPSrc {
|
||||||
gboolean is_live;
|
gboolean is_live;
|
||||||
gboolean ignore_x_server_reply;
|
gboolean ignore_x_server_reply;
|
||||||
GstStructure *prop_extra_http_request_headers;
|
GstStructure *prop_extra_http_request_headers;
|
||||||
|
gboolean force_non_compliant_url;
|
||||||
|
|
||||||
/* state */
|
/* state */
|
||||||
GstRTSPState state;
|
GstRTSPState state;
|
||||||
|
|
Loading…
Reference in a new issue