39 #define MAX_EXTRADATA_SIZE ((INT_MAX - 10) / 2)
41 struct sdp_session_level {
58 static void sdp_write_address(
char *buff,
int size,
const char *dest_addr,
59 const char *dest_type,
int ttl)
64 if (ttl > 0 && !strcmp(dest_type,
"IP4")) {
67 av_strlcatf(buff, size,
"c=IN %s %s/%d\r\n", dest_type, dest_addr, ttl);
69 av_strlcatf(buff, size,
"c=IN %s %s\r\n", dest_type, dest_addr);
74 static void sdp_write_header(
char *buff,
int size,
struct sdp_session_level *
s)
77 "o=- %d %d IN %s %s\r\n"
80 s->id, s->version, s->src_type, s->src_addr,
82 sdp_write_address(buff, size, s->dst_addr, s->dst_type, s->ttl);
85 s->start_time, s->end_time);
89 static int resolve_destination(
char *dest_addr,
int size,
char *
type,
104 getnameinfo(ai->ai_addr, ai->ai_addrlen, dest_addr, size,
107 if (ai->ai_family == AF_INET6)
115 static int resolve_destination(
char *dest_addr,
int size,
char *type,
122 static int sdp_get_address(
char *dest_addr,
int size,
int *ttl,
const char *url)
132 if (strcmp(proto,
"rtp") && strcmp(proto,
"srtp")) {
139 p = strchr(url,
'?');
144 *ttl = strtol(buff,
NULL, 10);
153 #define MAX_PSET_SIZE 1024
158 static const char pset_string[] =
"; sprop-parameter-sets=";
159 static const char profile_string[] =
"; profile-level-id=";
183 memcpy(psets, pset_string, strlen(pset_string));
184 p = psets + strlen(pset_string);
186 while (r < extradata + extradata_size) {
191 nal_type = *r & 0x1f;
193 if (nal_type != 7 && nal_type != 8) {
197 if (p != (psets + strlen(pset_string))) {
215 if (sps && sps_end - sps >= 4) {
216 memcpy(p, profile_string, strlen(profile_string));
232 int ps_pos[3] = { 0 };
233 static const char *
const ps_names[3] = {
"vps",
"sps",
"pps" };
234 int num_arrays, num_nalus;
253 if (extradata_size < 23)
256 num_arrays = extradata[22];
258 for (i = 0; i < num_arrays; i++) {
259 int num_nalus, nalu_type;
260 if (pos + 3 > extradata_size)
262 nalu_type = extradata[pos] & 0x3f;
267 else if (nalu_type == 33)
269 else if (nalu_type == 34)
271 num_nalus =
AV_RB16(&extradata[pos + 1]);
273 for (j = 0; j < num_nalus; j++) {
275 if (pos + 2 > extradata_size)
277 len =
AV_RB16(&extradata[pos]);
279 if (pos + len > extradata_size)
284 if (!ps_pos[0] || !ps_pos[1] || !ps_pos[2])
292 for (i = 0; i < 3; i++) {
297 av_strlcatf(psets, MAX_PSET_SIZE,
"sprop-%s=", ps_names[i]);
301 num_nalus =
AV_RB16(&extradata[pos + 1]);
303 for (j = 0; j < num_nalus; j++) {
304 int len =
AV_RB16(&extradata[pos]);
309 strpos = strlen(psets);
311 &extradata[pos], len)) {
341 memcpy(config,
"; config=", 9);
350 char *
config, *encoded_config;
351 const uint8_t *header_start[3];
352 int headers_len, header_len[3], config_len;
353 int first_header_size;
357 first_header_size = 42;
360 first_header_size = 30;
368 first_header_size, header_start,
374 headers_len = header_len[0] + header_len[2];
387 if (!encoded_config) {
392 config[0] = config[1] = config[2] = 0;
397 config[7] = (headers_len >> 8) & 0xff;
398 config[8] = headers_len & 0xff;
400 config[10] = header_len[0];
402 memcpy(config + 12, header_start[0], header_len[0]);
403 memcpy(config + 12 + header_len[0], header_start[2], header_len[2]);
409 return encoded_config;
413 "Not enough memory for configuration string\n");
423 int profile_level = 0x2B;
430 profile_level = 0x28;
433 profile_level = 0x29;
435 profile_level = 0x2A;
439 profile_level = 0x2B;
443 return profile_level;
456 for (rate_index = 0; rate_index < 16; rate_index++)
459 if (rate_index == 16) {
464 config_byte[0] = 0x40;
466 config_byte[2] = 0x20 | rate_index;
468 config_byte[4] = 0x3f;
469 config_byte[5] = 0xc0;
493 config = extradata2psets(c);
495 av_strlcatf(buff, size,
"a=rtpmap:%d H264/90000\r\n"
496 "a=fmtp:%d packetization-mode=%d%s\r\n",
498 payload_type, mode, config ? config :
"");
503 const char *pic_fmt =
NULL;
510 av_strlcatf(buff, size,
"a=rtpmap:%d H261/90000\r\n", payload_type);
512 av_strlcatf(buff, size,
"a=fmtp:%d %s\r\n", payload_type, pic_fmt);
524 av_strlcatf(buff, size,
"a=rtpmap:%d H263-2000/90000\r\n"
525 "a=framesize:%d %d-%d\r\n",
531 config = extradata2psets_hevc(c);
532 av_strlcatf(buff, size,
"a=rtpmap:%d H265/90000\r\n", payload_type);
535 payload_type, config);
539 config = extradata2config(c);
541 av_strlcatf(buff, size,
"a=rtpmap:%d MP4V-ES/90000\r\n"
542 "a=fmtp:%d profile-level-id=1%s\r\n",
544 payload_type, config ? config :
"");
549 config = latm_context2config(c);
552 av_strlcatf(buff, size,
"a=rtpmap:%d MP4A-LATM/%d/%d\r\n"
553 "a=fmtp:%d profile-level-id=%d;cpresent=0;config=%s\r\n",
555 payload_type, latm_context2profilelevel(c), config);
558 config = extradata2config(c);
569 av_strlcatf(buff, size,
"a=rtpmap:%d MPEG4-GENERIC/%d/%d\r\n"
570 "a=fmtp:%d profile-level-id=1;"
571 "mode=AAC-hbr;sizelength=13;indexlength=3;"
572 "indexdeltalength=3%s\r\n",
574 payload_type, config);
579 av_strlcatf(buff, size,
"a=rtpmap:%d L16/%d/%d\r\n",
585 av_strlcatf(buff, size,
"a=rtpmap:%d PCMU/%d/%d\r\n",
591 av_strlcatf(buff, size,
"a=rtpmap:%d PCMA/%d/%d\r\n",
596 av_strlcatf(buff, size,
"a=rtpmap:%d AMR/%d/%d\r\n"
597 "a=fmtp:%d octet-align=1\r\n",
602 av_strlcatf(buff, size,
"a=rtpmap:%d AMR-WB/%d/%d\r\n"
603 "a=fmtp:%d octet-align=1\r\n",
609 config = xiph_extradata2config(c);
615 av_strlcatf(buff, size,
"a=rtpmap:%d vorbis/%d/%d\r\n"
616 "a=fmtp:%d configuration=%s\r\n",
618 payload_type, config);
624 pix_fmt =
"YCbCr-4:2:0";
627 pix_fmt =
"YCbCr-4:2:2";
630 pix_fmt =
"YCbCr-4:4:4";
638 config = xiph_extradata2config(c);
644 av_strlcatf(buff, size,
"a=rtpmap:%d theora/90000\r\n"
645 "a=fmtp:%d delivery-method=inline; "
646 "width=%d; height=%d; sampling=%s; "
647 "configuration=%s\r\n",
648 payload_type, payload_type,
653 av_strlcatf(buff, size,
"a=rtpmap:%d VP8/90000\r\n",
658 av_strlcatf(buff, size,
"a=rtpmap:%d JPEG/90000\r\n",
663 av_strlcatf(buff, size,
"a=rtpmap:%d G722/%d/%d\r\n",
669 av_strlcatf(buff, size,
"a=rtpmap:%d G726-%d/%d\r\n",
677 "a=fmtp:%d mode=%d\r\n",
682 av_strlcatf(buff, size,
"a=rtpmap:%d speex/%d\r\n",
706 av_strlcatf(buff, size,
"a=rtpmap:%d opus/48000/2\r\n",
709 av_strlcatf(buff, size,
"a=fmtp:%d sprop-stereo:1\r\n",
724 const char *dest_addr,
const char *dest_type,
737 default : type =
"application";
break;
740 av_strlcatf(buff, size,
"m=%s %d RTP/AVP %d\r\n", type, port, payload_type);
741 sdp_write_address(buff, size, dest_addr, dest_type, ttl);
746 sdp_write_media_attributes(buff, size, c, payload_type, fmt);
752 struct sdp_session_level s = { 0 };
753 int i, j, port, ttl, is_multicast,
index = 0;
754 char dst[32], dst_type[5];
756 memset(buf, 0, size);
758 s.src_addr =
"127.0.0.1";
760 s.name = title ? title->
value :
"No Name";
765 port = sdp_get_address(dst,
sizeof(dst), &ttl, ac[0]->filename);
766 is_multicast = resolve_destination(dst,
sizeof(dst), dst_type,
772 s.dst_type = dst_type;
774 if (!strcmp(dst_type,
"IP6")) {
780 sdp_write_header(buf, size, &s);
783 for (i = 0; i < n_files; i++) {
785 port = sdp_get_address(dst,
sizeof(dst), &ttl, ac[i]->filename);
786 is_multicast = resolve_destination(dst,
sizeof(dst), dst_type,
793 dst[0] ? dst :
NULL, dst_type,
794 (port > 0) ? port + j * 2 : 0,
798 "a=control:streamid=%d\r\n", i + j);
800 if (ac[i]->pb && ac[i]->pb->
av_class) {
806 if (crypto_suite && crypto_suite[0])
808 "a=crypto:1 %s inline:%s\r\n",
809 crypto_suite, crypto_params);
825 const char *dest_addr,
const char *dest_type,