+static char *xiph_extradata2config(AVCodecContext *c)
+{
+ char *config, *encoded_config;
+ uint8_t *header_start[3];
+ int headers_len, header_len[3], config_len;
+ int first_header_size;
+
+ switch (c->codec_id) {
+ case AV_CODEC_ID_THEORA:
+ first_header_size = 42;
+ break;
+ case AV_CODEC_ID_VORBIS:
+ first_header_size = 30;
+ break;
+ default:
+ av_log(c, AV_LOG_ERROR, "Unsupported Xiph codec ID\n");
+ return NULL;
+ }
+
+ if (avpriv_split_xiph_headers(c->extradata, c->extradata_size,
+ first_header_size, header_start,
+ header_len) < 0) {
+ av_log(c, AV_LOG_ERROR, "Extradata corrupt.\n");
+ return NULL;
+ }
+
+ headers_len = header_len[0] + header_len[2];
+ config_len = 4 + // count
+ 3 + // ident
+ 2 + // packet size
+ 1 + // header count
+ 2 + // header size
+ headers_len; // and the rest
+
+ config = av_malloc(config_len);
+ if (!config)
+ goto xiph_fail;
+
+ encoded_config = av_malloc(AV_BASE64_SIZE(config_len));
+ if (!encoded_config) {
+ av_free(config);
+ goto xiph_fail;
+ }
+
+ config[0] = config[1] = config[2] = 0;
+ config[3] = 1;
+ config[4] = (RTP_XIPH_IDENT >> 16) & 0xff;
+ config[5] = (RTP_XIPH_IDENT >> 8) & 0xff;
+ config[6] = (RTP_XIPH_IDENT ) & 0xff;
+ config[7] = (headers_len >> 8) & 0xff;
+ config[8] = headers_len & 0xff;
+ config[9] = 2;
+ config[10] = header_len[0];
+ config[11] = 0; // size of comment header; nonexistent
+ memcpy(config + 12, header_start[0], header_len[0]);
+ memcpy(config + 12 + header_len[0], header_start[2], header_len[2]);
+
+ av_base64_encode(encoded_config, AV_BASE64_SIZE(config_len),
+ config, config_len);
+ av_free(config);
+
+ return encoded_config;
+
+xiph_fail:
+ av_log(c, AV_LOG_ERROR,
+ "Not enough memory for configuration string\n");
+ return NULL;
+}
+
+static int latm_context2profilelevel(AVCodecContext *c)
+{
+ /* MP4A-LATM
+ * The RTP payload format specification is described in RFC 3016
+ * The encoding specifications are provided in ISO/IEC 14496-3 */
+
+ int profile_level = 0x2B;
+
+ /* TODO: AAC Profile only supports AAC LC Object Type.
+ * Different Object Types should implement different Profile Levels */
+
+ if (c->sample_rate <= 24000) {
+ if (c->channels <= 2)
+ profile_level = 0x28; // AAC Profile, Level 1
+ } else if (c->sample_rate <= 48000) {
+ if (c->channels <= 2) {
+ profile_level = 0x29; // AAC Profile, Level 2
+ } else if (c->channels <= 5) {
+ profile_level = 0x2A; // AAC Profile, Level 4
+ }
+ } else if (c->sample_rate <= 96000) {
+ if (c->channels <= 5) {
+ profile_level = 0x2B; // AAC Profile, Level 5
+ }
+ }
+
+ return profile_level;
+}
+
+static char *latm_context2config(AVCodecContext *c)
+{
+ /* MP4A-LATM
+ * The RTP payload format specification is described in RFC 3016
+ * The encoding specifications are provided in ISO/IEC 14496-3 */
+
+ uint8_t config_byte[6];
+ int rate_index;
+ char *config;
+
+ for (rate_index = 0; rate_index < 16; rate_index++)
+ if (avpriv_mpeg4audio_sample_rates[rate_index] == c->sample_rate)
+ break;
+ if (rate_index == 16) {
+ av_log(c, AV_LOG_ERROR, "Unsupported sample rate\n");
+ return NULL;
+ }
+
+ config_byte[0] = 0x40;
+ config_byte[1] = 0;
+ config_byte[2] = 0x20 | rate_index;
+ config_byte[3] = c->channels << 4;
+ config_byte[4] = 0x3f;
+ config_byte[5] = 0xc0;
+
+ config = av_malloc(6*2+1);
+ if (!config) {
+ av_log(c, AV_LOG_ERROR, "Cannot allocate memory for the config info.\n");
+ return NULL;
+ }
+ ff_data_to_hex(config, config_byte, 6, 1);
+ config[12] = 0;
+
+ return config;
+}
+
+static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c, int payload_type, AVFormatContext *fmt)