gst/rtsp/gstrtspsrc.*: Parse server address from SDP.

Original commit message from CVS:
* gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_finalize),
(gst_rtspsrc_stream_free), (request_pt_map),
(gst_rtspsrc_stream_configure_transport), (gst_rtspsrc_open):
* gst/rtsp/gstrtspsrc.h:
Parse server address from SDP.
Hook up a udpsink to send RTCP back to the server.
* docs/plugins/gst-plugins-good-plugins-sections.txt:
* gst/rtsp/rtsptransport.h:
Add some docs.
This commit is contained in:
Wim Taymans 2007-04-25 08:36:46 +00:00
parent fa7454bda2
commit 1beeda3ff2
5 changed files with 110 additions and 2 deletions

View file

@ -1,3 +1,16 @@
2007-04-25 Wim Taymans <wim@fluendo.com>
* gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_finalize),
(gst_rtspsrc_stream_free), (request_pt_map),
(gst_rtspsrc_stream_configure_transport), (gst_rtspsrc_open):
* gst/rtsp/gstrtspsrc.h:
Parse server address from SDP.
Hook up a udpsink to send RTCP back to the server.
* docs/plugins/gst-plugins-good-plugins-sections.txt:
* gst/rtsp/rtsptransport.h:
Add some docs.
2007-04-25 Stefan Kost <ensonic@users.sf.net> 2007-04-25 Stefan Kost <ensonic@users.sf.net>
* gst/wavparse/gstwavparse.c: (gst_wavparse_stream_headers): * gst/wavparse/gstwavparse.c: (gst_wavparse_stream_headers):

View file

@ -489,6 +489,7 @@ gst_progress_report_get_type
<SECTION> <SECTION>
<FILE>element-rtspsrc</FILE> <FILE>element-rtspsrc</FILE>
RTSPLowerTrans
GstRTSPSrc GstRTSPSrc
<TITLE>rtspsrc</TITLE> <TITLE>rtspsrc</TITLE>
<SUBSECTION Standard> <SUBSECTION Standard>

View file

