gst/udp/gstmultiudpsink.c: Add code to drop membership of a multicast group.

Original commit message from CVS:
* 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.
This commit is contained in:
Wim Taymans 2007-04-29 14:43:37 +00:00
parent 96b4ce1692
commit 066598d8de
4 changed files with 99 additions and 6 deletions

View file

@ -1,3 +1,18 @@
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):

View file

@ -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)

View file

@ -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),

View file

@ -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)
{