rtsp: keep track of server ip and ipv6
authorWim Taymans <wim.taymans@collabora.co.uk>
Tue, 16 Mar 2010 17:37:18 +0000 (18:37 +0100)
committerWim Taymans <wim.taymans@collabora.co.uk>
Tue, 16 Mar 2010 17:37:18 +0000 (18:37 +0100)
Keep track of how the client connected to the server and setup the udp ports
with the same protocol.
Copy the server ip address in the SDP so that clients can send RTCP back to
us.

gst/rtsp-server/rtsp-client.h
gst/rtsp-server/rtsp-media.c
gst/rtsp-server/rtsp-media.h
gst/rtsp-server/rtsp-sdp.c
gst/rtsp-server/rtsp-sdp.h
gst/rtsp-server/rtsp-server.c

index ab124c0670f8e765d21987aa845d7685c4c1fc6b..b29e218593de92633101ea1ce2e8b8b985c12313 100644 (file)
@@ -61,6 +61,7 @@ typedef struct _GstRTSPClientClass GstRTSPClientClass;
  * @connection: the connection object handling the client request.
  * @watch: watch for the connection
  * @watchid: id of the watch
+ * @ip: ip address used by the client to connect to us
  * @session_pool: handle to the session pool used by the client.
  * @media_mapping: handle to the media mapping used by the client.
  * @uri: cached uri
