summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2005-09-20 17:35:11 +0000
committerWim Taymans <wim.taymans@gmail.com>2005-09-20 17:35:11 +0000
commiteb20f045f8fcbf9e6459cb7d7c608acb72c5f8b6 (patch)
tree452df9e0f9e5b13241ec8e429f17712ce21229ca
parent69821962183662a9abeca8297233aa8eb738cd84 (diff)
gst/rtsp/: Add URI handler.
Original commit message from CVS: * gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_get_type), (gst_rtspsrc_parse_rtpmap), (gst_rtspsrc_media_to_caps), (gst_rtspsrc_stream_setup_rtp), (gst_rtspsrc_send), (gst_rtspsrc_open), (gst_rtspsrc_uri_get_type), (gst_rtspsrc_uri_get_protocols), (gst_rtspsrc_uri_get_uri), (gst_rtspsrc_uri_set_uri), (gst_rtspsrc_uri_handler_init): * gst/rtsp/sdpmessage.c: (sdp_media_get_format): * gst/rtsp/sdpmessage.h: Add URI handler. Parse SDP and create caps.
-rw-r--r--ChangeLog13
-rw-r--r--gst/rtsp/gstrtspsrc.c191
-rw-r--r--gst/rtsp/sdpmessage.c8
-rw-r--r--gst/rtsp/sdpmessage.h1
4 files changed, 204 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 75b77784..4ea6c7fe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2005-09-20 Wim Taymans <wim@fluendo.com>
+
+ * gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_get_type),
+ (gst_rtspsrc_parse_rtpmap), (gst_rtspsrc_media_to_caps),
+ (gst_rtspsrc_stream_setup_rtp), (gst_rtspsrc_send),
+ (gst_rtspsrc_open), (gst_rtspsrc_uri_get_type),
+ (gst_rtspsrc_uri_get_protocols), (gst_rtspsrc_uri_get_uri),
+ (gst_rtspsrc_uri_set_uri), (gst_rtspsrc_uri_handler_init):
+ * gst/rtsp/sdpmessage.c: (sdp_media_get_format):
+ * gst/rtsp/sdpmessage.h:
+ Add URI handler.
+ Parse SDP and create caps.
+
2005-09-20 Stefan Kost <ensonic@users.sf.net>
* gst/alpha/gstalpha.c:
diff --git a/gst/rtsp/gstrtspsrc.c b/gst/rtsp/gstrtspsrc.c
index db155647..106e568a 100644
--- a/gst/rtsp/gstrtspsrc.c
+++ b/gst/rtsp/gstrtspsrc.c
@@ -88,6 +88,9 @@ static void gst_rtspsrc_base_init (gpointer g_class);
static void gst_rtspsrc_class_init (GstRTSPSrc * klass);
static void gst_rtspsrc_init (GstRTSPSrc * rtspsrc);
+static void gst_rtspsrc_uri_handler_init (gpointer g_iface,
+ gpointer iface_data);
+
static GstStateChangeReturn gst_rtspsrc_change_state (GstElement * element,
GstStateChange transition);
@@ -120,10 +123,18 @@ gst_rtspsrc_get_type (void)
(GInstanceInitFunc) gst_rtspsrc_init,
NULL
};
+ static const GInterfaceInfo urihandler_info = {
+ gst_rtspsrc_uri_handler_init,
+ NULL,
+ NULL
+ };
rtspsrc_type =
g_type_register_static (GST_TYPE_ELEMENT, "GstRTSPSrc", &rtspsrc_info,
0);
+
+ g_type_add_interface_static (rtspsrc_type, GST_TYPE_URI_HANDLER,
+ &urihandler_info);
}
return rtspsrc_type;
}
@@ -289,11 +300,125 @@ done:
}
static gboolean
-gst_rtspsrc_stream_setup_rtp (GstRTSPStream * stream, gint * rtpport,
- gint * rtcpport)
+gst_rtspsrc_parse_rtpmap (gchar * rtpmap, gint * payload, gchar ** name,
+ gint * rate, gchar ** params)
+{
+ gchar *p, *t;
+
+ t = p = rtpmap;
+
+ p = strstr (p, " ");
+ if (p == NULL)
+ return FALSE;
+ *p = '\0';
+ p++;
+
+ *payload = atoi (t);
+
+ while (*p && g_ascii_isspace (*p))
+ p++;
+
+ if (*p == '\0')
+ return FALSE;
+
+ t = p;
+ p = strstr (p, "/");
+ if (p == NULL)
+ return FALSE;
+ *p = '\0';
+ p++;
+ *name = t;
+
+ t = p;
+ p = strstr (p, "/");
+ if (p == NULL) {
+ *rate = atoi (t);
+ return TRUE;
+ }
+ *p = '\0';
+ p++;
+ *rate = atoi (t);
+
+ t = p;
+ if (*p == '\0')
+ return TRUE;
+ *params = t;
+
+ return TRUE;
+}
+
+/*
+ * Mapping of caps to and from SDP fields:
+ *
+ * m=<media> <udp port> RTP/AVP <payload>
+ * a=rtpmap:<payload> <encoding_name>/<clock_rate>[/<encoding_params>]
+ * a=fmtp:<payload> <param>=<value>;...
+ */
+static GstCaps *
+gst_rtspsrc_media_to_caps (SDPMedia * media)
+{
+ GstCaps *caps;
+ gchar *payload;
+ gchar *rtpmap;
+
+ //gchar *fmtp;
+ gint pt;
+ gchar *name = NULL;
+ gint rate = -1;
+ gchar *params = NULL;
+ GstStructure *s;
+
+ payload = sdp_media_get_format (media, 0);
+ if (payload == NULL) {
+ g_warning ("payload type not given");
+ return NULL;
+ }
+ pt = atoi (payload);
+
+ if (pt >= 96) {
+ gint payload = 0;
+ gboolean ret;
+
+ rtpmap = sdp_media_get_attribute_val (media, "rtpmap");
+ if (rtpmap == NULL) {
+ g_warning ("rtpmap type not given");
+ return NULL;
+ }
+ ret = gst_rtspsrc_parse_rtpmap (rtpmap, &payload, &name, &rate, &params);
+ if (!ret) {
+ g_warning ("error parsing rtpmap");
+ }
+ if (payload != pt) {
+ g_warning ("rtpmap of wrong payload type");
+ name = NULL;
+ rate = -1;
+ params = NULL;
+ }
+ }
+
+ caps = gst_caps_new_simple ("application/x-rtp",
+ "media", G_TYPE_STRING, media->media, "payload", G_TYPE_INT, pt, NULL);
+ s = gst_caps_get_structure (caps, 0);
+
+ if (rate != -1)
+ gst_structure_set (s, "clock-rate", G_TYPE_INT, rate, NULL);
+
+ if (name != NULL)
+ gst_structure_set (s, "encoding-name", G_TYPE_STRING, name, NULL);
+
+ if (params != NULL)
+ gst_structure_set (s, "encoding-params", G_TYPE_STRING, params, NULL);
+
+ return caps;
+}
+
+static gboolean
+gst_rtspsrc_stream_setup_rtp (GstRTSPStream * stream, SDPMedia * media,
+ gint * rtpport, gint * rtcpport)
{
GstStateChangeReturn ret;
GstRTSPSrc *src;
+ GstCaps *caps;
src = stream->parent;
@@ -319,6 +444,10 @@ gst_rtspsrc_stream_setup_rtp (GstRTSPStream * stream, gint * rtpport,
if (ret == GST_STATE_CHANGE_FAILURE)
goto start_rtcp_failure;
+ caps = gst_rtspsrc_media_to_caps (media);
+
+ g_object_set (G_OBJECT (stream->rtpsrc), "caps", caps, NULL);
+
g_object_get (G_OBJECT (stream->rtpsrc), "port", rtpport, NULL);
g_object_get (G_OBJECT (stream->rtcpsrc), "port", rtcpport, NULL);
@@ -514,12 +643,11 @@ gst_rtspsrc_send (GstRTSPSrc * src, RTSPMessage * request,
*code = response->type_data.response.code;
}
- if (response->type_data.response.code != RTSP_STS_OK)
- goto error_response;
-
if (src->debug) {
rtsp_message_dump (response);
}
+ if (response->type_data.response.code != RTSP_STS_OK)
+ goto error_response;
return TRUE;
@@ -537,9 +665,9 @@ receive_error:
}
error_response:
{
- rtsp_message_dump (request);
- rtsp_message_dump (response);
- GST_ELEMENT_ERROR (src, RESOURCE, READ, ("Got error response."), (NULL));
+ GST_ELEMENT_ERROR (src, RESOURCE, READ, ("Got error response: %d (%s).",
+ response->type_data.response.code,
+ response->type_data.response.reason), (NULL));
return FALSE;
}
}
@@ -706,7 +834,7 @@ gst_rtspsrc_open (GstRTSPSrc * src)
gchar *trxparams;
/* allocate two udp ports */
- if (!gst_rtspsrc_stream_setup_rtp (stream, &rtpport, &rtcpport))
+ if (!gst_rtspsrc_stream_setup_rtp (stream, media, &rtpport, &rtcpport))
goto setup_rtp_failed;
trxparams = g_strdup_printf ("client_port=%d-%d", rtpport, rtcpport);
@@ -1022,3 +1150,48 @@ open_failed:
return GST_STATE_CHANGE_FAILURE;
}
}
+
+/*** GSTURIHANDLER INTERFACE *************************************************/
+
+static guint
+gst_rtspsrc_uri_get_type (void)
+{
+ return GST_URI_SRC;
+}
+static gchar **
+gst_rtspsrc_uri_get_protocols (void)
+{
+ static gchar *protocols[] = { "rtsp", NULL };
+
+ return protocols;
+}
+
+static const gchar *
+gst_rtspsrc_uri_get_uri (GstURIHandler * handler)
+{
+ GstRTSPSrc *src = GST_RTSPSRC (handler);
+
+ return g_strdup (src->location);
+}
+
+static gboolean
+gst_rtspsrc_uri_set_uri (GstURIHandler * handler, const gchar * uri)
+{
+ GstRTSPSrc *src = GST_RTSPSRC (handler);
+
+ g_free (src->location);
+ src->location = g_strdup (uri);
+
+ return TRUE;
+}
+
+static void
+gst_rtspsrc_uri_handler_init (gpointer g_iface, gpointer iface_data)
+{
+ GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
+
+ iface->get_type = gst_rtspsrc_uri_get_type;
+ iface->get_protocols = gst_rtspsrc_uri_get_protocols;
+ iface->get_uri = gst_rtspsrc_uri_get_uri;
+ iface->set_uri = gst_rtspsrc_uri_set_uri;
+}
diff --git a/gst/rtsp/sdpmessage.c b/gst/rtsp/sdpmessage.c
index 16dd84a7..76dd73d7 100644
--- a/gst/rtsp/sdpmessage.c
+++ b/gst/rtsp/sdpmessage.c
@@ -399,6 +399,14 @@ sdp_media_get_attribute_val (SDPMedia * media, gchar * key)
return NULL;
}
+gchar *
+sdp_media_get_format (SDPMedia * media, gint i)
+{
+ if (i >= media->fmts->len)
+ return NULL;
+ return g_array_index (media->fmts, gchar *, i);
+}
+
static void
read_string (gchar * dest, gint size, gchar ** src)
{
diff --git a/gst/rtsp/sdpmessage.h b/gst/rtsp/sdpmessage.h
index 64b8ed94..450bdced 100644
--- a/gst/rtsp/sdpmessage.h
+++ b/gst/rtsp/sdpmessage.h
@@ -158,6 +158,7 @@ RTSPResult sdp_media_clean (SDPMedia *media);
RTSPResult sdp_media_free (SDPMedia *media);
gchar* sdp_media_get_attribute_val (SDPMedia *media, gchar *key);
+gchar* sdp_media_get_format (SDPMedia *media, gint i);
G_END_DECLS