From: <wt...@ke...> - 2006-10-04 17:24:54
|
CVS Root: /cvs/gstreamer Module: gst-plugins-good Changes by: wtay Date: Wed Oct 04 2006 17:24:52 UTC Log message: * gst/rtsp/Makefile.am: * gst/rtsp/gstrtpdec.c: (gst_rtpdec_getcaps), (gst_rtpdec_chain_rtp), (gst_rtpdec_chain_rtcp): * gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_init), (gst_rtspsrc_finalize), (gst_rtspsrc_create_stream), (gst_rtspsrc_parse_rtpmap), (gst_rtspsrc_stream_configure_transport), (gst_rtspsrc_send), (gst_rtspsrc_parse_methods), (gst_rtspsrc_open), (gst_rtspsrc_play), (gst_rtspsrc_handle_message): * gst/rtsp/gstrtspsrc.h: * gst/rtsp/rtspdefs.c: (rtsp_strresult): * gst/rtsp/rtspdefs.h: * gst/rtsp/rtspext.h: * gst/rtsp/rtspextwms.c: (rtsp_ext_wms_parse_sdp), (rtsp_ext_wms_get_context): * gst/rtsp/rtspextwms.h: * gst/rtsp/rtsptransport.c: (rtsp_transport_init), (parse_mode), (rtsp_transport_parse): * gst/rtsp/rtsptransport.h: Factor out extension in separate module. Fix getcaps to filter against the padtemplate. Use Content-Base if the server gives one. Rework the transport parsing a bit for future extensions. Added some Real Header field definitions. Modified files: . : ChangeLog gst/rtsp : Makefile.am gstrtpdec.c gstrtspsrc.c gstrtspsrc.h rtspdefs.c rtspdefs.h rtsptransport.c rtsptransport.h Added files: gst/rtsp : rtspext.h rtspextwms.c rtspextwms.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-good/ChangeLog.diff?r1=1.2574&r2=1.2575 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-good/gst/rtsp/Makefile.am.diff?r1=1.6&r2=1.7 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-good/gst/rtsp/gstrtpdec.c.diff?r1=1.9&r2=1.10 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-good/gst/rtsp/gstrtspsrc.c.diff?r1=1.43&r2=1.44 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-good/gst/rtsp/gstrtspsrc.h.diff?r1=1.17&r2=1.18 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-good/gst/rtsp/rtspdefs.c.diff?r1=1.6&r2=1.7 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-good/gst/rtsp/rtspdefs.h.diff?r1=1.9&r2=1.10 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-good/gst/rtsp/rtspext.h?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-good/gst/rtsp/rtspextwms.c?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-good/gst/rtsp/rtspextwms.h?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-good/gst/rtsp/rtsptransport.c.diff?r1=1.7&r2=1.8 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-good/gst/rtsp/rtsptransport.h.diff?r1=1.3&r2=1.4 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-good/ChangeLog,v retrieving revision 1.2574 retrieving revision 1.2575 diff -u -d -r1.2574 -r1.2575 --- ChangeLog 4 Oct 2006 10:29:11 -0000 1.2574 +++ ChangeLog 4 Oct 2006 17:24:40 -0000 1.2575 @@ -1,3 +1,30 @@ +2006-10-04 Wim Taymans <wi...@fl...> + + * gst/rtsp/Makefile.am: + * gst/rtsp/gstrtpdec.c: (gst_rtpdec_getcaps), + (gst_rtpdec_chain_rtp), (gst_rtpdec_chain_rtcp): + * gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_init), + (gst_rtspsrc_finalize), (gst_rtspsrc_create_stream), + (gst_rtspsrc_parse_rtpmap), + (gst_rtspsrc_stream_configure_transport), (gst_rtspsrc_send), + (gst_rtspsrc_parse_methods), (gst_rtspsrc_open), + (gst_rtspsrc_play), (gst_rtspsrc_handle_message): + * gst/rtsp/gstrtspsrc.h: + * gst/rtsp/rtspdefs.c: (rtsp_strresult): + * gst/rtsp/rtspdefs.h: + * gst/rtsp/rtspext.h: + * gst/rtsp/rtspextwms.c: (rtsp_ext_wms_parse_sdp), + (rtsp_ext_wms_get_context): + * gst/rtsp/rtspextwms.h: + * gst/rtsp/rtsptransport.c: (rtsp_transport_init), (parse_mode), + (rtsp_transport_parse): + * gst/rtsp/rtsptransport.h: + Factor out extension in separate module. + Fix getcaps to filter against the padtemplate. + Use Content-Base if the server gives one. + Rework the transport parsing a bit for future extensions. + Added some Real Header field definitions. 2006-10-04 Thomas Vander Stichele <thomas at apestaart dot org> * docs/plugins/Makefile.am: Index: Makefile.am RCS file: /cvs/gstreamer/gst-plugins-good/gst/rtsp/Makefile.am,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- Makefile.am 10 Jul 2006 16:41:57 -0000 1.6 +++ Makefile.am 4 Oct 2006 17:24:40 -0000 1.7 @@ -4,6 +4,7 @@ gstrtpdec.c \ rtspconnection.c \ rtspdefs.c \ + rtspextwms.c \ rtspmessage.c \ rtsptransport.c \ rtspurl.c \ @@ -19,4 +20,4 @@ test_CFLAGS = $(GST_CFLAGS) test_LDFLAGS = $(GST_LIBS) $(WIN32_LIBS) -noinst_HEADERS = gstrtspsrc.h gstrtsp.h gstrtpdec.h rtsptransport.h rtsp.h rtspurl.h rtspconnection.h rtspdefs.h rtspmessage.h sdp.h sdpmessage.h +noinst_HEADERS = gstrtspsrc.h gstrtsp.h gstrtpdec.h rtsptransport.h rtsp.h rtspurl.h rtspconnection.h rtspdefs.h rtspmessage.h sdp.h sdpmessage.h rtspextwms.h Index: gstrtpdec.c RCS file: /cvs/gstreamer/gst-plugins-good/gst/rtsp/gstrtpdec.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- gstrtpdec.c 20 Sep 2006 16:06:27 -0000 1.9 +++ gstrtpdec.c 4 Oct 2006 17:24:40 -0000 1.10 @@ -222,6 +222,7 @@ GstRTPDec *src; GstPad *other; GstCaps *caps; + const GstCaps *templ; src = GST_RTPDEC (GST_PAD_PARENT (pad)); @@ -229,8 +230,20 @@ caps = gst_pad_peer_get_caps (other); - if (caps == NULL) - caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad)); + templ = gst_pad_get_pad_template_caps (pad); + if (caps == NULL) { + GST_DEBUG_OBJECT (src, "copy template"); + caps = gst_caps_copy (templ); + } else { + GstCaps *intersect; + GST_DEBUG_OBJECT (src, "intersect with template"); + intersect = gst_caps_intersect (caps, templ); + gst_caps_unref (caps); + caps = intersect; + } return caps; } @@ -242,14 +255,18 @@ - GST_DEBUG ("got rtp packet"); + GST_DEBUG_OBJECT (src, "got rtp packet"); return gst_pad_push (src->src_rtp, buffer); static GstFlowReturn gst_rtpdec_chain_rtcp (GstPad * pad, GstBuffer * buffer) { - GST_DEBUG ("got rtcp packet"); + GstRTPDec *src; + src = GST_RTPDEC (GST_PAD_PARENT (pad)); + GST_DEBUG_OBJECT (src, "got rtcp packet"); gst_buffer_unref (buffer); return GST_FLOW_OK; Index: gstrtspsrc.c RCS file: /cvs/gstreamer/gst-plugins-good/gst/rtsp/gstrtspsrc.c,v retrieving revision 1.43 retrieving revision 1.44 diff -u -d -r1.43 -r1.44 --- gstrtspsrc.c 29 Sep 2006 15:37:29 -0000 1.43 +++ gstrtspsrc.c 4 Oct 2006 17:24:40 -0000 1.44 @@ -95,6 +95,8 @@ #include "gstrtspsrc.h" #include "sdp.h" +#include "rtspextwms.h" GST_DEBUG_CATEGORY_STATIC (rtspsrc_debug); #define GST_CAT_DEFAULT (rtspsrc_debug) @@ -265,8 +267,12 @@ src->loop_cond = g_cond_new (); - src->location = DEFAULT_LOCATION; + src->location = g_strdup (DEFAULT_LOCATION); src->url = NULL; + /* install WMS extension by default */ + src->extension = rtsp_ext_wms_get_context (); + src->extension->src = (gpointer) src; static void @@ -279,6 +285,9 @@ g_static_rec_mutex_free (rtspsrc->stream_rec_lock); g_free (rtspsrc->stream_rec_lock); g_cond_free (rtspsrc->loop_cond); + g_free (rtspsrc->location); + g_free (rtspsrc->content_base); + rtsp_url_free (rtspsrc->url); G_OBJECT_CLASS (parent_class)->finalize (object); @@ -409,6 +418,9 @@ /* check absolute/relative URL */ if (g_str_has_prefix (control_url, "rtsp://")) stream->setup_url = g_strdup (control_url); + else if (src->content_base) + stream->setup_url = + g_strdup_printf ("%s%s", src->content_base, control_url); else stream->setup_url = g_strdup_printf ("%s/%s", src->location, control_url); } @@ -487,8 +499,12 @@ return FALSE; PARSE_STRING (p, "/", *name); - if (*name == NULL) - return FALSE; + if (*name == NULL) { + /* no rate, assume 0 then */ + *name = p; + *rate = -1; + return TRUE; t = p; p = strstr (p, "/"); @@ -792,7 +808,7 @@ } else { /* multicast was selected, create UDP sources and join the multicast * group. */ - if (transport->multicast) { + if (transport->lower_transport == RTSP_LOWER_TRANS_UDP_MCAST) { gchar *uri; /* creating RTP source */ @@ -1143,12 +1159,16 @@ * * Returns: TRUE if the processing was successful. */ -static gboolean +gboolean gst_rtspsrc_send (GstRTSPSrc * src, RTSPMessage * request, RTSPMessage * response, RTSPStatusCode * code) RTSPResult res; RTSPStatusCode thecode; + gchar *content_base = NULL; + if (src->extension && src->extension->before_send) + src->extension->before_send (src->extension, request); if (src->debug) rtsp_message_dump (request); @@ -1170,6 +1190,16 @@ else if (thecode != RTSP_STS_OK) goto error_response; + /* store new content base if any */ + rtsp_message_get_header (response, RTSP_HDR_CONTENT_BASE, &content_base); + if (content_base) { + g_free (src->content_base); + src->content_base = g_strdup (content_base); + if (src->extension && src->extension->after_send) + src->extension->after_send (src->extension, request, response); return TRUE; /* ERRORS */ @@ -1233,7 +1263,7 @@ /* this field is not required, assume the server supports * DESCRIBE, SETUP and PLAY */ GST_DEBUG_OBJECT (src, "could not get OPTIONS"); - src->methods = RTSP_DESCRIBE | RTSP_SETUP | RTSP_PLAY; + src->methods = RTSP_DESCRIBE | RTSP_SETUP | RTSP_PLAY | RTSP_PAUSE; goto done; @@ -1333,6 +1363,12 @@ /* we only accept SDP for now */ rtsp_message_add_header (&request, RTSP_HDR_ACCEPT, "application/sdp"); + /* prepare global stream caps properties */ + if (src->props) + gst_structure_remove_all_fields (src->props); + else + src->props = gst_structure_empty_new ("RTSP Properties"); /* send DESCRIBE */ GST_DEBUG_OBJECT (src, "send describe..."); if (!gst_rtspsrc_send (src, &request, &response, NULL)) @@ -1357,29 +1393,8 @@ sdp_message_dump (&sdp); - /* prepare global stream caps properties */ - if (src->props) - gst_structure_remove_all_fields (src->props); - else - src->props = gst_structure_empty_new ("RTSP Properties"); - - /* FIXME, WMServer specific, move to extensions */ -#define HEADER_PREFIX "data:application/vnd.ms.wms-hdr.asfv1;base64," - { - gchar *config, *maxps; - for (i = 0; (config = sdp_message_get_attribute_val_n (&sdp, "pgmpu", i)); - i++) { - if (g_str_has_prefix (config, HEADER_PREFIX)) { - config += strlen (HEADER_PREFIX); - gst_structure_set (src->props, "config", G_TYPE_STRING, config, NULL); - break; - } - } - maxps = sdp_message_get_attribute_val (&sdp, "maxps"); - if (maxps) - gst_structure_set (src->props, "maxps", G_TYPE_STRING, maxps, NULL); - } + if (src->extension && src->extension->parse_sdp) + src->extension->parse_sdp (src->extension, &sdp); /* we initially allow all configured protocols. based on the replies from the * server we narrow them down. */ @@ -1393,7 +1408,7 @@ /* create stream from the media, can never return NULL */ stream = gst_rtspsrc_create_stream (src, &sdp, i); - /* merge global caps */ + /* merge/overwrite global caps */ if (stream->caps) { guint j, num; GstStructure *s; @@ -1408,6 +1423,8 @@ name = gst_structure_nth_field_name (src->props, j); val = gst_structure_get_value (src->props, name); gst_structure_set_value (s, name, val); + GST_DEBUG_OBJECT (src, "copied %s", name); } } @@ -1494,20 +1511,26 @@ /* update allowed transports for other streams. once the transport of * one stream has been determined, we make sure that all other streams * are configured in the same way */ - if (transport.lower_transport == RTSP_LOWER_TRANS_TCP) { - GST_DEBUG_OBJECT (src, "stream %d as TCP", i); - protocols = GST_RTSP_PROTO_TCP; - src->interleaved = TRUE; - } else { - if (transport.multicast) { + switch (transport.lower_transport) { + case RTSP_LOWER_TRANS_TCP: + GST_DEBUG_OBJECT (src, "stream %d as TCP interleaved", i); + protocols = GST_RTSP_PROTO_TCP; + src->interleaved = TRUE; + break; + case RTSP_LOWER_TRANS_UDP_MCAST: /* only allow multicast for other streams */ - GST_DEBUG_OBJECT (src, "stream %d as MULTICAST", i); + GST_DEBUG_OBJECT (src, "stream %d as UDP multicast", i); protocols = GST_RTSP_PROTO_UDP_MULTICAST; - } else { + case RTSP_LOWER_TRANS_UDP: /* only allow unicast for other streams */ - GST_DEBUG_OBJECT (src, "stream %d as UNICAST", i); + GST_DEBUG_OBJECT (src, "stream %d as UDP unicast", i); protocols = GST_RTSP_PROTO_UDP_UNICAST; - } + default: + GST_DEBUG_OBJECT (src, "stream %d unknown transport %d", i, + transport.lower_transport); if (!stream->container || !src->interleaved) { @@ -1522,6 +1545,8 @@ rtsp_transport_init (&transport); + if (src->extension && src->extension->stream_select) + src->extension->stream_select (src->extension); /* if we got here all was configured. We have dynamic pads so we notify that * we are done */ @@ -1735,7 +1760,8 @@ rtsp_message_unset (&response); /* for interleaved transport, we receive the data on the RTSP connection - * instead of UDP. We start a task to select and read from that connection. */ + * instead of UDP. We start a task to select and read from that connection. + * For UDP we start the task as well to look for server info and UDP timeouts. */ if (src->task == NULL) { src->task = gst_task_create ((GstTaskFunction) gst_rtspsrc_loop, src); gst_task_set_lock (src->task, src->stream_rec_lock); Index: gstrtspsrc.h RCS file: /cvs/gstreamer/gst-plugins-good/gst/rtsp/gstrtspsrc.h,v retrieving revision 1.17 retrieving revision 1.18 diff -u -d -r1.17 -r1.18 --- gstrtspsrc.h 29 Sep 2006 15:37:29 -0000 1.17 +++ gstrtspsrc.h 4 Oct 2006 17:24:40 -0000 1.18 @@ -50,6 +50,7 @@ #include "gstrtsp.h" #include "rtsp.h" +#include "rtspext.h" #define GST_TYPE_RTSPSRC \ (gst_rtspsrc_get_type()) @@ -142,6 +143,7 @@ gchar *location; RTSPUrl *url; + gchar *content_base; GstRTSPProto protocols; gboolean debug; guint retry; @@ -153,6 +155,8 @@ RTSPConnection *connection; RTSPMessage *request; RTSPMessage *response; + RTSPExtensionCtx *extension; }; struct _GstRTSPSrcClass { @@ -161,6 +165,10 @@ GType gst_rtspsrc_get_type(void); +gboolean gst_rtspsrc_send (GstRTSPSrc * src, RTSPMessage * request, + RTSPMessage * response, RTSPStatusCode * code); G_END_DECLS #endif /* __GST_RTSPSRC_H__ */ Index: rtspdefs.c RCS file: /cvs/gstreamer/gst-plugins-good/gst/rtsp/rtspdefs.c,v --- rtspdefs.c 23 Sep 2006 15:31:56 -0000 1.6 +++ rtspdefs.c 4 Oct 2006 17:24:40 -0000 1.7 @@ -122,6 +122,13 @@ "User-Agent", /* User-Agent R opt. all */ "Via", /* Via g opt. all */ "WWW-Authenticate", /* WWW-Authenticate r opt. all */ + /* Real extensions */ + "ClientChallenge", /* ClientChallenge */ + "RealChallenge1", /* RealChallenge1 */ + "RealChallenge2", /* RealChallenge2 */ + "Subscribe", /* Subscribe */ NULL Index: rtspdefs.h RCS file: /cvs/gstreamer/gst-plugins-good/gst/rtsp/rtspdefs.h,v --- rtspdefs.h 23 Sep 2006 15:31:56 -0000 1.9 +++ rtspdefs.h 4 Oct 2006 17:24:40 -0000 1.10 @@ -150,6 +150,12 @@ RTSP_HDR_VIA, /* Via g opt. all */ RTSP_HDR_WWW_AUTHENTICATE, /* WWW-Authenticate r opt. all */ + RTSP_HDR_CLIENT_CHALLENGE, /* ClientChallenge */ + RTSP_HDR_REAL_CHALLENGE1, /* RealChallenge1 */ + RTSP_HDR_REAL_CHALLENGE2, /* RealChallenge2 */ + RTSP_HDR_SUBSCRIBE, /* Subscribe */ } RTSPHeaderField; typedef enum { --- NEW FILE: rtspext.h --- /* GStreamer * Copyright (C) <2006> Wim Taymans <wi...@fl...> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* * Unless otherwise indicated, Source Code is licensed under MIT license. * See further explanation attached in License Statement (distributed in the file * LICENSE). * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do * so, subject to the following conditions: * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. #ifndef __RTSP_EXT_H__ #define __RTSP_EXT_H__ #include <glib.h> #include "sdp.h" G_BEGIN_DECLS typedef struct _RTSPExtensionCtx RTSPExtensionCtx; struct _RTSPExtensionCtx { GstRank rank; gchar *name; gpointer *src; gboolean (*detect_server) (RTSPExtensionCtx *ctx, RTSPMessage *resp); RTSPResult (*before_send) (RTSPExtensionCtx *ctx, RTSPMessage *req); RTSPResult (*after_send) (RTSPExtensionCtx *ctx, RTSPMessage *req, RTSPMessage *resp); RTSPResult (*parse_sdp) (RTSPExtensionCtx *ctx, SDPMessage *sdp); RTSPResult (*setup_media) (RTSPExtensionCtx *ctx, SDPMedia *media); RTSPResult (*stream_select) (RTSPExtensionCtx *ctx); }; RTSPExtensionCtx* rtsp_extension_detect (RTSPMessage *resp); gboolean rtsp_extension_register (RTSPExtensionCtx *ctx); G_END_DECLS #endif /* __RTSP_EXT_H__ */ --- NEW FILE: rtspextwms.c --- #include <string.h> #include "gstrtspsrc.h" #include "rtspextwms.h" typedef struct _RTSPExtWMSCtx RTSPExtWMSCtx; struct _RTSPExtWMSCtx RTSPExtensionCtx ctx; #define HEADER_PREFIX "data:application/vnd.ms.wms-hdr.asfv1;base64," static RTSPResult rtsp_ext_wms_parse_sdp (RTSPExtensionCtx * ctx, SDPMessage * sdp) GstRTSPSrc *src = (GstRTSPSrc *) ctx->src; gchar *config, *maxps; gint i; for (i = 0; (config = sdp_message_get_attribute_val_n (sdp, "pgmpu", i)); i++) { if (g_str_has_prefix (config, HEADER_PREFIX)) { config += strlen (HEADER_PREFIX); gst_structure_set (src->props, "config", G_TYPE_STRING, config, NULL); break; } } if (config == NULL) goto no_config; gst_structure_set (src->props, "config", G_TYPE_STRING, config, NULL); maxps = sdp_message_get_attribute_val (sdp, "maxps"); if (maxps) gst_structure_set (src->props, "maxps", G_TYPE_STRING, maxps, NULL); gst_structure_set (src->props, "encoding-name", G_TYPE_STRING, "x-asf-pf", NULL); gst_structure_set (src->props, "media", G_TYPE_STRING, "application", NULL); return RTSP_OK; /* ERRORS */ no_config: { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("Could not find config SDP field.")); return RTSP_ENOTIMPL; } RTSPExtensionCtx * rtsp_ext_wms_get_context (void) RTSPExtWMSCtx *res; res = g_new0 (RTSPExtWMSCtx, 1); res->ctx.parse_sdp = rtsp_ext_wms_parse_sdp; return (RTSPExtensionCtx *) res; --- NEW FILE: rtspextwms.h --- #ifndef __RTSP_EXT_WMS_H__ #define __RTSP_EXT_WMS_H__ #include "rtspext.h" RTSPExtensionCtx* rtsp_ext_wms_get_context (void); #endif /* __RTSP_EXT_WMS_H__ */ Index: rtsptransport.c RCS file: /cvs/gstreamer/gst-plugins-good/gst/rtsp/rtsptransport.c,v retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- rtsptransport.c 20 Sep 2006 16:06:27 -0000 1.7 +++ rtsptransport.c 4 Oct 2006 17:24:40 -0000 1.8 @@ -45,6 +45,45 @@ #include "rtsptransport.h" +typedef struct +{ + const gchar *name; + const RTSPTransMode mode; + const gchar *gst_mime; +} RTSPTransMap; +static const RTSPTransMap transports[] = { + {"rtp", RTSP_TRANS_RTP, "application/x-rtp"}, + {"x-real-rdt", RTSP_TRANS_RDT, "application/x-rdt"}, + {"x-pn-tng", RTSP_TRANS_RDT, "application/x-rdt"}, + {NULL, RTSP_TRANS_UNKNOWN, "application/x-unknown"} +}; + const RTSPProfile profile; +} RTSPProfileMap; +static const RTSPProfileMap profiles[] = { + {"avp", RTSP_PROFILE_AVP}, + {"savp", RTSP_PROFILE_SAVP}, + {NULL, RTSP_PROFILE_UNKNOWN} + const RTSPLowerTrans ltrans; +} RTSPLTransMap; +static const RTSPLTransMap ltrans[] = { + {"udp", RTSP_LOWER_TRANS_UDP}, + {"mcast", RTSP_LOWER_TRANS_UDP_MCAST}, + {"tcp", RTSP_LOWER_TRANS_TCP}, + {NULL, RTSP_LOWER_TRANS_UNKNOWN} RTSPResult rtsp_transport_new (RTSPTransport ** transport) @@ -72,7 +111,7 @@ transport->trans = RTSP_TRANS_RTP; transport->profile = RTSP_PROFILE_AVP; - transport->lower_transport = RTSP_LOWER_TRANS_UNKNOWN; + transport->lower_transport = RTSP_LOWER_TRANS_UDP; transport->mode_play = TRUE; transport->mode_record = FALSE; @@ -82,8 +121,8 @@ parse_mode (RTSPTransport * transport, gchar * str) - transport->mode_play = (strstr (str, "\"PLAY\"") != NULL); - transport->mode_record = (strstr (str, "\"RECORD\"") != NULL); + transport->mode_play = (strstr (str, "\"play\"") != NULL); + transport->mode_record = (strstr (str, "\"record\"") != NULL); @@ -102,7 +141,7 @@ -rtsp_transport_parse (gchar * str, RTSPTransport * transport) +rtsp_transport_parse (const gchar * str, RTSPTransport * transport) gchar **split, *down; gint i; @@ -116,18 +155,30 @@ down = g_ascii_strdown (str, -1); split = g_strsplit (down, ";", 0); + /* First field contains the transport/profile/lower_transport */ i = 0; + if (split[0]) { + for (i = 0; transports[i].name; i++) + if (strstr (split[0], transports[i].name)) + break; + transport->trans = transports[i].mode; + for (i = 1; profiles[i].name; i++) + if (strstr (split[0], profiles[i].name)) + transport->profile = profiles[i].profile; + for (i = 1; ltrans[i].name; i++) + if (strstr (split[0], ltrans[i].name)) + transport->lower_transport = ltrans[i].ltrans; + i = 1; while (split[i]) { - if (g_str_has_prefix (split[i], "rtp/avp/udp")) { - transport->lower_transport = RTSP_LOWER_TRANS_UDP; - } else if (g_str_has_prefix (split[i], "rtp/avp/tcp")) { - transport->lower_transport = RTSP_LOWER_TRANS_TCP; - } else if (g_str_has_prefix (split[i], "rtp/avp")) { - } else if (g_str_has_prefix (split[i], "multicast")) { - transport->multicast = TRUE; + if (g_str_has_prefix (split[i], "multicast")) { + transport->lower_transport = RTSP_LOWER_TRANS_UDP_MCAST; } else if (g_str_has_prefix (split[i], "unicast")) { - transport->multicast = FALSE; + if (transport->lower_transport == RTSP_LOWER_TRANS_UDP_MCAST) + transport->lower_transport = RTSP_LOWER_TRANS_UDP; } else if (g_str_has_prefix (split[i], "destination=")) { transport->destination = g_strdup (split[i] + 12); } else if (g_str_has_prefix (split[i], "source=")) { Index: rtsptransport.h RCS file: /cvs/gstreamer/gst-plugins-good/gst/rtsp/rtsptransport.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- rtsptransport.h 20 Sep 2006 16:06:27 -0000 1.3 +++ rtsptransport.h 4 Oct 2006 17:24:40 -0000 1.4 @@ -48,17 +48,22 @@ G_BEGIN_DECLS - RTSP_TRANS_RTP, + RTSP_TRANS_UNKNOWN = 0, + RTSP_TRANS_RTP = (1 << 0), + RTSP_TRANS_RDT = (1 << 1) } RTSPTransMode; - RTSP_PROFILE_AVP, + RTSP_PROFILE_UNKNOWN = 0, + RTSP_PROFILE_AVP = (1 << 0), + RTSP_PROFILE_SAVP = (1 << 1) } RTSPProfile; - RTSP_LOWER_TRANS_UNKNOWN, - RTSP_LOWER_TRANS_UDP, - RTSP_LOWER_TRANS_TCP, + RTSP_LOWER_TRANS_UNKNOWN = 0, + RTSP_LOWER_TRANS_UDP = (1 << 0), + RTSP_LOWER_TRANS_UDP_MCAST = (1 << 1), + RTSP_LOWER_TRANS_TCP = (1 << 2) } RTSPLowerTrans; typedef struct @@ -72,7 +77,6 @@ RTSPProfile profile; RTSPLowerTrans lower_transport; - gboolean multicast; gchar *destination; gchar *source; gint layers; @@ -84,10 +88,11 @@ /* mulitcast specific */ gint ttl; - /* RTP specific */ + /* UDP specific */ RTSPRange port; RTSPRange client_port; RTSPRange server_port; + /* RTP specific */ gchar *ssrc; } RTSPTransport; @@ -95,7 +100,7 @@ RTSPResult rtsp_transport_new (RTSPTransport **transport); RTSPResult rtsp_transport_init (RTSPTransport *transport); -RTSPResult rtsp_transport_parse (gchar *str, RTSPTransport *transport); +RTSPResult rtsp_transport_parse (const gchar *str, RTSPTransport *transport); RTSPResult rtsp_transport_free (RTSPTransport *transport); |