summaryrefslogtreecommitdiffstats
path: root/gst/rtsp
diff options
context:
space:
mode:
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2009-01-26 11:06:13 +0100
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2009-02-23 22:47:55 +0100
commit21cb00aa9c290010c7da7afc04388348914e7c07 (patch)
treea975d6bf1120fdfd237da80d37e91f15db90d7cc /gst/rtsp
parent969622b439cc7232e8889cd5c7a5579cba6b665f (diff)
rtspsrc: perform UDP SETUP according to MS RTSP spec
MS RTSP spec states that the UDP port pair used in subsequent SETUP requests for various streams must be identical (since there will actually be only 1 stream of muxed asf packets). Following traditional specs and using different port pairs in the SETUPs for separate streams will result in all but the first one failing and only one stream being streamed. So, in appropriate circumstances, retry UDP SETUP using previously used port pair. Fixes #552650.
Diffstat (limited to 'gst/rtsp')
-rw-r--r--gst/rtsp/gstrtspsrc.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/gst/rtsp/gstrtspsrc.c b/gst/rtsp/gstrtspsrc.c
index 6dc09cc5..b3e1df47 100644
--- a/gst/rtsp/gstrtspsrc.c
+++ b/gst/rtsp/gstrtspsrc.c
@@ -3790,7 +3790,8 @@ failed:
}
static GstRTSPResult
-gst_rtspsrc_prepare_transports (GstRTSPStream * stream, gchar ** transports)
+gst_rtspsrc_prepare_transports (GstRTSPStream * stream, gchar ** transports,
+ gint orig_rtpport, gint orig_rtcpport)
{
GstRTSPSrc *src;
gint nr_udp, nr_int;
@@ -3819,8 +3820,13 @@ gst_rtspsrc_prepare_transports (GstRTSPStream * stream, gchar ** transports)
goto done;
if (nr_udp > 0) {
- if (!gst_rtspsrc_alloc_udp_ports (stream, &rtpport, &rtcpport))
- goto failed;
+ if (!orig_rtpport || !orig_rtcpport) {
+ if (!gst_rtspsrc_alloc_udp_ports (stream, &rtpport, &rtcpport))
+ goto failed;
+ } else {
+ rtpport = orig_rtpport;
+ rtcpport = orig_rtcpport;
+ }
}
str = g_string_new ("");
@@ -3880,6 +3886,7 @@ gst_rtspsrc_setup_streams (GstRTSPSrc * src)
GstRTSPStream *stream = NULL;
GstRTSPLowerTrans protocols;
GstRTSPStatusCode code;
+ gint rtpport, rtcpport;
/* we initially allow all configured lower transports. based on the URL
* transports and the replies from the server we narrow them down. */
@@ -3892,9 +3899,11 @@ gst_rtspsrc_setup_streams (GstRTSPSrc * src)
src->free_channel = 0;
src->interleaved = FALSE;
src->need_activate = FALSE;
+ rtpport = rtcpport = 0;
for (walk = src->streams; walk; walk = g_list_next (walk)) {
gchar *transports;
+ gint retry = 0;
stream = (GstRTSPStream *) walk->data;
@@ -3935,6 +3944,7 @@ gst_rtspsrc_setup_streams (GstRTSPSrc * src)
GST_DEBUG_OBJECT (src, "doing setup of stream %p with %s", stream,
stream->setup_url);
+retry:
/* create a string with all the transports */
res = gst_rtspsrc_create_transports_string (src, protocols, &transports);
if (res < 0)
@@ -3944,7 +3954,8 @@ gst_rtspsrc_setup_streams (GstRTSPSrc * src)
/* replace placeholders with real values, this function will optionally
* allocate UDP ports and other info needed to execute the setup request */
- res = gst_rtspsrc_prepare_transports (stream, &transports);
+ res = gst_rtspsrc_prepare_transports (stream, &transports,
+ retry > 0 ? rtpport : 0, retry > 0 ? rtcpport : 0);
if (res < 0)
goto setup_transport_failed;
@@ -3971,8 +3982,17 @@ gst_rtspsrc_setup_streams (GstRTSPSrc * src)
case GST_RTSP_STS_UNSUPPORTED_TRANSPORT:
gst_rtsp_message_unset (&request);
gst_rtsp_message_unset (&response);
- /* cleanup of leftover transport and move to the next stream */
+ /* cleanup of leftover transport */
gst_rtspsrc_stream_free_udp (stream);
+ /* MS WMServer RTSP MUST use same UDP pair in all SETUP requests;
+ * we might be in this case */
+ if (stream->container && rtpport && rtcpport && !retry) {
+ GST_DEBUG_OBJECT (src, "retrying with original port pair %u-%u",
+ rtpport, rtcpport);
+ retry++;
+ goto retry;
+ }
+ /* give up on this stream and move to the next stream */
continue;
default:
/* cleanup of leftover transport and move to the next stream */
@@ -4029,13 +4049,17 @@ gst_rtspsrc_setup_streams (GstRTSPSrc * src)
break;
}
- if (!stream->container || !src->interleaved) {
+ if (!stream->container || (!src->interleaved && !retry)) {
/* now configure the stream with the selected transport */
if (!gst_rtspsrc_stream_configure_transport (stream, &transport)) {
GST_DEBUG_OBJECT (src,
"could not configure stream %p transport, skipping stream",
stream);
goto next;
+ } else if (stream->udpsrc[0] && stream->udpsrc[1]) {
+ /* retain the first allocated UDP port pair */
+ g_object_get (G_OBJECT (stream->udpsrc[0]), "port", &rtpport, NULL);
+ g_object_get (G_OBJECT (stream->udpsrc[1]), "port", &rtcpport, NULL);
}
}
/* we need to activate at least one streams when we detect activity */