@ -311,6 +311,7 @@ gst_rtspsrc_finalize (GObject * object)
g_free (rtspsrc->req_location); g_free (rtspsrc->req_location);
g_free (rtspsrc->content_base); g_free (rtspsrc->content_base);
rtsp_url_free (rtspsrc->url); rtsp_url_free (rtspsrc->url);
g_free (rtspsrc->addr);
if (rtspsrc->extension) { if (rtspsrc->extension) {
#ifdef WITH_EXT_REAL #ifdef WITH_EXT_REAL
@ -556,6 +557,12 @@ gst_rtspsrc_stream_free (GstRTSPSrc * src, GstRTSPStream * stream)
stream->udpsrc[i] = NULL; stream->udpsrc[i] = NULL;
} }
} }
if (stream->udpsink) {
gst_element_set_state (stream->udpsink, GST_STATE_NULL);
gst_bin_remove (GST_BIN_CAST (src), stream->udpsink);
gst_object_unref (stream->udpsink);
stream->udpsink = NULL;
}
if (stream->srcpad) { if (stream->srcpad) {
gst_pad_set_active (stream->srcpad, FALSE); gst_pad_set_active (stream->srcpad, FALSE);
if (stream->added) { if (stream->added) {
@ -1086,6 +1093,8 @@ request_pt_map (GstElement * sess, guint session, guint pt, GstRTSPSrc * src)
GstRTSPStream *stream; GstRTSPStream *stream;
GList *lstream; GList *lstream;
GST_DEBUG_OBJECT (src, "getting pt map for pt %d in session %d", pt, session);
lstream = g_list_find_custom (src->streams, GINT_TO_POINTER (session), lstream = g_list_find_custom (src->streams, GINT_TO_POINTER (session),
(GCompareFunc) find_stream_by_id); (GCompareFunc) find_stream_by_id);
if (!lstream) if (!lstream)
@ -1093,8 +1102,6 @@ request_pt_map (GstElement * sess, guint session, guint pt, GstRTSPSrc * src)
stream = (GstRTSPStream *) lstream->data; stream = (GstRTSPStream *) lstream->data;
GST_DEBUG_OBJECT (src, "getting pt map for pt %d in session %d", pt, session);
return stream->caps; return stream->caps;
unknown_stream: unknown_stream:
@ -1312,6 +1319,38 @@ use_no_manager:
gst_object_unref (pad); gst_object_unref (pad);
} }
} }
/* configure udpsink back to the server for RTCP messages. */
{
GstPad *pad;
stream->udpsink = gst_element_factory_make ("udpsink", NULL);
if (stream->udpsink == NULL)
goto no_sink_element;
/* we keep this playing always */
gst_element_set_locked_state (stream->udpsink, TRUE);
gst_element_set_state (stream->udpsink, GST_STATE_PLAYING);
/* 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);
stream->rtcppad = gst_element_get_pad (stream->udpsink, "sink");
/* get session RTCP pad */
name = g_strdup_printf ("rtcp_src_%d", stream->id);
pad = gst_element_get_request_pad (src->session, name);
g_free (name);
/* and link */
gst_pad_link (pad, stream->rtcppad);
}
} }
if (src->session && !src->session_sig_id) { if (src->session && !src->session_sig_id) {
@ -1365,6 +1404,11 @@ no_element:
GST_DEBUG_OBJECT (src, "no UDP source element found"); GST_DEBUG_OBJECT (src, "no UDP source element found");
return FALSE; return FALSE;
} }
no_sink_element:
{
GST_DEBUG_OBJECT (src, "no UDP sink element found");
return FALSE;
}
start_session_failure: start_session_failure:
{ {
GST_DEBUG_OBJECT (src, "could not start session"); GST_DEBUG_OBJECT (src, "could not start session");
@ -2570,6 +2614,16 @@ gst_rtspsrc_open (GstRTSPSrc * src)
if (src->extension && src->extension->parse_sdp) if (src->extension && src->extension->parse_sdp)
src->extension->parse_sdp (src->extension, &sdp); src->extension->parse_sdp (src->extension, &sdp);
/* parse address */
{
SDPOrigin *origin;
origin = sdp_message_get_origin (&sdp);
g_free (src->addr);
src->addr = g_strdup (origin->addr);
}
/* create streams */ /* create streams */
n_streams = sdp_message_medias_len (&sdp); n_streams = sdp_message_medias_len (&sdp);
for (i = 0; i < n_streams; i++) { for (i = 0; i < n_streams; i++) {

View file

@ -96,6 +96,7 @@ struct _GstRTSPStream {
/* our udp sink back to the server */ /* our udp sink back to the server */
GstElement *udpsink; GstElement *udpsink;
GstPad *rtcppad;
/* state */ /* state */
gint pt; gint pt;
@ -142,6 +143,7 @@ struct _GstRTSPSrc {
gchar *content_base; gchar *content_base;
RTSPLowerTrans cur_protocols; RTSPLowerTrans cur_protocols;
gboolean tried_url_auth; gboolean tried_url_auth;
gchar *addr;
/* supported methods */ /* supported methods */
gint methods; gint methods;

View file

@ -47,18 +47,43 @@
G_BEGIN_DECLS G_BEGIN_DECLS
/**
* RTSPTransMode:
* @RTSP_TRANS_UNKNOWN: invalid tansport mode
* @RTSP_TRANS_RTP: transfer RTP data
* @RTSP_TRANS_RDT: transfer RDT (RealMedia) data
*
* The transfer mode to use.
*/
typedef enum { typedef enum {
RTSP_TRANS_UNKNOWN = 0, RTSP_TRANS_UNKNOWN = 0,
RTSP_TRANS_RTP = (1 << 0), RTSP_TRANS_RTP = (1 << 0),
RTSP_TRANS_RDT = (1 << 1) RTSP_TRANS_RDT = (1 << 1)
} RTSPTransMode; } RTSPTransMode;
/**
* RTSPProfile:
* @RTSP_PROFILE_UNKNOWN: invalid profile
* @RTSP_PROFILE_AVP: the Audio/Visual profile
* @RTSP_PROFILE_SAVP: the secure Audio/Visual profile
*
* The transfer profile to use.
*/
typedef enum { typedef enum {
RTSP_PROFILE_UNKNOWN = 0, RTSP_PROFILE_UNKNOWN = 0,
RTSP_PROFILE_AVP = (1 << 0), RTSP_PROFILE_AVP = (1 << 0),
RTSP_PROFILE_SAVP = (1 << 1) RTSP_PROFILE_SAVP = (1 << 1)
} RTSPProfile; } RTSPProfile;
/**
* RTSPLowerTrans:
* @RTSP_LOWER_TRANS_UNKNOWN: invalid transport flag
* @RTSP_LOWER_TRANS_UDP: stream data over UDP
* @RTSP_LOWER_TRANS_UDP_MCAST: stream data over UDP multicast
* @RTSP_LOWER_TRANS_TCP: stream data over TCP
*
* The different transport methods.
*/
typedef enum { typedef enum {
RTSP_LOWER_TRANS_UNKNOWN = 0, RTSP_LOWER_TRANS_UNKNOWN = 0,
RTSP_LOWER_TRANS_UDP = (1 << 0), RTSP_LOWER_TRANS_UDP = (1 << 0),
@ -66,13 +91,26 @@ typedef enum {
RTSP_LOWER_TRANS_TCP = (1 << 2) RTSP_LOWER_TRANS_TCP = (1 << 2)
} RTSPLowerTrans; } RTSPLowerTrans;
/**
* RTSPRange:
* @min: minimum value of the range
* @max: maximum value of the range
*
* A type to specify a range.
*/
typedef struct typedef struct
{ {
gint min; gint min;
gint max; gint max;
} RTSPRange; } RTSPRange;
/**
* RTSPTransport:
*
* A structure holding the RTSP transport values.
*/
typedef struct _RTSPTransport { typedef struct _RTSPTransport {
/*< private >*/
RTSPTransMode trans; RTSPTransMode trans;
RTSPProfile profile; RTSPProfile profile;
RTSPLowerTrans lower_transport; RTSPLowerTrans lower_transport;