00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <string.h>
00022 #include "libavutil/avstring.h"
00023 #include "libavutil/base64.h"
00024 #include "libavutil/dict.h"
00025 #include "libavutil/parseutils.h"
00026 #include "libavutil/opt.h"
00027 #include "libavcodec/xiph.h"
00028 #include "libavcodec/mpeg4audio.h"
00029 #include "avformat.h"
00030 #include "internal.h"
00031 #include "avc.h"
00032 #include "rtp.h"
00033 #if CONFIG_NETWORK
00034 #include "network.h"
00035 #endif
00036
00037 #if CONFIG_RTP_MUXER
00038 #define MAX_EXTRADATA_SIZE ((INT_MAX - 10) / 2)
00039
00040 struct sdp_session_level {
00041 int sdp_version;
00042 int id;
00043 int version;
00044 int start_time;
00046 int end_time;
00048 int ttl;
00049 const char *user;
00050 const char *src_addr;
00051 const char *src_type;
00052 const char *dst_addr;
00053 const char *dst_type;
00054 const char *name;
00055 };
00056
00057 static void sdp_write_address(char *buff, int size, const char *dest_addr,
00058 const char *dest_type, int ttl)
00059 {
00060 if (dest_addr) {
00061 if (!dest_type)
00062 dest_type = "IP4";
00063 if (ttl > 0 && !strcmp(dest_type, "IP4")) {
00064
00065
00066 av_strlcatf(buff, size, "c=IN %s %s/%d\r\n", dest_type, dest_addr, ttl);
00067 } else {
00068 av_strlcatf(buff, size, "c=IN %s %s\r\n", dest_type, dest_addr);
00069 }
00070 }
00071 }
00072
00073 static void sdp_write_header(char *buff, int size, struct sdp_session_level *s)
00074 {
00075 av_strlcatf(buff, size, "v=%d\r\n"
00076 "o=- %d %d IN %s %s\r\n"
00077 "s=%s\r\n",
00078 s->sdp_version,
00079 s->id, s->version, s->src_type, s->src_addr,
00080 s->name);
00081 sdp_write_address(buff, size, s->dst_addr, s->dst_type, s->ttl);
00082 av_strlcatf(buff, size, "t=%d %d\r\n"
00083 "a=tool:libavformat " AV_STRINGIFY(LIBAVFORMAT_VERSION) "\r\n",
00084 s->start_time, s->end_time);
00085 }
00086
00087 #if CONFIG_NETWORK
00088 static int resolve_destination(char *dest_addr, int size, char *type,
00089 int type_size)
00090 {
00091 struct addrinfo hints, *ai;
00092 int is_multicast;
00093
00094 av_strlcpy(type, "IP4", type_size);
00095 if (!dest_addr[0])
00096 return 0;
00097
00098
00099
00100
00101 memset(&hints, 0, sizeof(hints));
00102 if (getaddrinfo(dest_addr, NULL, &hints, &ai))
00103 return 0;
00104 getnameinfo(ai->ai_addr, ai->ai_addrlen, dest_addr, size,
00105 NULL, 0, NI_NUMERICHOST);
00106 #ifdef AF_INET6
00107 if (ai->ai_family == AF_INET6)
00108 av_strlcpy(type, "IP6", type_size);
00109 #endif
00110 is_multicast = ff_is_multicast_address(ai->ai_addr);
00111 freeaddrinfo(ai);
00112 return is_multicast;
00113 }
00114 #else
00115 static int resolve_destination(char *dest_addr, int size, char *type,
00116 int type_size)
00117 {
00118 return 0;
00119 }
00120 #endif
00121
00122 static int sdp_get_address(char *dest_addr, int size, int *ttl, const char *url)
00123 {
00124 int port;
00125 const char *p;
00126 char proto[32];
00127
00128 av_url_split(proto, sizeof(proto), NULL, 0, dest_addr, size, &port, NULL, 0, url);
00129
00130 *ttl = 0;
00131
00132 if (strcmp(proto, "rtp")) {
00133
00134
00135
00136 return 0;
00137 }
00138
00139 p = strchr(url, '?');
00140 if (p) {
00141 char buff[64];
00142
00143 if (av_find_info_tag(buff, sizeof(buff), "ttl", p)) {
00144 *ttl = strtol(buff, NULL, 10);
00145 } else {
00146 *ttl = 5;
00147 }
00148 }
00149
00150 return port;
00151 }
00152
00153 #define MAX_PSET_SIZE 1024
00154 static char *extradata2psets(AVCodecContext *c)
00155 {
00156 char *psets, *p;
00157 const uint8_t *r;
00158 const char *pset_string = "; sprop-parameter-sets=";
00159
00160 if (c->extradata_size > MAX_EXTRADATA_SIZE) {
00161 av_log(c, AV_LOG_ERROR, "Too much extradata!\n");
00162
00163 return NULL;
00164 }
00165 if (c->extradata[0] == 1) {
00166 uint8_t *dummy_p;
00167 int dummy_int;
00168 AVBitStreamFilterContext *bsfc= av_bitstream_filter_init("h264_mp4toannexb");
00169
00170 if (!bsfc) {
00171 av_log(c, AV_LOG_ERROR, "Cannot open the h264_mp4toannexb BSF!\n");
00172
00173 return NULL;
00174 }
00175 av_bitstream_filter_filter(bsfc, c, NULL, &dummy_p, &dummy_int, NULL, 0, 0);
00176 av_bitstream_filter_close(bsfc);
00177 }
00178
00179 psets = av_mallocz(MAX_PSET_SIZE);
00180 if (psets == NULL) {
00181 av_log(c, AV_LOG_ERROR, "Cannot allocate memory for the parameter sets.\n");
00182 return NULL;
00183 }
00184 memcpy(psets, pset_string, strlen(pset_string));
00185 p = psets + strlen(pset_string);
00186 r = ff_avc_find_startcode(c->extradata, c->extradata + c->extradata_size);
00187 while (r < c->extradata + c->extradata_size) {
00188 const uint8_t *r1;
00189 uint8_t nal_type;
00190
00191 while (!*(r++));
00192 nal_type = *r & 0x1f;
00193 r1 = ff_avc_find_startcode(r, c->extradata + c->extradata_size);
00194 if (nal_type != 7 && nal_type != 8) {
00195 r = r1;
00196 continue;
00197 }
00198 if (p != (psets + strlen(pset_string))) {
00199 *p = ',';
00200 p++;
00201 }
00202 if (av_base64_encode(p, MAX_PSET_SIZE - (p - psets), r, r1 - r) == NULL) {
00203 av_log(c, AV_LOG_ERROR, "Cannot Base64-encode %td %td!\n", MAX_PSET_SIZE - (p - psets), r1 - r);
00204 av_free(psets);
00205
00206 return NULL;
00207 }
00208 p += strlen(p);
00209 r = r1;
00210 }
00211
00212 return psets;
00213 }
00214
00215 static char *extradata2config(AVCodecContext *c)
00216 {
00217 char *config;
00218
00219 if (c->extradata_size > MAX_EXTRADATA_SIZE) {
00220 av_log(c, AV_LOG_ERROR, "Too much extradata!\n");
00221
00222 return NULL;
00223 }
00224 config = av_malloc(10 + c->extradata_size * 2);
00225 if (config == NULL) {
00226 av_log(c, AV_LOG_ERROR, "Cannot allocate memory for the config info.\n");
00227 return NULL;
00228 }
00229 memcpy(config, "; config=", 9);
00230 ff_data_to_hex(config + 9, c->extradata, c->extradata_size, 0);
00231 config[9 + c->extradata_size * 2] = 0;
00232
00233 return config;
00234 }
00235
00236 static char *xiph_extradata2config(AVCodecContext *c)
00237 {
00238 char *config, *encoded_config;
00239 uint8_t *header_start[3];
00240 int headers_len, header_len[3], config_len;
00241 int first_header_size;
00242
00243 switch (c->codec_id) {
00244 case CODEC_ID_THEORA:
00245 first_header_size = 42;
00246 break;
00247 case CODEC_ID_VORBIS:
00248 first_header_size = 30;
00249 break;
00250 default:
00251 av_log(c, AV_LOG_ERROR, "Unsupported Xiph codec ID\n");
00252 return NULL;
00253 }
00254
00255 if (ff_split_xiph_headers(c->extradata, c->extradata_size,
00256 first_header_size, header_start,
00257 header_len) < 0) {
00258 av_log(c, AV_LOG_ERROR, "Extradata corrupt.\n");
00259 return NULL;
00260 }
00261
00262 headers_len = header_len[0] + header_len[2];
00263 config_len = 4 +
00264 3 +
00265 2 +
00266 1 +
00267 2 +
00268 headers_len;
00269
00270 config = av_malloc(config_len);
00271 if (!config)
00272 goto xiph_fail;
00273
00274 encoded_config = av_malloc(AV_BASE64_SIZE(config_len));
00275 if (!encoded_config) {
00276 av_free(config);
00277 goto xiph_fail;
00278 }
00279
00280 config[0] = config[1] = config[2] = 0;
00281 config[3] = 1;
00282 config[4] = (RTP_XIPH_IDENT >> 16) & 0xff;
00283 config[5] = (RTP_XIPH_IDENT >> 8) & 0xff;
00284 config[6] = (RTP_XIPH_IDENT ) & 0xff;
00285 config[7] = (headers_len >> 8) & 0xff;
00286 config[8] = headers_len & 0xff;
00287 config[9] = 2;
00288 config[10] = header_len[0];
00289 config[11] = 0;
00290 memcpy(config + 12, header_start[0], header_len[0]);
00291 memcpy(config + 12 + header_len[0], header_start[2], header_len[2]);
00292
00293 av_base64_encode(encoded_config, AV_BASE64_SIZE(config_len),
00294 config, config_len);
00295 av_free(config);
00296
00297 return encoded_config;
00298
00299 xiph_fail:
00300 av_log(c, AV_LOG_ERROR,
00301 "Not enough memory for configuration string\n");
00302 return NULL;
00303 }
00304
00305 static int latm_context2profilelevel(AVCodecContext *c)
00306 {
00307
00308
00309
00310
00311 int profile_level = 0x2B;
00312
00313
00314
00315
00316 if (c->sample_rate <= 24000) {
00317 if (c->channels <= 2)
00318 profile_level = 0x28;
00319 } else if (c->sample_rate <= 48000) {
00320 if (c->channels <= 2) {
00321 profile_level = 0x29;
00322 } else if (c->channels <= 5) {
00323 profile_level = 0x2A;
00324 }
00325 } else if (c->sample_rate <= 96000) {
00326 if (c->channels <= 5) {
00327 profile_level = 0x2B;
00328 }
00329 }
00330
00331 return profile_level;
00332 }
00333
00334 static char *latm_context2config(AVCodecContext *c)
00335 {
00336
00337
00338
00339
00340 uint8_t config_byte[6];
00341 int rate_index;
00342 char *config;
00343
00344 for (rate_index = 0; rate_index < 16; rate_index++)
00345 if (ff_mpeg4audio_sample_rates[rate_index] == c->sample_rate)
00346 break;
00347 if (rate_index == 16) {
00348 av_log(c, AV_LOG_ERROR, "Unsupported sample rate\n");
00349 return NULL;
00350 }
00351
00352 config_byte[0] = 0x40;
00353 config_byte[1] = 0;
00354 config_byte[2] = 0x20 | rate_index;
00355 config_byte[3] = c->channels << 4;
00356 config_byte[4] = 0x3f;
00357 config_byte[5] = 0xc0;
00358
00359 config = av_malloc(6*2+1);
00360 if (!config) {
00361 av_log(c, AV_LOG_ERROR, "Cannot allocate memory for the config info.\n");
00362 return NULL;
00363 }
00364 ff_data_to_hex(config, config_byte, 6, 1);
00365 config[12] = 0;
00366
00367 return config;
00368 }
00369
00370 static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c, int payload_type, AVFormatContext *fmt)
00371 {
00372 char *config = NULL;
00373
00374 switch (c->codec_id) {
00375 case CODEC_ID_H264:
00376 if (c->extradata_size) {
00377 config = extradata2psets(c);
00378 }
00379 av_strlcatf(buff, size, "a=rtpmap:%d H264/90000\r\n"
00380 "a=fmtp:%d packetization-mode=1%s\r\n",
00381 payload_type,
00382 payload_type, config ? config : "");
00383 break;
00384 case CODEC_ID_H263:
00385 case CODEC_ID_H263P:
00386
00387
00388
00389
00390 av_strlcatf(buff, size, "a=rtpmap:%d H263-2000/90000\r\n"
00391 "a=framesize:%d %d-%d\r\n",
00392 payload_type,
00393 payload_type, c->width, c->height);
00394 break;
00395 case CODEC_ID_MPEG4:
00396 if (c->extradata_size) {
00397 config = extradata2config(c);
00398 }
00399 av_strlcatf(buff, size, "a=rtpmap:%d MP4V-ES/90000\r\n"
00400 "a=fmtp:%d profile-level-id=1%s\r\n",
00401 payload_type,
00402 payload_type, config ? config : "");
00403 break;
00404 case CODEC_ID_AAC:
00405 if (fmt && fmt->oformat->priv_class &&
00406 av_opt_flag_is_set(fmt->priv_data, "rtpflags", "latm")) {
00407 config = latm_context2config(c);
00408 if (!config)
00409 return NULL;
00410 av_strlcatf(buff, size, "a=rtpmap:%d MP4A-LATM/%d/%d\r\n"
00411 "a=fmtp:%d profile-level-id=%d;cpresent=0;config=%s\r\n",
00412 payload_type, c->sample_rate, c->channels,
00413 payload_type, latm_context2profilelevel(c), config);
00414 } else {
00415 if (c->extradata_size) {
00416 config = extradata2config(c);
00417 } else {
00418
00419
00420
00421 av_log(c, AV_LOG_ERROR, "AAC with no global headers is currently not supported.\n");
00422 return NULL;
00423 }
00424 if (config == NULL) {
00425 return NULL;
00426 }
00427 av_strlcatf(buff, size, "a=rtpmap:%d MPEG4-GENERIC/%d/%d\r\n"
00428 "a=fmtp:%d profile-level-id=1;"
00429 "mode=AAC-hbr;sizelength=13;indexlength=3;"
00430 "indexdeltalength=3%s\r\n",
00431 payload_type, c->sample_rate, c->channels,
00432 payload_type, config);
00433 }
00434 break;
00435 case CODEC_ID_PCM_S16BE:
00436 if (payload_type >= RTP_PT_PRIVATE)
00437 av_strlcatf(buff, size, "a=rtpmap:%d L16/%d/%d\r\n",
00438 payload_type,
00439 c->sample_rate, c->channels);
00440 break;
00441 case CODEC_ID_PCM_MULAW:
00442 if (payload_type >= RTP_PT_PRIVATE)
00443 av_strlcatf(buff, size, "a=rtpmap:%d PCMU/%d/%d\r\n",
00444 payload_type,
00445 c->sample_rate, c->channels);
00446 break;
00447 case CODEC_ID_PCM_ALAW:
00448 if (payload_type >= RTP_PT_PRIVATE)
00449 av_strlcatf(buff, size, "a=rtpmap:%d PCMA/%d/%d\r\n",
00450 payload_type,
00451 c->sample_rate, c->channels);
00452 break;
00453 case CODEC_ID_AMR_NB:
00454 av_strlcatf(buff, size, "a=rtpmap:%d AMR/%d/%d\r\n"
00455 "a=fmtp:%d octet-align=1\r\n",
00456 payload_type, c->sample_rate, c->channels,
00457 payload_type);
00458 break;
00459 case CODEC_ID_AMR_WB:
00460 av_strlcatf(buff, size, "a=rtpmap:%d AMR-WB/%d/%d\r\n"
00461 "a=fmtp:%d octet-align=1\r\n",
00462 payload_type, c->sample_rate, c->channels,
00463 payload_type);
00464 break;
00465 case CODEC_ID_VORBIS:
00466 if (c->extradata_size)
00467 config = xiph_extradata2config(c);
00468 else
00469 av_log(c, AV_LOG_ERROR, "Vorbis configuration info missing\n");
00470 if (!config)
00471 return NULL;
00472
00473 av_strlcatf(buff, size, "a=rtpmap:%d vorbis/%d/%d\r\n"
00474 "a=fmtp:%d configuration=%s\r\n",
00475 payload_type, c->sample_rate, c->channels,
00476 payload_type, config);
00477 break;
00478 case CODEC_ID_THEORA: {
00479 const char *pix_fmt;
00480 if (c->extradata_size)
00481 config = xiph_extradata2config(c);
00482 else
00483 av_log(c, AV_LOG_ERROR, "Theora configuation info missing\n");
00484 if (!config)
00485 return NULL;
00486
00487 switch (c->pix_fmt) {
00488 case PIX_FMT_YUV420P:
00489 pix_fmt = "YCbCr-4:2:0";
00490 break;
00491 case PIX_FMT_YUV422P:
00492 pix_fmt = "YCbCr-4:2:2";
00493 break;
00494 case PIX_FMT_YUV444P:
00495 pix_fmt = "YCbCr-4:4:4";
00496 break;
00497 default:
00498 av_log(c, AV_LOG_ERROR, "Unsupported pixel format.\n");
00499 return NULL;
00500 }
00501
00502 av_strlcatf(buff, size, "a=rtpmap:%d theora/90000\r\n"
00503 "a=fmtp:%d delivery-method=inline; "
00504 "width=%d; height=%d; sampling=%s; "
00505 "configuration=%s\r\n",
00506 payload_type, payload_type,
00507 c->width, c->height, pix_fmt, config);
00508 break;
00509 }
00510 case CODEC_ID_VP8:
00511 av_strlcatf(buff, size, "a=rtpmap:%d VP8/90000\r\n",
00512 payload_type);
00513 break;
00514 case CODEC_ID_ADPCM_G722:
00515 if (payload_type >= RTP_PT_PRIVATE)
00516 av_strlcatf(buff, size, "a=rtpmap:%d G722/%d/%d\r\n",
00517 payload_type,
00518 8000, c->channels);
00519 break;
00520 default:
00521
00522 break;
00523 }
00524
00525 av_free(config);
00526
00527 return buff;
00528 }
00529
00530 void ff_sdp_write_media(char *buff, int size, AVCodecContext *c, const char *dest_addr, const char *dest_type, int port, int ttl, AVFormatContext *fmt)
00531 {
00532 const char *type;
00533 int payload_type;
00534
00535 payload_type = ff_rtp_get_payload_type(c);
00536 if (payload_type < 0) {
00537 payload_type = RTP_PT_PRIVATE + (c->codec_type == AVMEDIA_TYPE_AUDIO);
00538 }
00539
00540 switch (c->codec_type) {
00541 case AVMEDIA_TYPE_VIDEO : type = "video" ; break;
00542 case AVMEDIA_TYPE_AUDIO : type = "audio" ; break;
00543 case AVMEDIA_TYPE_SUBTITLE: type = "text" ; break;
00544 default : type = "application"; break;
00545 }
00546
00547 av_strlcatf(buff, size, "m=%s %d RTP/AVP %d\r\n", type, port, payload_type);
00548 sdp_write_address(buff, size, dest_addr, dest_type, ttl);
00549 if (c->bit_rate) {
00550 av_strlcatf(buff, size, "b=AS:%d\r\n", c->bit_rate / 1000);
00551 }
00552
00553 sdp_write_media_attributes(buff, size, c, payload_type, fmt);
00554 }
00555
00556 int av_sdp_create(AVFormatContext *ac[], int n_files, char *buf, int size)
00557 {
00558 AVDictionaryEntry *title = av_dict_get(ac[0]->metadata, "title", NULL, 0);
00559 struct sdp_session_level s;
00560 int i, j, port, ttl, is_multicast;
00561 char dst[32], dst_type[5];
00562
00563 memset(buf, 0, size);
00564 memset(&s, 0, sizeof(struct sdp_session_level));
00565 s.user = "-";
00566 s.src_addr = "127.0.0.1";
00567 s.src_type = "IP4";
00568 s.name = title ? title->value : "No Name";
00569
00570 port = 0;
00571 ttl = 0;
00572 if (n_files == 1) {
00573 port = sdp_get_address(dst, sizeof(dst), &ttl, ac[0]->filename);
00574 is_multicast = resolve_destination(dst, sizeof(dst), dst_type,
00575 sizeof(dst_type));
00576 if (!is_multicast)
00577 ttl = 0;
00578 if (dst[0]) {
00579 s.dst_addr = dst;
00580 s.dst_type = dst_type;
00581 s.ttl = ttl;
00582 if (!strcmp(dst_type, "IP6")) {
00583 s.src_addr = "::1";
00584 s.src_type = "IP6";
00585 }
00586 }
00587 }
00588 sdp_write_header(buf, size, &s);
00589
00590 dst[0] = 0;
00591 for (i = 0; i < n_files; i++) {
00592 if (n_files != 1) {
00593 port = sdp_get_address(dst, sizeof(dst), &ttl, ac[i]->filename);
00594 is_multicast = resolve_destination(dst, sizeof(dst), dst_type,
00595 sizeof(dst_type));
00596 if (!is_multicast)
00597 ttl = 0;
00598 }
00599 for (j = 0; j < ac[i]->nb_streams; j++) {
00600 ff_sdp_write_media(buf, size,
00601 ac[i]->streams[j]->codec, dst[0] ? dst : NULL,
00602 dst_type, (port > 0) ? port + j * 2 : 0, ttl,
00603 ac[i]);
00604 if (port <= 0) {
00605 av_strlcatf(buf, size,
00606 "a=control:streamid=%d\r\n", i + j);
00607 }
00608 }
00609 }
00610
00611 return 0;
00612 }
00613 #else
00614 int av_sdp_create(AVFormatContext *ac[], int n_files, char *buf, int size)
00615 {
00616 return AVERROR(ENOSYS);
00617 }
00618
00619 void ff_sdp_write_media(char *buff, int size, AVCodecContext *c, const char *dest_addr, const char *dest_type, int port, int ttl, AVFormatContext *fmt)
00620 {
00621 }
00622 #endif
00623
00624 #if FF_API_SDP_CREATE
00625 int avf_sdp_create(AVFormatContext *ac[], int n_files, char *buff, int size)
00626 {
00627 return av_sdp_create(ac, n_files, buff, size);
00628 }
00629 #endif