From 1beeda3ff2859372cecbea4542a4da8dc05960d6 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 25 Apr 2007 08:36:46 +0000 Subject: [PATCH] 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. --- ChangeLog | 13 +++++ .../gst-plugins-good-plugins-sections.txt | 1 + gst/rtsp/gstrtspsrc.c | 58 ++++++++++++++++++- gst/rtsp/gstrtspsrc.h | 2 + gst/rtsp/rtsptransport.h | 38 ++++++++++++ 5 files changed, 110 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3792b66b1f..4de511e016 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2007-04-25 Wim Taymans + + * 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 * gst/wavparse/gstwavparse.c: (gst_wavparse_stream_headers): diff --git a/docs/plugins/gst-plugins-good-plugins-sections.txt b/docs/plugins/gst-plugins-good-plugins-sections.txt index d8e572b3e1..86ba73313f 100644 --- a/docs/plugins/gst-plugins-good-plugins-sections.txt +++ b/docs/plugins/gst-plugins-good-plugins-sections.txt @@ -489,6 +489,7 @@ gst_progress_report_get_type
element-rtspsrc +RTSPLowerTrans GstRTSPSrc rtspsrc diff --git a/gst/rtsp/gstrtspsrc.c b/gst/rtsp/gstrtspsrc.c index db0c36ae6d..066a17d2e5 100644 --- a/gst/rtsp/gstrtspsrc.c +++ b/gst/rtsp/gstrtspsrc.c @@ -311,6 +311,7 @@ gst_rtspsrc_finalize (GObject * object) g_free (rtspsrc->req_location); g_free (rtspsrc->content_base); rtsp_url_free (rtspsrc->url); + g_free (rtspsrc->addr); if (rtspsrc->extension) { #ifdef WITH_EXT_REAL @@ -556,6 +557,12 @@ gst_rtspsrc_stream_free (GstRTSPSrc * src, GstRTSPStream * stream) 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) { gst_pad_set_active (stream->srcpad, FALSE); if (stream->added) { @@ -1086,6 +1093,8 @@ request_pt_map (GstElement * sess, guint session, guint pt, GstRTSPSrc * src) GstRTSPStream *stream; 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), (GCompareFunc) find_stream_by_id); if (!lstream) @@ -1093,8 +1102,6 @@ request_pt_map (GstElement * sess, guint session, guint pt, GstRTSPSrc * src) stream = (GstRTSPStream *) lstream->data; - GST_DEBUG_OBJECT (src, "getting pt map for pt %d in session %d", pt, session); - return stream->caps; unknown_stream: @@ -1312,6 +1319,38 @@ use_no_manager: 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) { @@ -1365,6 +1404,11 @@ no_element: GST_DEBUG_OBJECT (src, "no UDP source element found"); return FALSE; } +no_sink_element: + { + GST_DEBUG_OBJECT (src, "no UDP sink element found"); + return FALSE; + } start_session_failure: { GST_DEBUG_OBJECT (src, "could not start session"); @@ -2570,6 +2614,16 @@ gst_rtspsrc_open (GstRTSPSrc * src) if (src->extension && src->extension->parse_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 */ n_streams = sdp_message_medias_len (&sdp); for (i = 0; i < n_streams; i++) { diff --git a/gst/rtsp/gstrtspsrc.h b/gst/rtsp/gstrtspsrc.h index 19cf7f1c2a..c35c94341b 100644 --- a/gst/rtsp/gstrtspsrc.h +++ b/gst/rtsp/gstrtspsrc.h @@ -96,6 +96,7 @@ struct _GstRTSPStream { /* our udp sink back to the server */ GstElement *udpsink; + GstPad *rtcppad; /* state */ gint pt; @@ -142,6 +143,7 @@ struct _GstRTSPSrc { gchar *content_base; RTSPLowerTrans cur_protocols; gboolean tried_url_auth; + gchar *addr; /* supported methods */ gint methods; diff --git a/gst/rtsp/rtsptransport.h b/gst/rtsp/rtsptransport.h index 76e291058b..0581839108 100644 --- a/gst/rtsp/rtsptransport.h +++ b/gst/rtsp/rtsptransport.h @@ -47,18 +47,43 @@ 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 { RTSP_TRANS_UNKNOWN = 0, RTSP_TRANS_RTP = (1 << 0), RTSP_TRANS_RDT = (1 << 1) } 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 { RTSP_PROFILE_UNKNOWN = 0, RTSP_PROFILE_AVP = (1 << 0), RTSP_PROFILE_SAVP = (1 << 1) } 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 { RTSP_LOWER_TRANS_UNKNOWN = 0, RTSP_LOWER_TRANS_UDP = (1 << 0), @@ -66,13 +91,26 @@ typedef enum { RTSP_LOWER_TRANS_TCP = (1 << 2) } RTSPLowerTrans; +/** + * RTSPRange: + * @min: minimum value of the range + * @max: maximum value of the range + * + * A type to specify a range. + */ typedef struct { gint min; gint max; } RTSPRange; +/** + * RTSPTransport: + * + * A structure holding the RTSP transport values. + */ typedef struct _RTSPTransport { + /*< private >*/ RTSPTransMode trans; RTSPProfile profile; RTSPLowerTrans lower_transport;