diff options
| -rw-r--r-- | ChangeLog | 13 | ||||
| -rw-r--r-- | gst/rtsp/gstrtspsrc.c | 191 | ||||
| -rw-r--r-- | gst/rtsp/sdpmessage.c | 8 | ||||
| -rw-r--r-- | gst/rtsp/sdpmessage.h | 1 | 
4 files changed, 204 insertions, 9 deletions
| @@ -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, ¶ms); +    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 | 