@@ -76,6 +77,8 @@ struct _GstRTSPClient {
   GstRTSPConnection *connection;
   GstRTSPWatch      *watch;
   guint              watchid;
+  gchar             *server_ip;
+  gboolean           is_ipv6;
 
   GstRTSPSessionPool   *session_pool;
   GstRTSPMediaMapping  *media_mapping;
index bee6dff129eb31537224ba2fa892e98b1ba4b21f..c4f824bf40f0b90bee173c749d96ef056bc3e03e 100644 (file)
@@ -539,7 +539,7 @@ gst_rtsp_media_stream_rtcp (GstRTSPMediaStream * stream, GstBuffer * buffer)
 
 /* Allocate the udp ports and sockets */
 static gboolean
-alloc_udp_ports (GstRTSPMediaStream * stream, gboolean is_ipv6)
+alloc_udp_ports (GstRTSPMedia * media, GstRTSPMediaStream * stream)
 {
   GstStateChangeReturn ret;
   GstElement *udpsrc0, *udpsrc1;
@@ -558,7 +558,7 @@ alloc_udp_ports (GstRTSPMediaStream * stream, gboolean is_ipv6)
   /* Start with random port */
   tmp_rtp = 0;
 
-  if (is_ipv6)
+  if (media->is_ipv6)
     host = "udp://[::0]";
   else
     host = "udp://0.0.0.0";
@@ -922,7 +922,7 @@ setup_stream (GstRTSPMediaStream * stream, guint idx, GstRTSPMedia * media)
   /* allocate udp ports, we will have 4 of them, 2 for receiving RTP/RTCP and 2
    * for sending RTP/RTCP. The sender and receiver ports are shared between the
    * elements */
-  if (!alloc_udp_ports (stream, FALSE))
+  if (!alloc_udp_ports (media, stream))
     return FALSE;
 
   /* add the ports to the pipeline */
index e873c04569c3bd378d6f06fce5c24ea92f8028c0..8abf05fa44f98bf349ac386e1e71ad34c69d28f7 100644 (file)
@@ -191,6 +191,7 @@ struct _GstRTSPMedia {
   gboolean           shared;
   gboolean           reusable;
   gboolean           reused;
+  gboolean           is_ipv6;
 
   GstElement        *element;
   GArray            *streams;
index 7c1744b03b25a44a14dafa0de9452fc16990570f..56ca719b8e4072be643b61ba595f075ec871fdfd 100644 (file)
 
 /**
  * gst_rtsp_sdp_from_media:
+ * @sdp: a #GstSDPessage
+ * @info: info
  * @media: a #GstRTSPMedia
  *
- * Create a new sdp message for @media.
+ * Add @media specific info to @sdp. @info is used to configure the connection
+ * information in the SDP.
  *
- * Returns: a new sdp message for @media. gst_sdp_message_free() after usage.
+ * Returns: TRUE on success.
  */
-GstSDPMessage *
-gst_rtsp_sdp_from_media (GstRTSPMedia * media)
+gboolean
+gst_rtsp_sdp_from_media (GstSDPMessage *sdp, GstSDPInfo *info, GstRTSPMedia * media)
 {
-  GstSDPMessage *sdp;
   guint i, n_streams;
   gchar *rangestr;
 
@@ -40,19 +42,6 @@ gst_rtsp_sdp_from_media (GstRTSPMedia * media)
 
   n_streams = gst_rtsp_media_n_streams (media);
 
-  gst_sdp_message_new (&sdp);
-
-  /* some standard things first */
-  gst_sdp_message_set_version (sdp, "0");
-
-  gst_sdp_message_set_origin (sdp, "-", "1188340656180883", "1", "IN", "IP4",
-      "127.0.0.1");
-  gst_sdp_message_set_session_name (sdp, "Session streamed with GStreamer");
-  gst_sdp_message_set_information (sdp, "rtsp-server");
-  gst_sdp_message_add_time (sdp, "0", "0", NULL);
-  gst_sdp_message_add_attribute (sdp, "tool", "GStreamer");
-  gst_sdp_message_add_attribute (sdp, "type", "broadcast");
-  gst_sdp_message_add_attribute (sdp, "control", "*");
   rangestr = gst_rtsp_range_to_string (&media->range);
   gst_sdp_message_add_attribute (sdp, "range", rangestr);
   g_free (rangestr);
@@ -96,7 +85,7 @@ gst_rtsp_sdp_from_media (GstRTSPMedia * media)
     gst_sdp_media_set_proto (smedia, "RTP/AVP");
 
     /* for the c= line */
-    gst_sdp_media_add_connection (smedia, "IN", "IP4", "127.0.0.1", 0, 0);
+    gst_sdp_media_add_connection (smedia, "IN", info->server_proto, info->server_ip, 0, 0);
 
     /* get clock-rate, media type and params for the rtpmap attribute */
     gst_structure_get_int (s, "clock-rate", &caps_rate);
@@ -163,12 +152,12 @@ gst_rtsp_sdp_from_media (GstRTSPMedia * media)
     gst_sdp_media_free (smedia);
   }
 
-  return sdp;
+  return TRUE;
 
   /* ERRORS */
 not_prepared:
   {
     GST_ERROR ("media %p is not prepared", media);
-    return NULL;
+    return FALSE;
   }
 }
index 4016eda37c7e4970c175f49fd51ca2c9e3c5db72..6c4c00549ab64840ce2d0e7e8457ebb425503a18 100644 (file)
 
 G_BEGIN_DECLS
 
+typedef struct {
+  const gchar *server_proto;
+  const gchar *server_ip;
+} GstSDPInfo;
+
 /* creating SDP */
-GstSDPMessage *     gst_rtsp_sdp_from_media      (GstRTSPMedia *media);
+gboolean            gst_rtsp_sdp_from_media      (GstSDPMessage *sdp, GstSDPInfo *info, GstRTSPMedia * media);
 
 G_END_DECLS
 
index 1e302d5409effc1208b34c0402aa82263def8cee..7f54798dba2f60ea5e5c1e2f8e84993ab17fd8be 100644 (file)
@@ -425,7 +425,7 @@ gst_rtsp_server_sink_init_send (GstRTSPServer * server)
   memset(&hints, 0, sizeof(struct addrinfo));
   hints.ai_family = AF_UNSPEC;     /* Allow IPv4 or IPv6 */
   hints.ai_socktype = SOCK_STREAM; /* stream socket */
-  hints.ai_flags = AI_PASSIVE;     /* For wildcard IP address */
+  hints.ai_flags = AI_PASSIVE | AI_CANONNAME;     /* For wildcard IP address */
   hints.ai_protocol = 0;           /* Any protocol */
   hints.ai_canonname = NULL;
   hints.ai_addr = NULL;
@@ -446,8 +446,10 @@ gst_rtsp_server_sink_init_send (GstRTSPServer * server)
       continue;
     }
 
-    if (bind (sockfd, rp->ai_addr, rp->ai_addrlen) == 0)
+    if (bind (sockfd, rp->ai_addr, rp->ai_addrlen) == 0) {
+      GST_DEBUG_OBJECT (server, "bind on %s", rp->ai_canonname);
       break;
+    }
 
     GST_DEBUG_OBJECT (server, "failed to bind socket (%s), try next", g_strerror (errno));
     close (sockfd);
@@ -654,7 +656,7 @@ gst_rtsp_server_create_watch (GstRTSPServer *server)
     channel = gst_rtsp_server_get_io_channel (server);
     if (channel == NULL)
       goto no_channel;
-     
+
     /* create a watch for reads (new connections) and possible errors */
     server->io_watch = g_io_create_watch (channel, G_IO_IN |
                   G_IO_ERR | G_IO_HUP | G_IO_NVAL);
@@ -682,7 +684,7 @@ no_channel:
  * This function should be called when the server properties and urls are fully
  * configured and the server is ready to start.
  *
- * Returns: the ID (greater than 0) for the source within the GMainContext. 
+ * Returns: the ID (greater than 0) for the source within the GMainContext.
  */
 guint
 gst_rtsp_server_attach (GstRTSPServer *server, GMainContext *context)