vlc | branch: master | Rémi Denis-Courmont <r...@remlab.net> | Sat Feb 25 13:14:01 2017 +0200| [84ec386904a4f08c6bb4af6a488c73b9e3e50043] | committer: Rémi Denis-Courmont
sdp: use vlc_memstream > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=84ec386904a4f08c6bb4af6a488c73b9e3e50043 --- include/vlc_sout.h | 17 ++- modules/misc/rtsp.c | 17 +-- modules/stream_out/rtp.c | 27 ++-- modules/stream_out/standard.c | 27 ++-- modules/stream_out/vod.c | 20 +-- src/stream_output/sdp.c | 326 +++++++++++++++++++----------------------- 6 files changed, 207 insertions(+), 227 deletions(-) diff --git a/include/vlc_sout.h b/include/vlc_sout.h index acbb2cb..c710780 100644 --- a/include/vlc_sout.h +++ b/include/vlc_sout.h @@ -280,10 +280,19 @@ VLC_API void sout_AnnounceUnRegister(vlc_object_t *,session_descriptor_t* ); /** SDP */ struct sockaddr; - -VLC_API char * vlc_sdp_Start( vlc_object_t *obj, const char *cfgpref, const struct sockaddr *src, size_t srclen, const struct sockaddr *addr, size_t addrlen ) VLC_USED; -VLC_API char * sdp_AddMedia(char **sdp, const char *type, const char *protocol, int dport, unsigned pt, bool bw_indep, unsigned bw, const char *ptname, unsigned clockrate, unsigned channels, const char *fmtp); -VLC_API char * sdp_AddAttribute(char **sdp, const char *name, const char *fmt, ...) VLC_FORMAT( 3, 4 ); +struct vlc_memstream; + +VLC_API int vlc_sdp_Start(struct vlc_memstream *, vlc_object_t *obj, + const char *cfgpref, + const struct sockaddr *src, size_t slen, + const struct sockaddr *addr, size_t alen) VLC_USED; +VLC_API void sdp_AddMedia(struct vlc_memstream *, const char *type, + const char *protocol, int dport, unsigned pt, + bool bw_indep, unsigned bw, const char *ptname, + unsigned clockrate, unsigned channels, + const char *fmtp); +VLC_API void sdp_AddAttribute(struct vlc_memstream *, const char *name, + const char *fmt, ...) VLC_FORMAT(3, 4); /** Description module */ typedef struct sout_description_data_t diff --git a/modules/misc/rtsp.c b/modules/misc/rtsp.c index cb0d218..d2a03c1 100644 --- a/modules/misc/rtsp.c +++ b/modules/misc/rtsp.c @@ -44,6 +44,7 @@ #include <vlc_charset.h> #include <vlc_strings.h> #include <vlc_rand.h> +#include <vlc_memstream.h> #ifndef _WIN32 # include <locale.h> @@ -1499,7 +1500,8 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl, *****************************************************************************/ static char *SDPGenerate( const vod_media_t *p_media, httpd_client_t *cl ) { - char *psz_sdp, ip[NI_MAXNUMERICHOST]; + struct vlc_memstream sdp; + char ip[NI_MAXNUMERICHOST]; const char *psz_control; int port; @@ -1521,15 +1523,14 @@ static char *SDPGenerate( const vod_media_t *p_media, httpd_client_t *cl ) dst.ss_len = dstlen; #endif - psz_sdp = vlc_sdp_Start( VLC_OBJECT( p_media->p_vod ), "sout-rtp-", - NULL, 0, (struct sockaddr *)&dst, dstlen ); - if( psz_sdp == NULL ) + if( vlc_sdp_Start( &sdp, VLC_OBJECT( p_media->p_vod ), "sout-rtp-", + NULL, 0, (struct sockaddr *)&dst, dstlen ) ) return NULL; if( p_media->i_length > 0 ) { lldiv_t d = lldiv( p_media->i_length / 1000, 1000 ); - sdp_AddAttribute( &psz_sdp, "range","npt=0-%lld.%03u", d.quot, + sdp_AddAttribute( &sdp, "range","npt=0-%lld.%03u", d.quot, (unsigned)d.rem ); } @@ -1553,13 +1554,13 @@ static char *SDPGenerate( const vod_media_t *p_media, httpd_client_t *cl ) continue; } - sdp_AddMedia( &psz_sdp, mime_major, "RTP/AVP", 0 /* p_es->i_port */, + sdp_AddMedia( &sdp, mime_major, "RTP/AVP", 0 /* p_es->i_port */, p_es->i_payload_type, false, 0, p_es->psz_ptname, p_es->i_clock_rate, p_es->i_channels, p_es->psz_fmtp ); - sdp_AddAttribute( &psz_sdp, "control", psz_control, ip, port, i ); + sdp_AddAttribute( &sdp, "control", psz_control, ip, port, i ); } - return psz_sdp; + return vlc_memstream_close( &sdp ) ? NULL : sdp.ptr; } diff --git a/modules/stream_out/rtp.c b/modules/stream_out/rtp.c index 3f85f2e..c4436a8 100644 --- a/modules/stream_out/rtp.c +++ b/modules/stream_out/rtp.c @@ -41,6 +41,7 @@ #include <vlc_network.h> #include <vlc_fs.h> #include <vlc_rand.h> +#include <vlc_memstream.h> #ifdef HAVE_SRTP # include <srtp.h> # include <gcrypt.h> @@ -780,8 +781,9 @@ out: char *SDPGenerate( sout_stream_t *p_stream, const char *rtsp_url ) { sout_stream_sys_t *p_sys = p_stream->p_sys; - char *psz_sdp = NULL; + struct vlc_memstream sdp; struct sockaddr_storage dst; + char *psz_sdp = NULL; socklen_t dstlen; int i; /* @@ -836,17 +838,16 @@ char *SDPGenerate( sout_stream_t *p_stream, const char *rtsp_url ) #endif } - psz_sdp = vlc_sdp_Start( VLC_OBJECT( p_stream ), SOUT_CFG_PREFIX, - NULL, 0, (struct sockaddr *)&dst, dstlen ); - if( psz_sdp == NULL ) + if( vlc_sdp_Start( &sdp, VLC_OBJECT( p_stream ), SOUT_CFG_PREFIX, + NULL, 0, (struct sockaddr *)&dst, dstlen ) ) goto out; /* TODO: a=source-filter */ if( p_sys->rtcp_mux ) - sdp_AddAttribute( &psz_sdp, "rtcp-mux", NULL ); + sdp_AddAttribute( &sdp, "rtcp-mux", NULL ); if( rtsp_url != NULL ) - sdp_AddAttribute ( &psz_sdp, "control", "%s", rtsp_url ); + sdp_AddAttribute ( &sdp, "control", "%s", rtsp_url ); const char *proto = "RTP/AVP"; /* protocol */ if( rtsp_url == NULL ) @@ -887,34 +888,36 @@ char *SDPGenerate( sout_stream_t *p_stream, const char *rtsp_url ) continue; } - sdp_AddMedia( &psz_sdp, mime_major, proto, inclport * id->i_port, + sdp_AddMedia( &sdp, mime_major, proto, inclport * id->i_port, rtp_fmt->payload_type, false, rtp_fmt->bitrate, rtp_fmt->ptname, rtp_fmt->clock_rate, rtp_fmt->channels, rtp_fmt->fmtp); /* cf RFC4566 §5.14 */ if( inclport && !p_sys->rtcp_mux && (id->i_port & 1) ) - sdp_AddAttribute ( &psz_sdp, "rtcp", "%u", id->i_port + 1 ); + sdp_AddAttribute( &sdp, "rtcp", "%u", id->i_port + 1 ); if( rtsp_url != NULL ) { char *track_url = RtspAppendTrackPath( id->rtsp_id, rtsp_url ); if( track_url != NULL ) { - sdp_AddAttribute ( &psz_sdp, "control", "%s", track_url ); + sdp_AddAttribute( &sdp, "control", "%s", track_url ); free( track_url ); } } else { if( id->listen.fd != NULL ) - sdp_AddAttribute( &psz_sdp, "setup", "passive" ); + sdp_AddAttribute( &sdp, "setup", "passive" ); if( p_sys->proto == IPPROTO_DCCP ) - sdp_AddAttribute( &psz_sdp, "dccp-service-code", - "SC:RTP%c", + sdp_AddAttribute( &sdp, "dccp-service-code", "SC:RTP%c", toupper( (unsigned char)mime_major[0] ) ); } } + + if( vlc_memstream_close( &sdp ) == 0 ) + psz_sdp = sdp.ptr; out: vlc_mutex_unlock( &p_sys->lock_es ); return psz_sdp; diff --git a/modules/stream_out/standard.c b/modules/stream_out/standard.c index e8805ba..15c0f2b 100644 --- a/modules/stream_out/standard.c +++ b/modules/stream_out/standard.c @@ -34,6 +34,7 @@ #include <vlc_network.h> #include <vlc_url.h> +#include <vlc_memstream.h> /***************************************************************************** * Module descriptor @@ -179,29 +180,25 @@ static void create_SDP(sout_stream_t *p_stream, sout_access_out_t *p_access) freeaddrinfo (res); } - char *head = vlc_sdp_Start (VLC_OBJECT (p_stream), SOUT_CFG_PREFIX, - (struct sockaddr *)&src, srclen, - (struct sockaddr *)&dst, dstlen); - free (shost); + struct vlc_memstream sdp; - if (head != NULL) + if (vlc_sdp_Start(&sdp, VLC_OBJECT (p_stream), SOUT_CFG_PREFIX, + (struct sockaddr *)&src, srclen, + (struct sockaddr *)&dst, dstlen) == 0) { - char *psz_sdp = NULL; - if (asprintf (&psz_sdp, "%s" - "m=video %d udp mpeg\r\n", head, dport) == -1) - psz_sdp = NULL; - free (head); + vlc_memstream_printf(&sdp, "m=video %d udp mpeg\r\n", dport); /* Register the SDP with the SAP thread */ - if (psz_sdp) + if (vlc_memstream_close(&sdp)) { - msg_Dbg (p_stream, "Generated SDP:\n%s", psz_sdp); + msg_Dbg(p_stream, "Generated SDP:\n%s", sdp.ptr); p_sys->p_session = - sout_AnnounceRegisterSDP (p_stream, psz_sdp, dhost); - free( psz_sdp ); + sout_AnnounceRegisterSDP(p_stream, sdp.ptr, dhost); + free(sdp.ptr); } } - free (dhost); + free(shost); + free(dhost); } static const char *getMuxFromAlias( const char *psz_alias ) diff --git a/modules/stream_out/vod.c b/modules/stream_out/vod.c index 9c75198..9db3d70 100644 --- a/modules/stream_out/vod.c +++ b/modules/stream_out/vod.c @@ -40,6 +40,7 @@ #include <vlc_vod.h> #include <vlc_url.h> #include <vlc_network.h> +#include <vlc_memstream.h> #include <assert.h> @@ -390,8 +391,6 @@ static void* CommandThread( void *obj ) *****************************************************************************/ char *SDPGenerateVoD( const vod_media_t *p_media, const char *rtsp_url ) { - char *psz_sdp; - assert(rtsp_url != NULL); /* Check against URL format rtsp://[<ipv6>]:<port>/<path> */ bool ipv6 = strlen( rtsp_url ) > 7 && rtsp_url[7] == '['; @@ -406,19 +405,20 @@ char *SDPGenerateVoD( const vod_media_t *p_media, const char *rtsp_url ) dst.ss_len = dstlen; #endif - psz_sdp = vlc_sdp_Start( VLC_OBJECT( p_media->p_vod ), "sout-rtp-", - NULL, 0, (struct sockaddr *)&dst, dstlen ); - if( psz_sdp == NULL ) + struct vlc_memstream sdp; + + if( vlc_sdp_Start( &sdp, VLC_OBJECT( p_media->p_vod ), "sout-rtp-", + NULL, 0, (struct sockaddr *)&dst, dstlen ) ) return NULL; if( p_media->i_length > 0 ) { lldiv_t d = lldiv( p_media->i_length / 1000, 1000 ); - sdp_AddAttribute( &psz_sdp, "range"," npt=0-%lld.%03u", d.quot, + sdp_AddAttribute( &sdp, "range"," npt=0-%lld.%03u", d.quot, (unsigned)d.rem ); } - sdp_AddAttribute ( &psz_sdp, "control", "%s", rtsp_url ); + sdp_AddAttribute( &sdp, "control", "%s", rtsp_url ); /* No locking needed, the ES table can't be modified now */ for( int i = 0; i < p_media->i_es; i++ ) @@ -442,7 +442,7 @@ char *SDPGenerateVoD( const vod_media_t *p_media, const char *rtsp_url ) continue; } - sdp_AddMedia( &psz_sdp, mime_major, "RTP/AVP", 0, + sdp_AddMedia( &sdp, mime_major, "RTP/AVP", 0, rtp_fmt->payload_type, false, 0, rtp_fmt->ptname, rtp_fmt->clock_rate, rtp_fmt->channels, rtp_fmt->fmtp ); @@ -450,12 +450,12 @@ char *SDPGenerateVoD( const vod_media_t *p_media, const char *rtsp_url ) char *track_url = RtspAppendTrackPath( p_es->rtsp_id, rtsp_url ); if( track_url != NULL ) { - sdp_AddAttribute ( &psz_sdp, "control", "%s", track_url ); + sdp_AddAttribute( &sdp, "control", "%s", track_url ); free( track_url ); } } - return psz_sdp; + return vlc_memstream_close( &sdp ) ? NULL : sdp.ptr; } int vod_check_range(vod_media_t *p_media, const char *psz_session, diff --git a/src/stream_output/sdp.c b/src/stream_output/sdp.c index 37c55b0..c2ba6b2 100644 --- a/src/stream_output/sdp.c +++ b/src/stream_output/sdp.c @@ -32,6 +32,7 @@ #include <assert.h> #include <vlc_network.h> #include <vlc_charset.h> +#include <vlc_memstream.h> #include "stream_output.h" @@ -90,217 +91,186 @@ static bool IsSDPString (const char *str) return true; } - -static -char *sdp_Start (const char *name, const char *description, const char *url, - const char *email, const char *phone, - const struct sockaddr *src, size_t srclen, - const struct sockaddr *addr, size_t addrlen) +static void vsdp_AddAttribute(struct vlc_memstream *restrict stream, + const char *name, const char *fmt, va_list ap) { - uint64_t now = NTPtime64 (); - char *sdp; - char connection[MAXSDPADDRESS], hostname[256], - sfilter[MAXSDPADDRESS + sizeof ("\r\na=source-filter: incl * ")]; - const char *preurl = "\r\nu=", *premail = "\r\ne=", *prephone = "\r\np="; - - gethostname (hostname, sizeof (hostname)); - - if (name == NULL) - name = "Unnamed"; - if (description == NULL) - description = "N/A"; - if (url == NULL) - preurl = url = ""; - if (email == NULL) - premail = email = ""; - if (phone == NULL) - prephone = phone = ""; - - if (!IsSDPString (name) || !IsSDPString (description) - || !IsSDPString (url) || !IsSDPString (email) || !IsSDPString (phone) - || (AddressToSDP (addr, addrlen, connection) == NULL)) - return NULL; - - strcpy (sfilter, ""); - if (srclen > 0) - { - char machine[MAXSDPADDRESS]; + vlc_memstream_printf(stream, "a=%s:", name); + vlc_memstream_vprintf(stream, fmt, ap); + vlc_memstream_puts(stream, "\r\n"); +} - if (AddressToSDP (src, srclen, machine) != NULL) - sprintf (sfilter, "\r\na=source-filter: incl IN IP%c * %s", - machine[5], machine + 7); - } +void sdp_AddAttribute(struct vlc_memstream *restrict stream, const char *name, + const char *fmt, ...) +{ + va_list ap; - if (asprintf (&sdp, "v=0" - "\r\no=- %"PRIu64" %"PRIu64" IN IP%c %s" - "\r\ns=%s" - "\r\ni=%s" - "%s%s" // optional URL - "%s%s" // optional email - "%s%s" // optional phone number - "\r\nc=%s" - // bandwidth not specified - "\r\nt=0 0" // one dummy time span - // no repeating - // no time zone adjustment (silly idea anyway) - // no encryption key (deprecated) - "\r\na=tool:"PACKAGE_STRING - "\r\na=recvonly" - "\r\na=type:broadcast" - "\r\na=charset:UTF-8" - "%s" // optional source filter - "\r\n", - /* o= */ now, now, connection[5], hostname, - /* s= */ name, - /* i= */ description, - /* u= */ preurl, url, - /* e= */ premail, email, - /* p= */ prephone, phone, - /* c= */ connection, - /* source-filter */ sfilter) == -1) - return NULL; - return sdp; + va_start(ap, fmt); + vsdp_AddAttribute(stream, name, fmt, ap); + va_end(ap); } - -static char * -vsdp_AddAttribute (char **sdp, const char *name, const char *fmt, va_list ap) +void sdp_AddMedia(struct vlc_memstream *restrict stream, + const char *type, const char *proto, int dport, + unsigned pt, bool bw_indep, unsigned bw, + const char *ptname, unsigned clock, unsigned chans, + const char *fmtp) { - size_t oldlen = strlen (*sdp); - size_t addlen = sizeof ("a=\r\n") + strlen (name); - - if (fmt != NULL) - { - va_list aq; + /* Some default values */ + if (type == NULL) + type = "video"; + if (proto == NULL) + proto = "RTP/AVP"; + assert (pt < 128u); - va_copy (aq, ap); - addlen += 1 + vsnprintf (NULL, 0, fmt, aq); - va_end (aq); - } + vlc_memstream_printf(stream, "m=%s %u %s %u\r\n", type, dport, proto, pt); - char *ret = realloc (*sdp, oldlen + addlen); - if (ret == NULL) - return NULL; + if (bw > 0) + vlc_memstream_printf(stream, "b=%s:%u\r\n", + bw_indep ? "TIAS" : "AS", bw); + vlc_memstream_printf(stream, "b=%s:%u\r\n", "RR", 0); - oldlen += sprintf (ret + oldlen, "a=%s", name); - if (fmt != NULL) + /* RTP payload type map */ + if (ptname != NULL) { - ret[oldlen++] = ':'; - oldlen += vsprintf (ret + oldlen, fmt, ap); + vlc_memstream_printf(stream, "a=rtpmap:%u %s/%u", pt, ptname, clock); + if ((strcmp(type, "audio") == 0) && (chans != 1)) + vlc_memstream_printf(stream, "/%u", chans); + vlc_memstream_puts(stream, "\r\n"); } - strcpy (ret + oldlen, "\r\n"); - return *sdp = ret; + /* Format parameters */ + if (fmtp != NULL) + vlc_memstream_printf(stream, "a=fmtp:%u %s\r\n", pt, fmtp); } - -char *sdp_AddAttribute (char **sdp, const char *name, const char *fmt, ...) +int vlc_sdp_Start(struct vlc_memstream *restrict stream, + vlc_object_t *obj, const char *cfgpref, + const struct sockaddr *src, size_t srclen, + const struct sockaddr *addr, size_t addrlen) { - char *ret; - va_list ap; + char connection[MAXSDPADDRESS]; + char *str = NULL; - va_start (ap, fmt); - ret = vsdp_AddAttribute (sdp, name, fmt, ap); - va_end (ap); + size_t cfglen = strlen(cfgpref); + if (cfglen >= 128) + return -1; - return ret; -} + char varname[cfglen + sizeof ("description")]; + char *subvar = varname + cfglen; + strcpy(varname, cfgpref); -char *sdp_AddMedia (char **sdp, - const char *type, const char *protocol, int dport, - unsigned pt, bool bw_indep, unsigned bw, - const char *ptname, unsigned clock, unsigned chans, - const char *fmtp) -{ - char *newsdp, *ptr; - size_t inlen = strlen (*sdp), outlen = inlen; + vlc_memstream_open(stream); + vlc_memstream_puts(stream, "v=0\r\n"); - /* Some default values */ - if (type == NULL) - type = "video"; - if (protocol == NULL) - protocol = "RTP/AVP"; - assert (pt < 128u); + if (AddressToSDP(addr, addrlen, connection) == NULL) + goto error; + { + const uint_fast64_t now = NTPtime64(); + char hostname[256]; - outlen += snprintf (NULL, 0, - "m=%s %u %s %d\r\n" - "b=TIAS:%u\r\n" - "b=RR:0\r\n", - type, dport, protocol, pt, bw); + gethostname(hostname, sizeof (hostname)); - newsdp = realloc (*sdp, outlen + 1); - if (newsdp == NULL) - return NULL; + vlc_memstream_printf(stream, "o=- %"PRIu64" %"PRIu64" IN IP%c %s\r\n", + now, now, connection[5], hostname); + } - *sdp = newsdp; - ptr = newsdp + inlen; + strcpy(subvar, "name"); + str = var_GetNonEmptyString(obj, varname); + if (str != NULL) + { + if (!IsSDPString(str)) + goto error; - ptr += sprintf (ptr, "m=%s %u %s %u\r\n", - type, dport, protocol, pt); - if (bw > 0) - ptr += sprintf (ptr, "b=%s:%u\r\n", bw_indep ? "TIAS" : "AS", bw); - ptr += sprintf (ptr, "b=RR:0\r\n"); + vlc_memstream_printf(stream, "s=%s\r\n", str); + free(str); + } + else + vlc_memstream_printf(stream, "s=%s\r\n", "Unnamed"); - /* RTP payload type map */ - if (ptname != NULL) + strcpy(subvar, "description"); + str = var_GetNonEmptyString(obj, varname); + if (str != NULL) { - if ((strcmp (type, "audio") == 0) && (chans != 1)) - sdp_AddAttribute (sdp, "rtpmap", "%u %s/%u/%u", pt, ptname, clock, - chans); - else - sdp_AddAttribute (sdp, "rtpmap", "%u %s/%u", pt, ptname, clock); + if (!IsSDPString(str)) + goto error; + + vlc_memstream_printf(stream, "i=%s\r\n", str); + free(str); } - /* Format parameters */ - if (fmtp != NULL) - sdp_AddAttribute (sdp, "fmtp", "%u %s", pt, fmtp); + else + vlc_memstream_printf(stream, "i=%s\r\n", "N/A"); - return newsdp; -} + strcpy(subvar, "url"); + str = var_GetNonEmptyString(obj, varname); + if (str != NULL) + { + if (!IsSDPString(str)) + goto error; + vlc_memstream_printf(stream, "u=%s\r\n", str); + free(str); + } -char *vlc_sdp_Start (vlc_object_t *obj, const char *cfgpref, - const struct sockaddr *src, size_t srclen, - const struct sockaddr *addr, size_t addrlen) -{ - size_t cfglen = strlen (cfgpref); - if (cfglen > 100) - return NULL; + strcpy(subvar, "email"); + str = var_GetNonEmptyString(obj, varname); + if (str != NULL) + { + if (!IsSDPString(str)) + goto error; - char varname[cfglen + sizeof ("description")], *subvar = varname + cfglen; - strcpy (varname, cfgpref); - - strcpy (subvar, "name"); - char *name = var_GetNonEmptyString (obj, varname); - strcpy (subvar, "description"); - char *description = var_GetNonEmptyString (obj, varname); - strcpy (subvar, "url"); - char *url = var_GetNonEmptyString (obj, varname); - strcpy (subvar, "email"); - char *email = var_GetNonEmptyString (obj, varname); - strcpy (subvar, "phone"); - char *phone = var_GetNonEmptyString (obj, varname); - - char *sdp = sdp_Start (name, description, url, email, phone, - src, srclen, addr, addrlen); - free (name); - free (description); - free (url); - free (email); - free (phone); - - if (sdp == NULL) - return NULL; + vlc_memstream_printf(stream, "e=%s\r\n", str); + free(str); + } + + strcpy(subvar, "phone"); + str = var_GetNonEmptyString(obj, varname); + if (str != NULL) + { + if (!IsSDPString(str)) + goto error; + + vlc_memstream_printf(stream, "p=%s\r\n", str); + free(str); + } - strcpy (subvar, "cat"); - char *cat = var_GetNonEmptyString (obj, varname); - if (cat != NULL) + vlc_memstream_printf(stream, "c=%s\r\n", connection); + // bandwidth not specified + vlc_memstream_puts(stream, "t=0 0\r\n"); // one dummy time span + // no repeating + // no time zone adjustment (silly idea anyway) + // no encryption key (deprecated) + + vlc_memstream_printf(stream, "a=tool:%s\r\n", PACKAGE_STRING); + vlc_memstream_puts(stream, "a=recvonly\r\n"); + vlc_memstream_puts(stream, "a=type:broadcast\r\n"); + vlc_memstream_puts(stream, "a=charset:UTF-8\r\n"); + + if (srclen > 0) { - sdp_AddAttribute (&sdp, "cat", "%s", cat); - /* Totally non-standard */ - sdp_AddAttribute (&sdp, "x-plgroup", "%s", cat); - free (cat); + char machine[MAXSDPADDRESS]; + + if (AddressToSDP(src, srclen, machine) != NULL) + vlc_memstream_printf(stream, + "a=source-filter: incl IN IP%c * %s\r\n", + machine[5], machine + 7); } - return sdp; + strcpy(subvar, "cat"); + str = var_GetNonEmptyString(obj, varname); + if (str != NULL) + { + if (IsSDPString(str)) + goto error; + + vlc_memstream_printf(stream, "a=cat:%s\r\n", str); + vlc_memstream_printf(stream, "a=x-plgroup:%s\r\n", str); + free(str); + } + return 0; +error: + free(str); + if (vlc_memstream_close(stream) == 0) + free(stream->ptr); + return -1; } _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org https://mailman.videolan.org/listinfo/vlc-commits