|
|
@ -110,32 +110,61 @@ static char *data_to_hex(char *buff, const uint8_t *src, int s) |
|
|
|
return buff; |
|
|
|
return buff; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static char *sdp_media_attributes(char *buff, int size, AVCodecContext *c, int payload_type) |
|
|
|
static char *extradata2config(const uint8_t *extradata, int extradata_size) |
|
|
|
{ |
|
|
|
{ |
|
|
|
char *config = NULL; |
|
|
|
char *config; |
|
|
|
|
|
|
|
|
|
|
|
switch (c->codec_id) { |
|
|
|
if (extradata_size > MAX_EXTRADATA_SIZE) { |
|
|
|
case CODEC_ID_MPEG4: |
|
|
|
|
|
|
|
if (c->flags & CODEC_FLAG_GLOBAL_HEADER) { |
|
|
|
|
|
|
|
if (c->extradata_size > MAX_EXTRADATA_SIZE) { |
|
|
|
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Too many extra data!\n"); |
|
|
|
av_log(NULL, AV_LOG_ERROR, "Too many extra data!\n"); |
|
|
|
|
|
|
|
|
|
|
|
return NULL; |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
config = av_malloc(10 + c->extradata_size * 2); |
|
|
|
config = av_malloc(10 + extradata_size * 2); |
|
|
|
if (config == NULL) { |
|
|
|
if (config == NULL) { |
|
|
|
av_log(NULL, AV_LOG_ERROR, "Cannot allocate memory for the config info\n"); |
|
|
|
av_log(NULL, AV_LOG_ERROR, "Cannot allocate memory for the config info\n"); |
|
|
|
return NULL; |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
memcpy(config, "; config=", 9); |
|
|
|
memcpy(config, "; config=", 9); |
|
|
|
data_to_hex(config + 9, c->extradata, c->extradata_size); |
|
|
|
data_to_hex(config + 9, extradata, extradata_size); |
|
|
|
config[9 + c->extradata_size * 2] = 0; |
|
|
|
config[9 + extradata_size * 2] = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return config; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static char *sdp_media_attributes(char *buff, int size, AVCodecContext *c, int payload_type) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
char *config = NULL; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (c->codec_id) { |
|
|
|
|
|
|
|
case CODEC_ID_MPEG4: |
|
|
|
|
|
|
|
if (c->flags & CODEC_FLAG_GLOBAL_HEADER) { |
|
|
|
|
|
|
|
config = extradata2config(c->extradata, c->extradata_size); |
|
|
|
} |
|
|
|
} |
|
|
|
av_strlcatf(buff, size, "a=rtpmap:%d MP4V-ES/90000\r\n" |
|
|
|
av_strlcatf(buff, size, "a=rtpmap:%d MP4V-ES/90000\r\n" |
|
|
|
"a=fmtp:%d profile-level-id=1%s\r\n", |
|
|
|
"a=fmtp:%d profile-level-id=1%s\r\n", |
|
|
|
payload_type, |
|
|
|
payload_type, |
|
|
|
payload_type, config ? config : ""); |
|
|
|
payload_type, config ? config : ""); |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
case CODEC_ID_AAC: |
|
|
|
|
|
|
|
if (c->flags & CODEC_FLAG_GLOBAL_HEADER) { |
|
|
|
|
|
|
|
config = extradata2config(c->extradata, c->extradata_size); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
/* FIXME: maybe we can forge config information based on the
|
|
|
|
|
|
|
|
* codec parameters... |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "AAC with no global headers is currently not supported\n"); |
|
|
|
|
|
|
|
return NULL; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (config == NULL) { |
|
|
|
|
|
|
|
return NULL; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
av_strlcatf(buff, size, "a=rtpmap:%d MPEG4-GENERIC/%d/%d\r\n" |
|
|
|
|
|
|
|
"a=fmtp:%d profile-level-id=1;" |
|
|
|
|
|
|
|
"mode=AAC-hbr;sizelength=13;indexlength=3;" |
|
|
|
|
|
|
|
"indexdeltalength=3%s\r\n", |
|
|
|
|
|
|
|
payload_type, c->sample_rate, c->channels, |
|
|
|
|
|
|
|
payload_type, config); |
|
|
|
|
|
|
|
break; |
|
|
|
default: |
|
|
|
default: |
|
|
|
/* Nothing special to do, here... */ |
|
|
|
/* Nothing special to do, here... */ |
|
|
|
break; |
|
|
|
break; |
|
|
|