X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fstream_output%2Fsdp.c;h=d2c0610655df1ac88588dc4120ba48bdf1fcebca;hb=12ade3e3bc975d5426ba4af155b7372c31093b31;hp=afc99815b7cd7acb548592bc18ecb78806387452;hpb=6d54aef5a76010108e6f85e8832be6f8220d0228;p=vlc diff --git a/src/stream_output/sdp.c b/src/stream_output/sdp.c index afc99815b7..d2c0610655 100644 --- a/src/stream_output/sdp.c +++ b/src/stream_output/sdp.c @@ -19,8 +19,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include #include #include #include @@ -74,22 +79,23 @@ char *AddressToSDP (const struct sockaddr *addr, socklen_t addrlen, char *buf) } -static vlc_bool_t IsSDPString (const char *str) +static bool IsSDPString (const char *str) { if (strchr (str, '\r') != NULL) - return VLC_FALSE; + return false; if (strchr (str, '\n') != NULL) - return VLC_FALSE; + return false; if (!IsUTF8 (str)) - return VLC_FALSE; - return VLC_TRUE; + return false; + 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, socklen_t srclen, - const struct sockaddr *addr, socklen_t addrlen) + const char *email, const char *phone, + const struct sockaddr *src, size_t srclen, + const struct sockaddr *addr, size_t addrlen) { uint64_t now = NTPtime64 (); char *sdp; @@ -126,7 +132,7 @@ char *sdp_Start (const char *name, const char *description, const char *url, } if (asprintf (&sdp, "v=0" - "\r\no=- "I64Fu" "I64Fu" IN IP%c %s" + "\r\no=- %"PRIu64" %"PRIu64" IN IP%c %s" "\r\ns=%s" "\r\ni=%s" "%s%s" // optional URL @@ -161,15 +167,28 @@ static char * vsdp_AddAttribute (char **sdp, const char *name, const char *fmt, va_list ap) { size_t oldlen = strlen (*sdp); - size_t addlen = - sizeof ("a=:\r\n") + strlen (name) + vsnprintf (NULL, 0, fmt, ap); - char *ret = realloc (*sdp, oldlen + addlen); + size_t addlen = sizeof ("a=\r\n") + strlen (name); + + if (fmt != NULL) + { + va_list aq; + + va_copy (aq, ap); + addlen += 1 + vsnprintf (NULL, 0, fmt, aq); + va_end (aq); + } + char *ret = realloc (*sdp, oldlen + addlen); if (ret == NULL) return NULL; - oldlen += sprintf (ret + oldlen, "a=%s:", name); - oldlen += vsprintf (ret + oldlen, fmt, ap); + oldlen += sprintf (ret + oldlen, "a=%s", name); + if (fmt != NULL) + { + ret[oldlen++] = ':'; + oldlen += vsprintf (ret + oldlen, fmt, ap); + } + strcpy (ret + oldlen, "\r\n"); return *sdp = ret; } @@ -178,32 +197,21 @@ vsdp_AddAttribute (char **sdp, const char *name, const char *fmt, va_list ap) char *sdp_AddAttribute (char **sdp, const char *name, const char *fmt, ...) { char *ret; + va_list ap; - if (fmt != NULL) - { - va_list ap; + va_start (ap, fmt); + ret = vsdp_AddAttribute (sdp, name, fmt, ap); + va_end (ap); - va_start (ap, fmt); - ret = vsdp_AddAttribute (sdp, name, fmt, ap); - va_end (ap); - } - else - { - size_t oldlen = strlen (*sdp); - ret = realloc (*sdp, oldlen + strlen (name) + sizeof ("a=\r\n")); - if (ret == NULL) - return NULL; - - sprintf (ret + oldlen, "a=%s\r\n", name); - } return ret; } char *sdp_AddMedia (char **sdp, const char *type, const char *protocol, int dport, - unsigned pt, vlc_bool_t bw_indep, unsigned bw, - const char *rtpmap, const char *fmtp) + 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; @@ -217,8 +225,9 @@ char *sdp_AddMedia (char **sdp, 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); + type, dport, protocol, pt, bw); newsdp = realloc (*sdp, outlen + 1); if (newsdp == NULL) @@ -227,16 +236,70 @@ char *sdp_AddMedia (char **sdp, *sdp = newsdp; ptr = newsdp + inlen; - ptr += sprintf (ptr, "m=%s %u %s %u\r\n" - "b=RR:0\r\n", + 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"); /* RTP payload type map */ - if (rtpmap != NULL) - sdp_AddAttribute (sdp, "rtpmap", "%u %s", pt, rtpmap); + if (ptname != 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); + } /* Format parameters */ if (fmtp != NULL) sdp_AddAttribute (sdp, "fmtp", "%u %s", pt, fmtp); return newsdp; } + + +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; + + 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; + + /* Totally non-standard */ + strcpy (subvar, "group"); + char *group = var_GetNonEmptyString (obj, varname); + if (group != NULL) + { + sdp_AddAttribute (&sdp, "x-plgroup", "%s", group); + free (group); + } + + return sdp; +}