summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--gst/rtsp/gstrtspsrc.c27
-rw-r--r--gst/udp/gstmultiudpsink.c11
-rw-r--r--gst/udp/gstudpsink.c52
4 files changed, 99 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 219554e4..a8cf688c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,20 @@
2007-04-29 Wim Taymans <wim@fluendo.com>
+ * gst/udp/gstmultiudpsink.c: (leave_multicast),
+ (gst_multiudpsink_add), (gst_multiudpsink_remove):
+ Add code to drop membership of a multicast group.
+
+ * gst/udp/gstudpsink.c: (gst_udpsink_update_uri),
+ (gst_udpsink_set_uri):
+ Implement URI handler.
+
+ * gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_stream_configure_transport),
+ (gst_rtspsrc_parse_rtpinfo):
+ Use URI handler to make udpsink instace.
+ Improve code to configure port and destination.
+
+2007-04-29 Wim Taymans <wim@fluendo.com>
+
* gst/udp/gstmultiudpsink.c: (gst_multiudpsink_add):
Fix multicast detection.
Don't try to join a multicast group if the address is not multicast.
diff --git a/gst/rtsp/gstrtspsrc.c b/gst/rtsp/gstrtspsrc.c
index 64a050a2..ee383a45 100644
--- a/gst/rtsp/gstrtspsrc.c
+++ b/gst/rtsp/gstrtspsrc.c
@@ -1341,8 +1341,24 @@ use_no_manager:
/* configure udpsink back to the server for RTCP messages. */
{
GstPad *pad;
+ gint port;
+ gchar *destination, *uri;
- stream->udpsink = gst_element_factory_make ("udpsink", NULL);
+ /* get host and port */
+ if (transport->lower_transport == RTSP_LOWER_TRANS_UDP_MCAST)
+ port = transport->port.max;
+ else
+ port = transport->server_port.max;
+
+ destination = transport->destination;
+ if (destination == NULL)
+ destination = src->addr;
+
+ GST_DEBUG_OBJECT (src, "configure UDP sink for %s:%d", destination, port);
+
+ uri = g_strdup_printf ("udp://%s:%d", destination, port);
+ stream->udpsink = gst_element_make_from_uri (GST_URI_SINK, uri, NULL);
+ g_free (uri);
if (stream->udpsink == NULL)
goto no_sink_element;
@@ -1353,10 +1369,6 @@ use_no_manager:
/* no sync needed */
g_object_set (G_OBJECT (stream->udpsink), "sync", FALSE, NULL);
- /* configure host and port */
- g_object_set (G_OBJECT (stream->udpsink), "host", src->addr, "port",
- transport->server_port.max, NULL);
-
gst_object_ref (stream->udpsink);
gst_bin_add (GST_BIN_CAST (src), stream->udpsink);
@@ -2819,6 +2831,11 @@ close_failed:
/* RTP-Info is of the format:
*
* url=<URL>;[seq=<seqbase>;rtptime=<timebase>] [, url=...]
+ *
+ * rtptime corresponds to the timestamp for the NPT time given in the header
+ * seqbase corresponds to the next sequence number we received. This number
+ * indicates the first seqnum after the seek and should be used to discard
+ * packets that are from before the seek.
*/
static gboolean
gst_rtspsrc_parse_rtpinfo (GstRTSPSrc * src, gchar * rtpinfo)
diff --git a/gst/udp/gstmultiudpsink.c b/gst/udp/gstmultiudpsink.c
index 72fec4cf..21899c95 100644
--- a/gst/udp/gstmultiudpsink.c
+++ b/gst/udp/gstmultiudpsink.c
@@ -400,6 +400,14 @@ join_multicast (GstUDPClient * client)
perror ("setsockopt IP_MULTICAST_LOOP\n");
}
+static void
+leave_multicast (GstUDPClient * client)
+{
+ if (setsockopt (*(client->sock), IPPROTO_IP, IP_DROP_MEMBERSHIP,
+ &(client->multi_addr), sizeof (client->multi_addr)) < 0)
+ perror ("setsockopt IP_DROP_MEMBERSHIP\n");
+}
+
/* create a socket for sending to remote machine */
static gboolean
gst_multiudpsink_init_send (GstMultiUDPSink * sink)
@@ -563,6 +571,9 @@ gst_multiudpsink_remove (GstMultiUDPSink * sink, const gchar * host, gint port)
g_get_current_time (&now);
client->disconnect_time = GST_TIMEVAL_TO_TIME (now);
+ if (client->multi_addr.imr_multiaddr.s_addr)
+ leave_multicast (client);
+
/* Unlock to emit signal before we delete the actual client */
g_mutex_unlock (sink->client_lock);
g_signal_emit (G_OBJECT (sink),
diff --git a/gst/udp/gstudpsink.c b/gst/udp/gstudpsink.c
index 583827dd..78386062 100644
--- a/gst/udp/gstudpsink.c
+++ b/gst/udp/gstudpsink.c
@@ -153,10 +153,59 @@ gst_udpsink_finalize (GstUDPSink * udpsink)
G_OBJECT_CLASS (parent_class)->finalize ((GObject *) udpsink);
}
+static void
+gst_udpsink_update_uri (GstUDPSink * sink)
+{
+ g_free (sink->uri);
+ sink->uri = g_strdup_printf ("udp://%s:%d", sink->host, sink->port);
+
+ GST_DEBUG_OBJECT (sink, "updated uri to %s", sink->uri);
+}
+
static gboolean
gst_udpsink_set_uri (GstUDPSink * sink, const gchar * uri)
{
- return FALSE;
+ gchar *protocol;
+ gchar *location;
+ gchar *colptr;
+
+ protocol = gst_uri_get_protocol (uri);
+ if (strcmp (protocol, "udp") != 0)
+ goto wrong_protocol;
+ g_free (protocol);
+
+ location = gst_uri_get_location (uri);
+ if (!location)
+ return FALSE;
+ colptr = strstr (location, ":");
+
+ gst_multiudpsink_remove (GST_MULTIUDPSINK (sink), sink->host, sink->port);
+
+ if (colptr != NULL) {
+ g_free (sink->host);
+ sink->host = g_strndup (location, colptr - location);
+ sink->port = atoi (colptr + 1);
+ } else {
+ g_free (sink->host);
+ sink->host = g_strdup (location);
+ sink->port = UDP_DEFAULT_PORT;
+ }
+ g_free (location);
+
+ gst_multiudpsink_add (GST_MULTIUDPSINK (sink), sink->host, sink->port);
+
+ gst_udpsink_update_uri (sink);
+
+ return TRUE;
+
+ /* ERRORS */
+wrong_protocol:
+ {
+ g_free (protocol);
+ GST_ELEMENT_ERROR (sink, RESOURCE, READ, (NULL),
+ ("error parsing uri %s: wrong protocol (%s != udp)", uri, protocol));
+ return FALSE;
+ }
}
static void
@@ -216,6 +265,7 @@ gst_udpsink_uri_get_type (void)
{
return GST_URI_SINK;
}
+
static gchar **
gst_udpsink_uri_get_protocols (void)
{