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)
127 av_url_split(proto,
sizeof(proto), NULL, 0, dest_addr, size, &port, NULL, 0, url);
131 if (strcmp(proto,
"rtp") && strcmp(proto,
"srtp")) {
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=";
159 uint8_t *orig_extradata = NULL;
160 int orig_extradata_size = 0;
161 const uint8_t *sps = NULL, *sps_end;
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);
684 if (ac[i]->pb && ac[i]->pb->
av_class) {
685 uint8_t *crypto_suite = NULL, *crypto_params = NULL;
690 if (crypto_suite && crypto_suite[0])
692 "a=crypto:1 %s inline:%s\r\n",
693 crypto_suite, crypto_params);
709 const char *dest_addr,
const char *dest_type,