rtsp: keep track of server ip and ipv6

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.
This commit is contained in:
Wim Taymans 2010-03-16 18:37:18 +01:00
parent 4eccdd9dd7
commit e866345f15
6 changed files with 29 additions and 29 deletions

View file

@ -61,6 +61,7 @@ typedef struct _GstRTSPClientClass GstRTSPClientClass;
* @connection: the connection object handling the client request. * @connection: the connection object handling the client request.
* @watch: watch for the connection * @watch: watch for the connection
* @watchid: id of the watch * @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. * @session_pool: handle to the session pool used by the client.
* @media_mapping: handle to the media mapping used by the client. * @media_mapping: handle to the media mapping used by the client.
* @uri: cached uri * @uri: cached uri
@ -76,6 +77,8 @@ struct _GstRTSPClient {
GstRTSPConnection *connection; GstRTSPConnection *connection;
GstRTSPWatch *watch; GstRTSPWatch *watch;
guint watchid; guint watchid;
gchar *server_ip;
gboolean is_ipv6;
GstRTSPSessionPool *session_pool; GstRTSPSessionPool *session_pool;
GstRTSPMediaMapping *media_mapping; GstRTSPMediaMapping *media_mapping;

View file

@ -539,7 +539,7 @@ gst_rtsp_media_stream_rtcp (GstRTSPMediaStream * stream, GstBuffer * buffer)
/* Allocate the udp ports and sockets */ /* Allocate the udp ports and sockets */
static gboolean static gboolean
alloc_udp_ports (GstRTSPMediaStream * stream, gboolean is_ipv6) alloc_udp_ports (GstRTSPMedia * media, GstRTSPMediaStream * stream)
{ {
GstStateChangeReturn ret; GstStateChangeReturn ret;
GstElement *udpsrc0, *udpsrc1; GstElement *udpsrc0, *udpsrc1;
@ -558,7 +558,7 @@ alloc_udp_ports (GstRTSPMediaStream * stream, gboolean is_ipv6)
/* Start with random port */ /* Start with random port */
tmp_rtp = 0; tmp_rtp = 0;
if (is_ipv6) if (media->is_ipv6)
host = "udp://[::0]"; host = "udp://[::0]";
else else
host = "udp://0.0.0.0"; 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 /* 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 * for sending RTP/RTCP. The sender and receiver ports are shared between the
* elements */ * elements */
if (!alloc_udp_ports (stream, FALSE)) if (!alloc_udp_ports (media, stream))
return FALSE; return FALSE;
/* add the ports to the pipeline */ /* add the ports to the pipeline */

View file

@ -191,6 +191,7 @@ struct _GstRTSPMedia {
gboolean shared; gboolean shared;
gboolean reusable; gboolean reusable;
gboolean reused; gboolean reused;
gboolean is_ipv6;
GstElement *element; GstElement *element;
GArray *streams; GArray *streams;

View file

@ -22,16 +22,18 @@
/** /**
* gst_rtsp_sdp_from_media: * gst_rtsp_sdp_from_media:
* @sdp: a #GstSDPessage
* @info: info
* @media: a #GstRTSPMedia * @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 * gboolean
gst_rtsp_sdp_from_media (GstRTSPMedia * media) gst_rtsp_sdp_from_media (GstSDPMessage *sdp, GstSDPInfo *info, GstRTSPMedia * media)
{ {
GstSDPMessage *sdp;
guint i, n_streams; guint i, n_streams;
gchar *rangestr; gchar *rangestr;
@ -40,19 +42,6 @@ gst_rtsp_sdp_from_media (GstRTSPMedia * media)
n_streams = gst_rtsp_media_n_streams (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); rangestr = gst_rtsp_range_to_string (&media->range);
gst_sdp_message_add_attribute (sdp, "range", rangestr); gst_sdp_message_add_attribute (sdp, "range", rangestr);
g_free (rangestr); g_free (rangestr);
@ -96,7 +85,7 @@ gst_rtsp_sdp_from_media (GstRTSPMedia * media)
gst_sdp_media_set_proto (smedia, "RTP/AVP"); gst_sdp_media_set_proto (smedia, "RTP/AVP");
/* for the c= line */ /* 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 */ /* get clock-rate, media type and params for the rtpmap attribute */
gst_structure_get_int (s, "clock-rate", &caps_rate); 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); gst_sdp_media_free (smedia);
} }
return sdp; return TRUE;
/* ERRORS */ /* ERRORS */
not_prepared: not_prepared:
{ {
GST_ERROR ("media %p is not prepared", media); GST_ERROR ("media %p is not prepared", media);
return NULL; return FALSE;
} }
} }

View file

@ -27,8 +27,13 @@
G_BEGIN_DECLS G_BEGIN_DECLS
typedef struct {
const gchar *server_proto;
const gchar *server_ip;
} GstSDPInfo;
/* creating SDP */ /* 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 G_END_DECLS

View file

@ -425,7 +425,7 @@ gst_rtsp_server_sink_init_send (GstRTSPServer * server)
memset(&hints, 0, sizeof(struct addrinfo)); memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_STREAM; /* stream socket */ 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_protocol = 0; /* Any protocol */
hints.ai_canonname = NULL; hints.ai_canonname = NULL;
hints.ai_addr = NULL; hints.ai_addr = NULL;
@ -446,8 +446,10 @@ gst_rtsp_server_sink_init_send (GstRTSPServer * server)
continue; 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; break;
}
GST_DEBUG_OBJECT (server, "failed to bind socket (%s), try next", g_strerror (errno)); GST_DEBUG_OBJECT (server, "failed to bind socket (%s), try next", g_strerror (errno));
close (sockfd); close (sockfd);
@ -654,7 +656,7 @@ gst_rtsp_server_create_watch (GstRTSPServer *server)
channel = gst_rtsp_server_get_io_channel (server); channel = gst_rtsp_server_get_io_channel (server);
if (channel == NULL) if (channel == NULL)
goto no_channel; goto no_channel;
/* create a watch for reads (new connections) and possible errors */ /* create a watch for reads (new connections) and possible errors */
server->io_watch = g_io_create_watch (channel, G_IO_IN | server->io_watch = g_io_create_watch (channel, G_IO_IN |
G_IO_ERR | G_IO_HUP | G_IO_NVAL); 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 * This function should be called when the server properties and urls are fully
* configured and the server is ready to start. * 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 guint
gst_rtsp_server_attach (GstRTSPServer *server, GMainContext *context) gst_rtsp_server_attach (GstRTSPServer *server, GMainContext *context)