summaryrefslogtreecommitdiffstats
path: root/gst/rtsp
diff options
context:
space:
mode:
authorThomas Vander Stichele <thomas (at) apestaart (dot) org>2009-03-02 09:43:30 +0100
committerThomas Vander Stichele <thomas (at) apestaart (dot) org>2009-03-02 09:43:30 +0100
commit9f25f96155b246663a1f900624ccda4b9eafcded (patch)
tree029a4a4e8e96dc27e5f3ba38615bcfe9bee64455 /gst/rtsp
parent13221762d09f8faacfbd682e68500ff22e6eb8ab (diff)
parent0083b9e40569db889500a3c1abd7ec3ac8876fee (diff)
Merge branch 'master' of ssh://thomasvs@git.freedesktop.org/git/gstreamer/gst-plugins-good
Diffstat (limited to 'gst/rtsp')
-rw-r--r--gst/rtsp/gstrtspext.c17
-rw-r--r--gst/rtsp/gstrtspext.h1
-rw-r--r--gst/rtsp/gstrtspsrc.c90
-rw-r--r--gst/rtsp/gstrtspsrc.h1
4 files changed, 89 insertions, 20 deletions
diff --git a/gst/rtsp/gstrtspext.c b/gst/rtsp/gstrtspext.c
index 0ad81b56..a3216794 100644
--- a/gst/rtsp/gstrtspext.c
+++ b/gst/rtsp/gstrtspext.c
@@ -247,3 +247,20 @@ gst_rtsp_ext_list_connect (GstRTSPExtensionList * ext,
g_signal_connect (elem, detailed_signal, c_handler, data);
}
}
+
+GstRTSPResult
+gst_rtsp_ext_list_receive_request (GstRTSPExtensionList * ext,
+ GstRTSPMessage * req)
+{
+ GList *walk;
+ GstRTSPResult res = GST_RTSP_ENOTIMPL;
+
+ for (walk = ext->extensions; walk; walk = g_list_next (walk)) {
+ GstRTSPExtension *elem = (GstRTSPExtension *) walk->data;
+
+ res = gst_rtsp_extension_receive_request (elem, req);
+ if (res != GST_RTSP_ENOTIMPL)
+ break;
+ }
+ return res;
+}
diff --git a/gst/rtsp/gstrtspext.h b/gst/rtsp/gstrtspext.h
index fa7f6892..f30b302f 100644
--- a/gst/rtsp/gstrtspext.h
+++ b/gst/rtsp/gstrtspext.h
@@ -76,6 +76,7 @@ GstRTSPResult gst_rtsp_ext_list_stream_select (GstRTSPExtensionList *ext, Gs
void gst_rtsp_ext_list_connect (GstRTSPExtensionList *ext,
const gchar *detailed_signal, GCallback c_handler,
gpointer data);
+GstRTSPResult gst_rtsp_ext_list_receive_request (GstRTSPExtensionList *ext, GstRTSPMessage *req);
G_END_DECLS
diff --git a/gst/rtsp/gstrtspsrc.c b/gst/rtsp/gstrtspsrc.c
index 02970c42..7c5ef8a6 100644
--- a/gst/rtsp/gstrtspsrc.c
+++ b/gst/rtsp/gstrtspsrc.c
@@ -146,6 +146,7 @@ enum
#define DEFAULT_LATENCY_MS 3000
#define DEFAULT_CONNECTION_SPEED 0
#define DEFAULT_NAT_METHOD GST_RTSP_NAT_DUMMY
+#define DEFAULT_DO_RTCP TRUE
enum
{
@@ -159,6 +160,7 @@ enum
PROP_LATENCY,
PROP_CONNECTION_SPEED,
PROP_NAT_METHOD,
+ PROP_DO_RTCP,
PROP_LAST
};
@@ -335,6 +337,19 @@ gst_rtspsrc_class_init (GstRTSPSrcClass * klass)
GST_TYPE_RTSP_NAT_METHOD, DEFAULT_NAT_METHOD,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+ /**
+ * GstRTSPSrc::do-rtcp
+ *
+ * Enable RTCP support. Some old server don't like RTCP and then this property
+ * needs to be set to FALSE.
+ *
+ * Since: 0.10.15
+ */
+ g_object_class_install_property (gobject_class, PROP_DO_RTCP,
+ g_param_spec_boolean ("do-rtcp", "Do RTCP",
+ "Don't send RTCP packets",
+ DEFAULT_DO_RTCP, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
gstelement_class->change_state = gst_rtspsrc_change_state;
gstbin_class->handle_message = gst_rtspsrc_handle_message;
@@ -454,6 +469,9 @@ gst_rtspsrc_set_property (GObject * object, guint prop_id, const GValue * value,
case PROP_NAT_METHOD:
rtspsrc->nat_method = g_value_get_enum (value);
break;
+ case PROP_DO_RTCP:
+ rtspsrc->do_rtcp = g_value_get_boolean (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -502,6 +520,9 @@ gst_rtspsrc_get_property (GObject * object, guint prop_id, GValue * value,
case PROP_NAT_METHOD:
g_value_set_enum (value, rtspsrc->nat_method);
break;
+ case PROP_DO_RTCP:
+ g_value_set_boolean (value, rtspsrc->do_rtcp);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -1942,8 +1963,8 @@ gst_rtspsrc_stream_configure_tcp (GstRTSPSrc * src, GstRTSPStream * stream,
}
gst_object_unref (template);
}
- /* setup RTCP transport back to the server */
- if (src->session) {
+ /* setup RTCP transport back to the server if we have to. */
+ if (src->session && src->do_rtcp) {
GstPad *pad;
template = gst_static_pad_template_get (&anysinktemplate);
@@ -2162,7 +2183,7 @@ gst_rtspsrc_stream_configure_udp_sinks (GstRTSPSrc * src,
}
/* it's possible that the server does not want us to send RTCP in which case
* the port is -1 */
- if (rtcp_port != -1 && src->session != NULL) {
+ if (rtcp_port != -1 && src->session != NULL && src->do_rtcp) {
GST_DEBUG_OBJECT (src, "configure RTCP UDP sink for %s:%d", destination,
rtcp_port);
@@ -2536,20 +2557,25 @@ gst_rtspsrc_handle_request (GstRTSPSrc * src, GstRTSPMessage * request)
if (src->debug)
gst_rtsp_message_dump (request);
- res =
- gst_rtsp_message_init_response (&response, GST_RTSP_STS_OK, "OK",
- request);
- if (res < 0)
- goto send_error;
+ res = gst_rtsp_ext_list_receive_request (src->extensions, request);
+
+ if (res == GST_RTSP_ENOTIMPL) {
+ /* default implementation, send OK */
+ res =
+ gst_rtsp_message_init_response (&response, GST_RTSP_STS_OK, "OK",
+ request);
+ if (res < 0)
+ goto send_error;
- GST_DEBUG_OBJECT (src, "replying with OK");
+ GST_DEBUG_OBJECT (src, "replying with OK");
- if (src->debug)
- gst_rtsp_message_dump (&response);
+ if (src->debug)
+ gst_rtsp_message_dump (&response);
- res = gst_rtspsrc_connection_send (src, &response, NULL);
- if (res < 0)
- goto send_error;
+ res = gst_rtspsrc_connection_send (src, &response, NULL);
+ if (res < 0)
+ goto send_error;
+ }
return GST_RTSP_OK;
@@ -3785,7 +3811,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;
@@ -3814,8 +3841,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 ("");
@@ -3875,6 +3907,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. */
@@ -3887,9 +3920,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;
@@ -3930,6 +3965,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)
@@ -3939,7 +3975,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;
@@ -3966,8 +4003,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 */
@@ -4024,13 +4070,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 */
diff --git a/gst/rtsp/gstrtspsrc.h b/gst/rtsp/gstrtspsrc.h
index 95dd9869..40a368c6 100644
--- a/gst/rtsp/gstrtspsrc.h
+++ b/gst/rtsp/gstrtspsrc.h
@@ -186,6 +186,7 @@ struct _GstRTSPSrc {
guint latency;
guint connection_speed;
GstRTSPNatMethod nat_method;
+ gboolean do_rtcp;
/* state */
GstRTSPState state;