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,
101 memset(&hints, 0,
sizeof(hints));
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")) {
139 p = strchr(url,
'?');
144 *ttl = strtol(buff,
NULL, 10);
153 #define MAX_PSET_SIZE 1024
158 const char *pset_string =
"; sprop-parameter-sets=";
159 uint8_t *orig_extradata =
NULL;
160 int orig_extradata_size = 0;
179 orig_extradata =
av_mallocz(orig_extradata_size +
181 if (!orig_extradata) {
185 memcpy(orig_extradata, c->
extradata, orig_extradata_size);
196 memcpy(psets, pset_string, strlen(pset_string));
197 p = psets + strlen(pset_string);
204 nal_type = *r & 0x1f;
206 if (nal_type != 7 && nal_type != 8) {
210 if (p != (psets + strlen(pset_string))) {
215 av_log(c,
AV_LOG_ERROR,
"Cannot Base64-encode %td %td!\n", MAX_PSET_SIZE - (p - psets), r1 - r);
223 if (orig_extradata) {
242 if (config ==
NULL) {
246 memcpy(config,
"; config=", 9);
255 char *config, *encoded_config;
256 uint8_t *header_start[3];
257 int headers_len, header_len[3], config_len;
258 int first_header_size;
262 first_header_size = 42;
265 first_header_size = 30;
273 first_header_size, header_start,
279 headers_len = header_len[0] + header_len[2];
292 if (!encoded_config) {
297 config[0] = config[1] = config[2] = 0;
302 config[7] = (headers_len >> 8) & 0xff;
303 config[8] = headers_len & 0xff;
305 config[10] = header_len[0];
307 memcpy(config + 12, header_start[0], header_len[0]);
308 memcpy(config + 12 + header_len[0], header_start[2], header_len[2]);
314 return encoded_config;
318 "Not enough memory for configuration string\n");
328 int profile_level = 0x2B;
335 profile_level = 0x28;
338 profile_level = 0x29;
340 profile_level = 0x2A;
344 profile_level = 0x2B;
348 return profile_level;
357 uint8_t config_byte[6];
361 for (rate_index = 0; rate_index < 16; rate_index++)
364 if (rate_index == 16) {
369 config_byte[0] = 0x40;
371 config_byte[2] = 0x20 | rate_index;
373 config_byte[4] = 0x3f;
374 config_byte[5] = 0xc0;
394 config = extradata2psets(c);
396 av_strlcatf(buff, size,
"a=rtpmap:%d H264/90000\r\n"
397 "a=fmtp:%d packetization-mode=1%s\r\n",
399 payload_type, config ? config :
"");
407 av_strlcatf(buff, size,
"a=rtpmap:%d H263-2000/90000\r\n"
408 "a=framesize:%d %d-%d\r\n",
414 config = extradata2config(c);
416 av_strlcatf(buff, size,
"a=rtpmap:%d MP4V-ES/90000\r\n"
417 "a=fmtp:%d profile-level-id=1%s\r\n",
419 payload_type, config ? config :
"");
424 config = latm_context2config(c);
427 av_strlcatf(buff, size,
"a=rtpmap:%d MP4A-LATM/%d/%d\r\n"
428 "a=fmtp:%d profile-level-id=%d;cpresent=0;config=%s\r\n",
430 payload_type, latm_context2profilelevel(c), config);
433 config = extradata2config(c);
441 if (config ==
NULL) {
444 av_strlcatf(buff, size,
"a=rtpmap:%d MPEG4-GENERIC/%d/%d\r\n"
445 "a=fmtp:%d profile-level-id=1;"
446 "mode=AAC-hbr;sizelength=13;indexlength=3;"
447 "indexdeltalength=3%s\r\n",
449 payload_type, config);
454 av_strlcatf(buff, size,
"a=rtpmap:%d L16/%d/%d\r\n",
460 av_strlcatf(buff, size,
"a=rtpmap:%d PCMU/%d/%d\r\n",
466 av_strlcatf(buff, size,
"a=rtpmap:%d PCMA/%d/%d\r\n",
471 av_strlcatf(buff, size,
"a=rtpmap:%d AMR/%d/%d\r\n"
472 "a=fmtp:%d octet-align=1\r\n",
477 av_strlcatf(buff, size,
"a=rtpmap:%d AMR-WB/%d/%d\r\n"
478 "a=fmtp:%d octet-align=1\r\n",
484 config = xiph_extradata2config(c);
490 av_strlcatf(buff, size,
"a=rtpmap:%d vorbis/%d/%d\r\n"
491 "a=fmtp:%d configuration=%s\r\n",
493 payload_type, config);
498 config = xiph_extradata2config(c);
506 pix_fmt =
"YCbCr-4:2:0";
509 pix_fmt =
"YCbCr-4:2:2";
512 pix_fmt =
"YCbCr-4:4:4";
519 av_strlcatf(buff, size,
"a=rtpmap:%d theora/90000\r\n"
520 "a=fmtp:%d delivery-method=inline; "
521 "width=%d; height=%d; sampling=%s; "
522 "configuration=%s\r\n",
523 payload_type, payload_type,
528 av_strlcatf(buff, size,
"a=rtpmap:%d VP8/90000\r\n",
533 av_strlcatf(buff, size,
"a=rtpmap:%d G722/%d/%d\r\n",
539 av_strlcatf(buff, size,
"a=rtpmap:%d G726-%d/%d\r\n",
566 default : type =
"application";
break;
569 av_strlcatf(buff, size,
"m=%s %d RTP/AVP %d\r\n", type, port, payload_type);
570 sdp_write_address(buff, size, dest_addr, dest_type, ttl);
575 sdp_write_media_attributes(buff, size, c, payload_type, fmt);
581 struct sdp_session_level s;
582 int i, j, port, ttl, is_multicast;
583 char dst[32], dst_type[5];
585 memset(buf, 0, size);
586 memset(&s, 0,
sizeof(
struct sdp_session_level));
588 s.src_addr =
"127.0.0.1";
590 s.name = title ? title->
value :
"No Name";
595 port = sdp_get_address(dst,
sizeof(dst), &ttl, ac[0]->filename);
596 is_multicast = resolve_destination(dst,
sizeof(dst), dst_type,
602 s.dst_type = dst_type;
604 if (!strcmp(dst_type,
"IP6")) {
610 sdp_write_header(buf, size, &s);
613 for (i = 0; i < n_files; i++) {
615 port = sdp_get_address(dst,
sizeof(dst), &ttl, ac[i]->filename);
616 is_multicast = resolve_destination(dst,
sizeof(dst), dst_type,
623 ac[i]->streams[j]->codec, dst[0] ? dst :
NULL,
624 dst_type, (port > 0) ? port + j * 2 : 0, ttl,
628 "a=control:streamid=%d\r\n", i + j);
646 #if FF_API_SDP_CREATE
647 int avf_sdp_create(
AVFormatContext *ac[],
int n_files,
char *buff,
int size)