summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2010-08-20 13:09:12 +0200
committerWim Taymans <wim.taymans@collabora.co.uk>2010-08-20 13:09:12 +0200
commit7c0f8a77ecfaa1b49bc0195e7c914769cec7e9de (patch)
treeb9d4f5581f764aadcfdcadf5f4e84e9b876ff0a9
parentaf732fa7492c592c6ce7fd8b6092354e64f4675b (diff)
media: don't add udp addresses multiple times
Keep track of the udp addresses we added to udpsink and never add the same udp destination twice. This avoids duplicate packets when using multicast.
-rw-r--r--gst/rtsp-server/rtsp-media.c91
-rw-r--r--gst/rtsp-server/rtsp-media.h1
2 files changed, 86 insertions, 6 deletions
diff --git a/gst/rtsp-server/rtsp-media.c b/gst/rtsp-server/rtsp-media.c
index 08939c6a69..919622e163 100644
--- a/gst/rtsp-server/rtsp-media.c
+++ b/gst/rtsp-server/rtsp-media.c
@@ -1527,6 +1527,89 @@ default_unprepare (GstRTSPMedia * media)
return TRUE;
}
+typedef struct {
+ gint count;
+ gchar *dest;
+ gint min, max;
+} RTSPDestination;
+
+
+static gint
+dest_compare (RTSPDestination * a, RTSPDestination * b)
+{
+ if ((a->min == b->min) && (a->max == b->max) && (strcmp (a->dest, b->dest) == 0))
+ return 0;
+
+ return 1;
+}
+
+/* FIXME, udpsink should do this for us */
+static void
+add_udp_destination (GstRTSPMedia *media, GstRTSPMediaStream *stream,
+ gchar *dest, gint min, gint max)
+{
+ RTSPDestination fdest;
+ RTSPDestination *ndest;
+ GList *find;
+
+ fdest.dest = dest;
+ fdest.min = min;
+ fdest.max = max;
+
+ /* first see if we already added this destination */
+ find = g_list_find_custom (stream->destinations, &fdest, (GCompareFunc) dest_compare);
+ if (find) {
+ ndest = (RTSPDestination *) find->data;
+
+ GST_INFO ("already streaming to %s:%d-%d with %d clients", dest, min, max, ndest->count);
+ ndest->count++;
+ } else {
+ GST_INFO ("adding %s:%d-%d", dest, min, max);
+
+ g_signal_emit_by_name (stream->udpsink[0], "add", dest, min, NULL);
+ g_signal_emit_by_name (stream->udpsink[1], "add", dest, max, NULL);
+
+ ndest = g_slice_new (RTSPDestination);
+ ndest->count = 1;
+ ndest->dest = g_strdup (dest);
+ ndest->min = min;
+ ndest->max = max;
+
+ stream->destinations = g_list_prepend (stream->destinations, ndest);
+ }
+}
+
+static void
+remove_udp_destination (GstRTSPMedia *media, GstRTSPMediaStream *stream,
+ gchar *dest, gint min, gint max)
+{
+ RTSPDestination fdest;
+ RTSPDestination *ndest;
+ GList *find;
+
+ fdest.dest = dest;
+ fdest.min = min;
+ fdest.max = max;
+
+ /* first see if we already added this destination */
+ find = g_list_find_custom (stream->destinations, &fdest, (GCompareFunc) dest_compare);
+ if (!find)
+ return;
+
+ ndest = (RTSPDestination *) find->data;
+ if (--ndest->count == 0) {
+ GST_INFO ("removing %s:%d-%d", dest, min, max);
+ g_signal_emit_by_name (stream->udpsink[0], "remove", dest, min, NULL);
+ g_signal_emit_by_name (stream->udpsink[1], "remove", dest, max, NULL);
+
+ stream->destinations = g_list_delete_link (stream->destinations, find);
+ g_free (ndest->dest);
+ g_slice_free (RTSPDestination, ndest);
+ } else {
+ GST_INFO ("still streaming to %s:%d-%d with %d clients", dest, min, max, ndest->count);
+ }
+}
+
/**
* gst_rtsp_media_set_state:
* @media: a #GstRTSPMedia
@@ -1610,16 +1693,12 @@ gst_rtsp_media_set_state (GstRTSPMedia * media, GstState state,
}
if (add && !tr->active) {
- GST_INFO ("adding %s:%d-%d", dest, min, max);
- g_signal_emit_by_name (stream->udpsink[0], "add", dest, min, NULL);
- g_signal_emit_by_name (stream->udpsink[1], "add", dest, max, NULL);
+ add_udp_destination (media, stream, dest, min, max);
stream->transports = g_list_prepend (stream->transports, tr);
tr->active = TRUE;
media->active++;
} else if (remove && tr->active) {
- GST_INFO ("removing %s:%d-%d", dest, min, max);
- g_signal_emit_by_name (stream->udpsink[0], "remove", dest, min, NULL);
- g_signal_emit_by_name (stream->udpsink[1], "remove", dest, max, NULL);
+ remove_udp_destination (media, stream, dest, min, max);
stream->transports = g_list_remove (stream->transports, tr);
tr->active = FALSE;
media->active--;
diff --git a/gst/rtsp-server/rtsp-media.h b/gst/rtsp-server/rtsp-media.h
index ec3e832f65..d3c94db69a 100644
--- a/gst/rtsp-server/rtsp-media.h
+++ b/gst/rtsp-server/rtsp-media.h
@@ -137,6 +137,7 @@ struct _GstRTSPMediaStream {
/* transports we stream to */
GList *transports;
+ GList *destinations;
};
/**