*ttl = 0;
- if (strcmp(proto, "rtp")) {
+ if (strcmp(proto, "rtp") && strcmp(proto, "srtp")) {
/* The url isn't for the actual rtp sessions,
* don't parse out anything else than the destination.
*/
{
char *psets, *p;
const uint8_t *r;
- const char *pset_string = "; sprop-parameter-sets=";
+ static const char pset_string[] = "; sprop-parameter-sets=";
+ static const char profile_string[] = "; profile-level-id=";
uint8_t *orig_extradata = NULL;
int orig_extradata_size = 0;
+ const uint8_t *sps = NULL, *sps_end;
if (c->extradata_size > MAX_EXTRADATA_SIZE) {
av_log(c, AV_LOG_ERROR, "Too much extradata!\n");
*p = ',';
p++;
}
+ if (!sps) {
+ sps = r;
+ sps_end = r1;
+ }
if (av_base64_encode(p, MAX_PSET_SIZE - (p - psets), r, r1 - r) == NULL) {
av_log(c, AV_LOG_ERROR, "Cannot Base64-encode %td %td!\n", MAX_PSET_SIZE - (p - psets), r1 - r);
av_free(psets);
p += strlen(p);
r = r1;
}
+ if (sps && sps_end - sps >= 4) {
+ memcpy(p, profile_string, strlen(profile_string));
+ p += strlen(p);
+ ff_data_to_hex(p, sps + 1, 3, 0);
+ p[6] = '\0';
+ }
if (orig_extradata) {
av_free(c->extradata);
c->extradata = orig_extradata;
int first_header_size;
switch (c->codec_id) {
- case CODEC_ID_THEORA:
+ case AV_CODEC_ID_THEORA:
first_header_size = 42;
break;
- case CODEC_ID_VORBIS:
+ case AV_CODEC_ID_VORBIS:
first_header_size = 30;
break;
default:
char *config = NULL;
switch (c->codec_id) {
- case CODEC_ID_H264: {
+ case AV_CODEC_ID_H264: {
int mode = 1;
if (fmt && fmt->oformat->priv_class &&
av_opt_flag_is_set(fmt->priv_data, "rtpflags", "h264_mode0"))
payload_type, mode, config ? config : "");
break;
}
- case CODEC_ID_H263:
- case CODEC_ID_H263P:
+ case AV_CODEC_ID_H263:
+ case AV_CODEC_ID_H263P:
/* a=framesize is required by 3GPP TS 26.234 (PSS). It
* actually specifies the maximum video size, but we only know
* the current size. This is required for playback on Android
* stagefright and on Samsung bada. */
if (!fmt || !fmt->oformat->priv_class ||
!av_opt_flag_is_set(fmt->priv_data, "rtpflags", "rfc2190") ||
- c->codec_id == CODEC_ID_H263P)
+ c->codec_id == AV_CODEC_ID_H263P)
av_strlcatf(buff, size, "a=rtpmap:%d H263-2000/90000\r\n"
"a=framesize:%d %d-%d\r\n",
payload_type,
payload_type, c->width, c->height);
break;
- case CODEC_ID_MPEG4:
+ case AV_CODEC_ID_MPEG4:
if (c->extradata_size) {
config = extradata2config(c);
}
payload_type,
payload_type, config ? config : "");
break;
- case CODEC_ID_AAC:
+ case AV_CODEC_ID_AAC:
if (fmt && fmt->oformat->priv_class &&
av_opt_flag_is_set(fmt->priv_data, "rtpflags", "latm")) {
config = latm_context2config(c);
payload_type, config);
}
break;
- case CODEC_ID_PCM_S16BE:
+ case AV_CODEC_ID_PCM_S16BE:
if (payload_type >= RTP_PT_PRIVATE)
av_strlcatf(buff, size, "a=rtpmap:%d L16/%d/%d\r\n",
payload_type,
c->sample_rate, c->channels);
break;
- case CODEC_ID_PCM_MULAW:
+ case AV_CODEC_ID_PCM_MULAW:
if (payload_type >= RTP_PT_PRIVATE)
av_strlcatf(buff, size, "a=rtpmap:%d PCMU/%d/%d\r\n",
payload_type,
c->sample_rate, c->channels);
break;
- case CODEC_ID_PCM_ALAW:
+ case AV_CODEC_ID_PCM_ALAW:
if (payload_type >= RTP_PT_PRIVATE)
av_strlcatf(buff, size, "a=rtpmap:%d PCMA/%d/%d\r\n",
payload_type,
c->sample_rate, c->channels);
break;
- case CODEC_ID_AMR_NB:
+ case AV_CODEC_ID_AMR_NB:
av_strlcatf(buff, size, "a=rtpmap:%d AMR/%d/%d\r\n"
"a=fmtp:%d octet-align=1\r\n",
payload_type, c->sample_rate, c->channels,
payload_type);
break;
- case CODEC_ID_AMR_WB:
+ case AV_CODEC_ID_AMR_WB:
av_strlcatf(buff, size, "a=rtpmap:%d AMR-WB/%d/%d\r\n"
"a=fmtp:%d octet-align=1\r\n",
payload_type, c->sample_rate, c->channels,
payload_type);
break;
- case CODEC_ID_VORBIS:
+ case AV_CODEC_ID_VORBIS:
if (c->extradata_size)
config = xiph_extradata2config(c);
else
payload_type, c->sample_rate, c->channels,
payload_type, config);
break;
- case CODEC_ID_THEORA: {
+ case AV_CODEC_ID_THEORA: {
const char *pix_fmt;
if (c->extradata_size)
config = xiph_extradata2config(c);
return NULL;
switch (c->pix_fmt) {
- case PIX_FMT_YUV420P:
+ case AV_PIX_FMT_YUV420P:
pix_fmt = "YCbCr-4:2:0";
break;
- case PIX_FMT_YUV422P:
+ case AV_PIX_FMT_YUV422P:
pix_fmt = "YCbCr-4:2:2";
break;
- case PIX_FMT_YUV444P:
+ case AV_PIX_FMT_YUV444P:
pix_fmt = "YCbCr-4:4:4";
break;
default:
c->width, c->height, pix_fmt, config);
break;
}
- case CODEC_ID_VP8:
+ case AV_CODEC_ID_VP8:
av_strlcatf(buff, size, "a=rtpmap:%d VP8/90000\r\n",
payload_type);
break;
- case CODEC_ID_ADPCM_G722:
+ case AV_CODEC_ID_MJPEG:
+ if (payload_type >= RTP_PT_PRIVATE)
+ av_strlcatf(buff, size, "a=rtpmap:%d JPEG/90000\r\n",
+ payload_type);
+ break;
+ case AV_CODEC_ID_ADPCM_G722:
if (payload_type >= RTP_PT_PRIVATE)
av_strlcatf(buff, size, "a=rtpmap:%d G722/%d/%d\r\n",
payload_type,
8000, c->channels);
break;
- case CODEC_ID_ADPCM_G726: {
+ case AV_CODEC_ID_ADPCM_G726: {
if (payload_type >= RTP_PT_PRIVATE)
av_strlcatf(buff, size, "a=rtpmap:%d G726-%d/%d\r\n",
payload_type,
c->sample_rate);
break;
}
- case CODEC_ID_ILBC:
+ case AV_CODEC_ID_ILBC:
av_strlcatf(buff, size, "a=rtpmap:%d iLBC/%d\r\n"
"a=fmtp:%d mode=%d\r\n",
payload_type, c->sample_rate,
payload_type, c->block_align == 38 ? 20 : 30);
break;
+ case AV_CODEC_ID_SPEEX:
+ av_strlcatf(buff, size, "a=rtpmap:%d speex/%d\r\n",
+ payload_type, c->sample_rate);
+ break;
+ case AV_CODEC_ID_OPUS:
+ av_strlcatf(buff, size, "a=rtpmap:%d opus/48000\r\n",
+ payload_type);
+ break;
default:
/* Nothing special to do here... */
break;
return buff;
}
-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)
+void ff_sdp_write_media(char *buff, int size, AVStream *st, int idx,
+ const char *dest_addr, const char *dest_type,
+ int port, int ttl, AVFormatContext *fmt)
{
+ AVCodecContext *c = st->codec;
const char *type;
int payload_type;
- payload_type = ff_rtp_get_payload_type(fmt, c);
+ payload_type = ff_rtp_get_payload_type(fmt, c, idx);
switch (c->codec_type) {
case AVMEDIA_TYPE_VIDEO : type = "video" ; break;
{
AVDictionaryEntry *title = av_dict_get(ac[0]->metadata, "title", NULL, 0);
struct sdp_session_level s = { 0 };
- int i, j, port, ttl, is_multicast;
+ int i, j, port, ttl, is_multicast, index = 0;
char dst[32], dst_type[5];
memset(buf, 0, size);
ttl = 0;
}
for (j = 0; j < ac[i]->nb_streams; j++) {
- ff_sdp_write_media(buf, size,
- ac[i]->streams[j]->codec, dst[0] ? dst : NULL,
- dst_type, (port > 0) ? port + j * 2 : 0, ttl,
- ac[i]);
+ ff_sdp_write_media(buf, size, ac[i]->streams[j], index++,
+ dst[0] ? dst : NULL, dst_type,
+ (port > 0) ? port + j * 2 : 0,
+ ttl, ac[i]);
if (port <= 0) {
av_strlcatf(buf, size,
"a=control:streamid=%d\r\n", i + j);
}
+ if (ac[i]->pb && ac[i]->pb->av_class) {
+ uint8_t *crypto_suite = NULL, *crypto_params = NULL;
+ av_opt_get(ac[i]->pb, "srtp_out_suite", AV_OPT_SEARCH_CHILDREN,
+ &crypto_suite);
+ av_opt_get(ac[i]->pb, "srtp_out_params", AV_OPT_SEARCH_CHILDREN,
+ &crypto_params);
+ if (crypto_suite && crypto_suite[0])
+ av_strlcatf(buf, size,
+ "a=crypto:1 %s inline:%s\r\n",
+ crypto_suite, crypto_params);
+ av_free(crypto_suite);
+ av_free(crypto_params);
+ }
}
}
return AVERROR(ENOSYS);
}
-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)
+void ff_sdp_write_media(char *buff, int size, AVStream *st, int idx,
+ const char *dest_addr, const char *dest_type,
+ int port, int ttl, AVFormatContext *fmt)
{
}
#endif