38 #define MAX_EXTRADATA_SIZE ((INT_MAX - 10) / 2) 
   40 struct sdp_session_level {
 
   57 static void sdp_write_address(
char *buff, 
int size, 
const char *dest_addr,
 
   58                               const char *dest_type, 
int ttl)
 
   63         if (ttl > 0 && !strcmp(dest_type, 
"IP4")) {
 
   66             av_strlcatf(buff, size, 
"c=IN %s %s/%d\r\n", dest_type, dest_addr, ttl);
 
   68             av_strlcatf(buff, size, 
"c=IN %s %s\r\n", dest_type, dest_addr);
 
   73 static void sdp_write_header(
char *buff, 
int size, 
struct sdp_session_level *s)
 
   76                             "o=- %d %d IN %s %s\r\n" 
   79                             s->id, s->version, s->src_type, s->src_addr,
 
   81     sdp_write_address(buff, size, s->dst_addr, s->dst_type, s->ttl);
 
   84                             s->start_time, s->end_time);
 
   88 static int resolve_destination(
char *dest_addr, 
int size, 
char *type,
 
  103     getnameinfo(ai->ai_addr, ai->ai_addrlen, dest_addr, size,
 
  106     if (ai->ai_family == AF_INET6)
 
  114 static int resolve_destination(
char *dest_addr, 
int size, 
char *type,
 
  121 static int sdp_get_address(
char *dest_addr, 
int size, 
int *ttl, 
const char *url)
 
  131     if (strcmp(proto, 
"rtp")) {
 
  138     p = strchr(url, 
'?');
 
  143             *ttl = strtol(buff, 
NULL, 10);
 
  152 #define MAX_PSET_SIZE 1024 
  157     static const char pset_string[] = 
"; sprop-parameter-sets=";
 
  158     static const char profile_string[] = 
"; profile-level-id=";
 
  160     int orig_extradata_size = 0;
 
  180         orig_extradata = 
av_mallocz(orig_extradata_size +
 
  182         if (!orig_extradata) {
 
  186         memcpy(orig_extradata, c->
extradata, orig_extradata_size);
 
  197     memcpy(psets, pset_string, strlen(pset_string));
 
  198     p = psets + strlen(pset_string);
 
  205         nal_type = *r & 0x1f;
 
  207         if (nal_type != 7 && nal_type != 8) { 
 
  211         if (p != (psets + strlen(pset_string))) {
 
  220             av_log(c, 
AV_LOG_ERROR, 
"Cannot Base64-encode %td %td!\n", MAX_PSET_SIZE - (p - psets), r1 - r);
 
  228     if (sps && sps_end - sps >= 4) {
 
  229         memcpy(p, profile_string, strlen(profile_string));
 
  234     if (orig_extradata) {
 
  253     if (config == 
NULL) {
 
  257     memcpy(config, 
"; config=", 9);
 
  266     char *
config, *encoded_config;
 
  268     int headers_len, header_len[3], config_len;
 
  269     int first_header_size;
 
  273         first_header_size = 42;
 
  276         first_header_size = 30;
 
  284                               first_header_size, header_start,
 
  290     headers_len = header_len[0] + header_len[2];
 
  303     if (!encoded_config) {
 
  308     config[0] = config[1] = config[2] = 0;
 
  313     config[7] = (headers_len >> 8) & 0xff;
 
  314     config[8] = headers_len & 0xff;
 
  316     config[10] = header_len[0];
 
  318     memcpy(config + 12, header_start[0], header_len[0]);
 
  319     memcpy(config + 12 + header_len[0], header_start[2], header_len[2]);
 
  325     return encoded_config;
 
  329            "Not enough memory for configuration string\n");
 
  339     int profile_level = 0x2B;
 
  346             profile_level = 0x28; 
 
  349             profile_level = 0x29; 
 
  351             profile_level = 0x2A; 
 
  355             profile_level = 0x2B; 
 
  359     return profile_level;
 
  372     for (rate_index = 0; rate_index < 16; rate_index++)
 
  375     if (rate_index == 16) {
 
  380     config_byte[0] = 0x40;
 
  382     config_byte[2] = 0x20 | rate_index;
 
  384     config_byte[4] = 0x3f;
 
  385     config_byte[5] = 0xc0;
 
  409                 config = extradata2psets(c);
 
  411             av_strlcatf(buff, size, 
"a=rtpmap:%d H264/90000\r\n" 
  412                                     "a=fmtp:%d packetization-mode=%d%s\r\n",
 
  414                                      payload_type, mode, config ? config : 
"");
 
  426             av_strlcatf(buff, size, 
"a=rtpmap:%d H263-2000/90000\r\n" 
  427                                     "a=framesize:%d %d-%d\r\n",
 
  433                 config = extradata2config(c);
 
  435             av_strlcatf(buff, size, 
"a=rtpmap:%d MP4V-ES/90000\r\n" 
  436                                     "a=fmtp:%d profile-level-id=1%s\r\n",
 
  438                                      payload_type, config ? config : 
"");
 
  443                 config = latm_context2config(c);
 
  446                 av_strlcatf(buff, size, 
"a=rtpmap:%d MP4A-LATM/%d/%d\r\n" 
  447                                         "a=fmtp:%d profile-level-id=%d;cpresent=0;config=%s\r\n",
 
  449                                          payload_type, latm_context2profilelevel(c), config);
 
  452                     config = extradata2config(c);
 
  460                 if (config == 
NULL) {
 
  463                 av_strlcatf(buff, size, 
"a=rtpmap:%d MPEG4-GENERIC/%d/%d\r\n" 
  464                                         "a=fmtp:%d profile-level-id=1;" 
  465                                         "mode=AAC-hbr;sizelength=13;indexlength=3;" 
  466                                         "indexdeltalength=3%s\r\n",
 
  468                                          payload_type, config);
 
  473                 av_strlcatf(buff, size, 
"a=rtpmap:%d L16/%d/%d\r\n",
 
  479                 av_strlcatf(buff, size, 
"a=rtpmap:%d PCMU/%d/%d\r\n",
 
  485                 av_strlcatf(buff, size, 
"a=rtpmap:%d PCMA/%d/%d\r\n",
 
  490             av_strlcatf(buff, size, 
"a=rtpmap:%d AMR/%d/%d\r\n" 
  491                                     "a=fmtp:%d octet-align=1\r\n",
 
  496             av_strlcatf(buff, size, 
"a=rtpmap:%d AMR-WB/%d/%d\r\n" 
  497                                     "a=fmtp:%d octet-align=1\r\n",
 
  503                 config = xiph_extradata2config(c);
 
  509             av_strlcatf(buff, size, 
"a=rtpmap:%d vorbis/%d/%d\r\n" 
  510                                     "a=fmtp:%d configuration=%s\r\n",
 
  512                                     payload_type, config);
 
  517                 config = xiph_extradata2config(c);
 
  525                 pix_fmt = 
"YCbCr-4:2:0";
 
  528                 pix_fmt = 
"YCbCr-4:2:2";
 
  531                 pix_fmt = 
"YCbCr-4:4:4";
 
  538             av_strlcatf(buff, size, 
"a=rtpmap:%d theora/90000\r\n" 
  539                                     "a=fmtp:%d delivery-method=inline; " 
  540                                     "width=%d; height=%d; sampling=%s; " 
  541                                     "configuration=%s\r\n",
 
  542                                     payload_type, payload_type,
 
  547             av_strlcatf(buff, size, 
"a=rtpmap:%d VP8/90000\r\n",
 
  552                 av_strlcatf(buff, size, 
"a=rtpmap:%d JPEG/90000\r\n",
 
  557                 av_strlcatf(buff, size, 
"a=rtpmap:%d G722/%d/%d\r\n",
 
  563                 av_strlcatf(buff, size, 
"a=rtpmap:%d G726-%d/%d\r\n",
 
  571                                     "a=fmtp:%d mode=%d\r\n",
 
  576             av_strlcatf(buff, size, 
"a=rtpmap:%d speex/%d\r\n",
 
  594             av_strlcatf(buff, size, 
"a=rtpmap:%d opus/48000\r\n",
 
  608                         const char *dest_addr, 
const char *dest_type,
 
  621         default                 : type = 
"application"; 
break;
 
  624     av_strlcatf(buff, size, 
"m=%s %d RTP/AVP %d\r\n", type, port, payload_type);
 
  625     sdp_write_address(buff, size, dest_addr, dest_type, ttl);
 
  630     sdp_write_media_attributes(buff, size, c, payload_type, fmt);
 
  636     struct sdp_session_level s = { 0 };
 
  637     int i, j, port, ttl, is_multicast, 
index = 0;
 
  638     char dst[32], dst_type[5];
 
  640     memset(buf, 0, size);
 
  642     s.src_addr = 
"127.0.0.1";    
 
  644     s.name = title ? title->
value : 
"No Name";
 
  649         port = sdp_get_address(dst, 
sizeof(dst), &ttl, ac[0]->filename);
 
  650         is_multicast = resolve_destination(dst, 
sizeof(dst), dst_type,
 
  656             s.dst_type = dst_type;
 
  658             if (!strcmp(dst_type, 
"IP6")) {
 
  664     sdp_write_header(buf, size, &s);
 
  667     for (i = 0; i < n_files; i++) {
 
  669             port = sdp_get_address(dst, 
sizeof(dst), &ttl, ac[i]->filename);
 
  670             is_multicast = resolve_destination(dst, 
sizeof(dst), dst_type,
 
  677                                dst[0] ? dst : 
NULL, dst_type,
 
  678                                (port > 0) ? port + j * 2 : 0,
 
  682                                    "a=control:streamid=%d\r\n", i + j);
 
  696                         const char *dest_addr, 
const char *dest_type,