[asterisk-commits] file: branch group/media_formats r410667 - in /team/group/media_formats: chan...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Mar 17 08:30:31 CDT 2014


Author: file
Date: Mon Mar 17 08:30:27 2014
New Revision: 410667

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=410667
Log:
Get chan_iax2 building again.

Modified:
    team/group/media_formats/channels/chan_iax2.c
    team/group/media_formats/channels/iax2/parser.c
    team/group/media_formats/channels/iax2/provision.c
    team/group/media_formats/include/asterisk/format_compatibility.h
    team/group/media_formats/include/asterisk/translate.h
    team/group/media_formats/main/format_compatibility.c

Modified: team/group/media_formats/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/team/group/media_formats/channels/chan_iax2.c?view=diff&rev=410667&r1=410666&r2=410667
==============================================================================
--- team/group/media_formats/channels/chan_iax2.c (original)
+++ team/group/media_formats/channels/chan_iax2.c Mon Mar 17 08:30:27 2014
@@ -1717,14 +1717,15 @@
 static iax2_format iax2_codec_choose(struct ast_codec_pref *pref, iax2_format formats, int find_best)
 {
 	struct ast_format_cap *cap;
-	struct ast_format tmpfmt;
+	struct ast_format *tmpfmt;
 	iax2_format format = 0;
-	if ((cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK))) {
-		ast_format_clear(&tmpfmt);
-		ast_format_cap_from_old_bitfield(cap, formats);
-		ast_codec_choose(pref, cap, find_best, &tmpfmt);
-		format = ast_format_to_old_bitfield(&tmpfmt);
-		cap = ast_format_cap_destroy(cap);
+
+	if ((cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
+		ast_format_compatibility_bitfield2cap(formats, cap);
+		ast_best_codec(cap, &tmpfmt);
+		format = ast_format_compatibility_format2bitfield(tmpfmt);
+		ao2_ref(tmpfmt, -1);
+		ao2_ref(cap, -1);
 	}
 
 	return format;
@@ -1732,55 +1733,69 @@
 
 static iax2_format iax2_best_codec(iax2_format formats)
 {
-	struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
-	struct ast_format tmpfmt;
+	struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+	struct ast_format *tmpfmt;
+	iax2_format format;
+
 	if (!cap) {
 		return 0;
 	}
 
-	ast_format_clear(&tmpfmt);
-	ast_format_cap_from_old_bitfield(cap, formats);
+	ast_format_compatibility_bitfield2cap(formats, cap);
 	ast_best_codec(cap, &tmpfmt);
-	cap = ast_format_cap_destroy(cap);
-	return ast_format_to_old_bitfield(&tmpfmt);
+	format = ast_format_compatibility_format2bitfield(tmpfmt);
+	ao2_ref(tmpfmt, -1);
+	ao2_ref(cap, -1);
+
+	return format;
 }
 
 const char *iax2_getformatname(iax2_format format)
 {
-	struct ast_format tmpfmt;
-	if (!(ast_format_from_old_bitfield(&tmpfmt, format))) {
+	struct ast_format *tmpfmt;
+
+	tmpfmt = ast_format_compatibility_bitfield2format(format);
+	if (!tmpfmt) {
 		return "Unknown";
 	}
 
-	return ast_getformatname(&tmpfmt);
+	return tmpfmt->codec->name;
 }
 
 static char *iax2_getformatname_multiple(char *codec_buf, size_t len, iax2_format format)
 {
-	struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
+	struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
 
 	if (!cap) {
 		return "(Nothing)";
 	}
-	ast_format_cap_from_old_bitfield(cap, format);
+	ast_format_compatibility_bitfield2cap(format, cap);
 	ast_getformatname_multiple(codec_buf, len, cap);
-	cap = ast_format_cap_destroy(cap);
+	ao2_ref(cap, -1);
 
 	return codec_buf;
 }
 
 static int iax2_parse_allow_disallow(struct ast_codec_pref *pref, iax2_format *formats, const char *list, int allowing)
 {
-	int res;
-	struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
+	int res, i;
+	struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+
 	if (!cap) {
 		return 1;
 	}
 
-	ast_format_cap_from_old_bitfield(cap, *formats);
-	res = ast_parse_allow_disallow(pref, cap, list, allowing);
-	*formats = ast_format_cap_to_old_bitfield(cap);
-	cap = ast_format_cap_destroy(cap);
+	ast_format_compatibility_bitfield2cap(*formats, cap);
+	res = ast_parse_allow_disallow(cap, list, allowing);
+
+	for (i = 0; i < ast_format_cap_count(cap); i++) {
+		struct ast_format *fmt = ast_format_cap_get_format(cap, i);
+
+		ast_codec_pref_append(pref, fmt);
+		ao2_ref(fmt, -1);
+	}
+
+	ao2_ref(cap, -1);
 
 	return res;
 }
@@ -1788,13 +1803,13 @@
 static int iax2_data_add_codecs(struct ast_data *root, const char *node_name, iax2_format formats)
 {
 	int res;
-	struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
+	struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
 	if (!cap) {
 		return -1;
 	}
-	ast_format_cap_from_old_bitfield(cap, formats);
+	ast_format_compatibility_bitfield2cap(formats, cap);
 	res = ast_data_add_codecs(root, node_name, cap);
-	cap = ast_format_cap_destroy(cap);
+	ao2_ref(cap, -1);
 	return res;
 }
 
@@ -3699,10 +3714,10 @@
 
 		ast_cli(a->fd, "  Codec Order  : (");
 		for(x = 0; x < AST_CODEC_PREF_SIZE; x++) {
-			struct ast_format tmpfmt;
+			struct ast_format *tmpfmt;
 			if(!(ast_codec_pref_index(&peer->prefs, x, &tmpfmt)))
 				break;
-			ast_cli(a->fd, "%s", ast_getformatname(&tmpfmt));
+			ast_cli(a->fd, "%s", tmpfmt->codec->name);
 			if(x < 31 && ast_codec_pref_index(&peer->prefs, x+1, &tmpfmt))
 				ast_cli(a->fd, "|");
 		}
@@ -3989,9 +4004,9 @@
 	ms = ast_tvdiff_ms(now, pvt->rxcore);
 
 	if(ms >= (next = jb_next(pvt->jb))) {
-		struct ast_format voicefmt;
-		ast_format_from_old_bitfield(&voicefmt, pvt->voiceformat);
-		ret = jb_get(pvt->jb, &frame, ms, ast_codec_interp_len(&voicefmt));
+		struct ast_format *voicefmt;
+		voicefmt = ast_format_compatibility_bitfield2format(pvt->voiceformat);
+		ret = jb_get(pvt->jb, &frame, ms, voicefmt->codec->default_ms);
 		switch(ret) {
 		case JB_OK:
 			fr = frame.data;
@@ -4005,8 +4020,8 @@
 
 			/* create an interpolation frame */
 			af.frametype = AST_FRAME_VOICE;
-			ast_format_copy(&af.subclass.format, &voicefmt);
-			af.samples  = frame.ms * (ast_format_rate(&voicefmt) / 1000);
+			af.subclass.format = voicefmt;
+			af.samples  = frame.ms * (voicefmt->codec->sample_rate / 1000);
 			af.src  = "IAX2 JB interpolation";
 			af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
 			af.offset = AST_FRIENDLY_OFFSET;
@@ -4087,7 +4102,7 @@
 
 	if(fr->af.frametype == AST_FRAME_VOICE) {
 		type = JB_TYPE_VOICE;
-		len = ast_codec_get_samples(&fr->af) / (ast_format_rate(&fr->af.subclass.format) / 1000);
+		len = fr->af.subclass.format->codec->get_samples(&fr->af) / (fr->af.subclass.format->codec->sample_rate / 1000);
 	} else if(fr->af.frametype == AST_FRAME_CNG) {
 		type = JB_TYPE_SILENCE;
 	}
@@ -4509,12 +4524,15 @@
 		/* But move the calling channel's native codec to the top of the preference list */
 		memcpy(&ourprefs, &prefs, sizeof(ourprefs));
 		if (c) {
-			struct ast_format tmpfmt;
-			ast_format_cap_iter_start(ast_channel_nativeformats(c));
-			while (!(ast_format_cap_iter_next(ast_channel_nativeformats(c), &tmpfmt))) {
-				ast_codec_pref_prepend(&ourprefs, &tmpfmt, 1);
+			int i;
+
+			for (i = 0; i < ast_format_cap_count(ast_channel_nativeformats(c)); i++) {
+				struct ast_format *format = ast_format_cap_get_format(
+					ast_channel_nativeformats(c), i);
+
+				ast_codec_pref_prepend(&ourprefs, format, 1);
+				ao2_ref(format, -1);
 			}
-			ast_format_cap_iter_end(ast_channel_nativeformats(c));
 		}
 		ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
 		return 0;
@@ -4540,13 +4558,15 @@
 	memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
 	/* Move the calling channel's native codec to the top of the preference list */
 	if (c) {
-		struct ast_format tmpfmt;
-		ast_format_cap_iter_start(ast_channel_nativeformats(c));
-		while (!(ast_format_cap_iter_next(ast_channel_nativeformats(c), &tmpfmt))) {
-			ast_debug(1, "prepending %s to prefs\n", ast_getformatname(&tmpfmt));
-			ast_codec_pref_prepend(&ourprefs, &tmpfmt, 1);
-		}
-		ast_format_cap_iter_end(ast_channel_nativeformats(c));
+		int i;
+
+		for (i = 0; i < ast_format_cap_count(ast_channel_nativeformats(c)); i++) {
+			struct ast_format *tmpfmt = ast_format_cap_get_format(
+				ast_channel_nativeformats(c), i);
+
+			ast_codec_pref_prepend(&ourprefs, tmpfmt, 1);
+			ao2_ref(tmpfmt, -1);
+		}
 	}
 	ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
 	ast_copy_string(cai->context, peer->context, sizeof(cai->context));
@@ -5086,7 +5106,7 @@
 	if (pds.password)
 		ast_string_field_set(iaxs[callno], secret, pds.password);
 
-	iax2_tmpfmt = ast_format_cap_to_old_bitfield(ast_channel_nativeformats(c));
+	iax2_tmpfmt = ast_format_compatibility_cap2bitfield(ast_channel_nativeformats(c));
 	iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) iax2_tmpfmt);
 	iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, iax2_tmpfmt);
 
@@ -5680,11 +5700,17 @@
 	struct ast_channel *tmp;
 	struct chan_iax2_pvt *i;
 	struct ast_variable *v = NULL;
-	struct ast_format tmpfmt;
+	struct ast_format_cap *native;
+	struct ast_format *tmpfmt;
 	struct ast_callid *callid;
 
 	if (!(i = iaxs[callno])) {
 		ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
+		return NULL;
+	}
+
+	native = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+	if (!native) {
 		return NULL;
 	}
 
@@ -5700,9 +5726,11 @@
 			tmp = ast_channel_release(tmp);
 			ast_mutex_lock(&iaxsl[callno]);
 		}
+		ao2_ref(native, -1);
 		return NULL;
 	}
 	if (!tmp) {
+		ao2_ref(native, -1);
 		return NULL;
 	}
 
@@ -5713,14 +5741,18 @@
 	}
 
 	ast_channel_tech_set(tmp, &iax2_tech);
+
 	/* We can support any format by default, until we get restricted */
-	ast_format_cap_from_old_bitfield(ast_channel_nativeformats(tmp), capability);
+	ast_format_compatibility_bitfield2cap(capability, native);
+	ast_channel_nativeformats_set(tmp, native);
 	ast_best_codec(ast_channel_nativeformats(tmp), &tmpfmt);
 
-	ast_format_copy(ast_channel_readformat(tmp), &tmpfmt);
-	ast_format_copy(ast_channel_rawreadformat(tmp), &tmpfmt);
-	ast_format_copy(ast_channel_writeformat(tmp), &tmpfmt);
-	ast_format_copy(ast_channel_rawwriteformat(tmp), &tmpfmt);
+	ast_channel_set_readformat(tmp, tmpfmt);
+	ast_channel_set_rawreadformat(tmp, tmpfmt);
+	ast_channel_set_writeformat(tmp, tmpfmt);
+	ast_channel_set_rawwriteformat(tmp, tmpfmt);
+
+	ao2_ref(native, -1);
 
 	ast_channel_tech_pvt_set(tmp, CALLNO_TO_PTR(i->callno));
 
@@ -5871,7 +5903,7 @@
 	int voice = 0;
 	int genuine = 0;
 	int adjust;
-	int rate = ast_format_rate(&f->subclass.format) / 1000;
+	int rate = f->subclass.format->codec->sample_rate / 1000;
 	struct timeval *delivery = NULL;
 
 
@@ -6244,9 +6276,9 @@
 		memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
 		f->frametype = fh->type;
 		if (f->frametype == AST_FRAME_VIDEO) {
-			ast_format_from_old_bitfield(&f->subclass.format, (uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1)));
+			f->subclass.format = ast_format_compatibility_bitfield2format(uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1));
 		} else if (f->frametype == AST_FRAME_VOICE) {
-			ast_format_from_old_bitfield(&f->subclass.format, uncompress_subclass(fh->csub));
+			f->subclass.format = ast_format_compatibility_bitfield2format(uncompress_subclass(fh->csub));
 		} else {
 			f->subclass.integer = uncompress_subclass(fh->csub);
 		}
@@ -6456,11 +6488,11 @@
 		fh->type = fr->af.frametype & 0xFF;
 
 		if (fr->af.frametype == AST_FRAME_VIDEO) {
-			iax2_format tmpfmt = ast_format_to_old_bitfield(&fr->af.subclass.format);
-			tmpfmt |= ast_format_get_video_mark(&fr->af.subclass.format) ? 0x1LL : 0;
+			iax2_format tmpfmt = ast_format_compatibility_format2bitfield(fr->af.subclass.format);
+			tmpfmt |= fr->af.subclass.video.rtp_marker_bit ? 0x1LL : 0;
 			fh->csub = compress_subclass(tmpfmt | ((tmpfmt & 0x1LL) << 6));
 		} else if (fr->af.frametype == AST_FRAME_VOICE) {
-			fh->csub = compress_subclass(ast_format_to_old_bitfield(&fr->af.subclass.format));
+			fh->csub = compress_subclass(ast_format_compatibility_format2bitfield(fr->af.subclass.format));
 		} else {
 			fh->csub = compress_subclass(fr->af.subclass.integer);
 		}
@@ -6483,9 +6515,9 @@
 		if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK))
 			fr->retries = -1;
 		else if (f->frametype == AST_FRAME_VOICE)
-			pvt->svoiceformat = ast_format_to_old_bitfield(&f->subclass.format);
+			pvt->svoiceformat = ast_format_compatibility_format2bitfield(f->subclass.format);
 		else if (f->frametype == AST_FRAME_VIDEO)
-			pvt->svideoformat = ast_format_to_old_bitfield(&f->subclass.format);
+			pvt->svideoformat = ast_format_compatibility_format2bitfield(f->subclass.format);
 		if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
 			if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
 				if (fr->transfer)
@@ -6516,7 +6548,7 @@
 			vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
 			vh->zeros = 0;
 			vh->callno = htons(0x8000 | fr->callno);
-			vh->ts = htons((fr->ts & 0x7FFF) | (ast_format_get_video_mark(&fr->af.subclass.format) ? 0x8000 : 0));
+			vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.video.rtp_marker_bit ? 0x8000 : 0));
 			fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
 			fr->data = vh;
 			fr->retries = -1;
@@ -9721,7 +9753,7 @@
 			ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
 			iax2_vnak(fr->callno);
 		} else {
-			ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->voiceformat);
+			f.subclass.format = ast_format_compatibility_bitfield2format(iaxs[fr->callno]->voiceformat);
 			f.datalen = len;
 			if (f.datalen >= 0) {
 				if (f.datalen)
@@ -9741,7 +9773,7 @@
 					f.mallocd = 0;
 					f.offset = 0;
 					if (f.datalen && (f.frametype == AST_FRAME_VOICE))
-						f.samples = ast_codec_get_samples(&f);
+						f.samples = f.subclass.format->codec->get_samples(&f);
 					else
 						f.samples = 0;
 					fr->outoforder = 0;
@@ -9951,12 +9983,12 @@
 		/* Retrieve the type and subclass */
 		f.frametype = fh->type;
 		if (f.frametype == AST_FRAME_VIDEO) {
-			ast_format_from_old_bitfield(&f.subclass.format, (uncompress_subclass(fh->csub & ~0x40)));
+			f.subclass.format = ast_format_compatibility_bitfield2format(uncompress_subclass(fh->csub & ~0x40));
 			if ((fh->csub >> 6) & 0x1) {
-				ast_format_set_video_mark(&f.subclass.format);
+				f.subclass.video.rtp_marker_bit = 1;
 			}
 		} else if (f.frametype == AST_FRAME_VOICE) {
-			ast_format_from_old_bitfield(&f.subclass.format, uncompress_subclass(fh->csub));
+			f.subclass.format = ast_format_compatibility_bitfield2format(uncompress_subclass(fh->csub));
 		} else {
 			f.subclass.integer = uncompress_subclass(fh->csub);
 		}
@@ -10380,22 +10412,21 @@
 		}
 
 		if (f.frametype == AST_FRAME_VOICE) {
-			if (ast_format_to_old_bitfield(&f.subclass.format) != iaxs[fr->callno]->voiceformat) {
-					iaxs[fr->callno]->voiceformat = ast_format_to_old_bitfield(&f.subclass.format);
-					ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(&f.subclass.format));
+			if (ast_format_compatibility_format2bitfield(f.subclass.format) != iaxs[fr->callno]->voiceformat) {
+					iaxs[fr->callno]->voiceformat = ast_format_compatibility_format2bitfield(f.subclass.format);
+					ast_debug(1, "Ooh, voice format changed to '%s'\n", f.subclass.format->codec->name);
 					if (iaxs[fr->callno]->owner) {
 						iax2_lock_owner(fr->callno);
 						if (iaxs[fr->callno]) {
 							if (iaxs[fr->callno]->owner) {
-								struct ast_format_cap *orignative = ast_format_cap_dup(ast_channel_nativeformats(iaxs[fr->callno]->owner));
-								struct ast_format_cap *native = ast_channel_nativeformats(iaxs[fr->callno]->owner);
-								if (orignative) {
-									ast_format_cap_set(native, &f.subclass.format);
-									if (ast_channel_readformat(iaxs[fr->callno]->owner)->id) {
+								struct ast_format_cap *native = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+								if (native) {
+									ast_format_cap_add(native, f.subclass.format, 0);
+									ast_channel_nativeformats_set(iaxs[fr->callno]->owner, native);
+									if (ast_channel_readformat(iaxs[fr->callno]->owner)) {
 										ast_set_read_format(iaxs[fr->callno]->owner, ast_channel_readformat(iaxs[fr->callno]->owner));
 									}
-									ast_format_cap_copy(native, orignative);
-									orignative = ast_format_cap_destroy(orignative);
+									ao2_ref(native, -1);
 								}
 								ast_channel_unlock(iaxs[fr->callno]->owner);
 							}
@@ -10414,9 +10445,9 @@
 			}
 		}
 		if (f.frametype == AST_FRAME_VIDEO) {
-			if (f.subclass.format.id != ast_format_id_from_old_bitfield(iaxs[fr->callno]->videoformat)) {
-				ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(&f.subclass.format));
-				iaxs[fr->callno]->videoformat = ast_format_to_old_bitfield(&f.subclass.format);
+			if (ast_format_compatibility_format2bitfield(f.subclass.format) != iaxs[fr->callno]->videoformat) {
+				ast_debug(1, "Ooh, video format changed to %s\n", f.subclass.format->codec->name);
+				iaxs[fr->callno]->videoformat = ast_format_compatibility_format2bitfield(f.subclass.format);
 			}
 		}
 		if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
@@ -10586,7 +10617,7 @@
 							strcpy(caller_pref_buf, "disabled");
 							strcpy(host_pref_buf, "disabled");
 						} else {
-							struct ast_format tmpfmt;
+							struct ast_format *tmpfmt;
 							using_prefs = "mine";
 							/* If the information elements are in here... use them */
 							if (ies.codec_prefs)
@@ -10645,7 +10676,7 @@
 										strcpy(caller_pref_buf,"disabled");
 										strcpy(host_pref_buf,"disabled");
 									} else {
-										struct ast_format tmpfmt;
+										struct ast_format *tmpfmt;
 										using_prefs = "mine";
 										if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
 											/* Do the opposite of what we tried above. */
@@ -10824,7 +10855,7 @@
 					iaxs[fr->callno]->peerformat = ies.format;
 				} else {
 					if (iaxs[fr->callno]->owner)
-						iaxs[fr->callno]->peerformat = ast_format_cap_to_old_bitfield(ast_channel_nativeformats(iaxs[fr->callno]->owner));
+						iaxs[fr->callno]->peerformat = ast_format_compatibility_cap2bitfield(ast_channel_nativeformats(iaxs[fr->callno]->owner));
 					else
 						iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
 				}
@@ -10846,12 +10877,16 @@
 							iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
 					}
 				} else {
+					struct ast_format_cap *native = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+
 					ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
 					iax2_lock_owner(fr->callno);
-					if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
+					if (iaxs[fr->callno] && iaxs[fr->callno]->owner && native) {
 						char tmp[256];
+
 						/* Switch us to use a compatible format */
-						ast_format_cap_from_old_bitfield(ast_channel_nativeformats(iaxs[fr->callno]->owner), iaxs[fr->callno]->peerformat);
+						ast_format_compatibility_bitfield2cap(iaxs[fr->callno]->peerformat, native);
+						ast_channel_nativeformats_set(iaxs[fr->callno]->owner, native);
 						ast_verb(3, "Format for call is %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), ast_channel_nativeformats(iaxs[fr->callno]->owner)));
 
 						/* Setup read/write formats properly. */
@@ -10861,6 +10896,8 @@
 							ast_set_read_format(iaxs[fr->callno]->owner, ast_channel_readformat(iaxs[fr->callno]->owner));
 						ast_channel_unlock(iaxs[fr->callno]->owner);
 					}
+
+					ao2_cleanup(native);
 				}
 				if (iaxs[fr->callno]) {
 					AST_LIST_LOCK(&dpcache);
@@ -11029,7 +11066,7 @@
 						strcpy(caller_pref_buf, "disabled");
 						strcpy(host_pref_buf, "disabled");
 					} else {
-						struct ast_format tmpfmt;
+						struct ast_format *tmpfmt;
 						using_prefs = "mine";
 						if (ies.codec_prefs)
 							ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
@@ -11090,7 +11127,7 @@
 									strcpy(caller_pref_buf,"disabled");
 									strcpy(host_pref_buf,"disabled");
 								} else {
-									struct ast_format tmpfmt;
+									struct ast_format *tmpfmt;
 									using_prefs = "mine";
 									if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
 										/* Do the opposite of what we tried above. */
@@ -11551,9 +11588,9 @@
 		f.frametype = AST_FRAME_VIDEO;
 		if (iaxs[fr->callno]->videoformat > 0) {
 			if (ntohs(vh->ts) & 0x8000LL) {
-				ast_format_set_video_mark(&f.subclass.format);
+				f.subclass.video.rtp_marker_bit = 1;
 			}
-			ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->videoformat);
+			f.subclass.format = ast_format_compatibility_bitfield2format(iaxs[fr->callno]->videoformat);
 		} else {
 			ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
 			iax2_vnak(fr->callno);
@@ -11576,7 +11613,7 @@
 		/* A mini frame */
 		f.frametype = AST_FRAME_VOICE;
 		if (iaxs[fr->callno]->voiceformat > 0)
-			ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->voiceformat);
+			f.subclass.format = ast_format_compatibility_bitfield2format(iaxs[fr->callno]->voiceformat);
 		else {
 			ast_debug(1, "Received mini frame before first full voice frame\n");
 			iax2_vnak(fr->callno);
@@ -11648,9 +11685,9 @@
 	f.offset = 0;
 	f.len = 0;
 	if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
-		f.samples = ast_codec_get_samples(&f);
+		f.samples = f.subclass.format->codec->get_samples(&f);
 		/* We need to byteswap incoming slinear samples from network byte order */
-		if (ast_format_cmp(f.subclass, ast_format_slin) == AST_FORMAT_CMP_EQUAL)
+		if (ast_format_cmp(f.subclass.format, ast_format_slin) == AST_FORMAT_CMP_EQUAL)
 			ast_frame_byteswap_be(&f);
 	} else
 		f.samples = 0;
@@ -12227,19 +12264,25 @@
 
 	if (c) {
 		struct ast_format_cap *joint;
+		struct ast_format *format;
 		if (callid) {
 			ast_channel_lock(c);
 			ast_channel_callid_set(c, callid);
 			ast_channel_unlock(c);
 		}
 
-		/* Choose a format we can live with */
-		if ((joint = ast_format_cap_joint(ast_channel_nativeformats(c), cap))) {
-			ast_format_cap_copy(ast_channel_nativeformats(c), joint);
-			joint = ast_format_cap_destroy(joint);
-		} else {
-			struct ast_format best_fmt_cap;
-			struct ast_format best_fmt_native;
+		joint = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+		if (!joint) {
+			ast_hangup(c);
+			return NULL;
+		}
+
+		ast_format_cap_get_compatible(ast_channel_nativeformats(c), cap, joint);
+
+		/* If there is no joint format find one through translation */
+		if (!ast_format_cap_count(joint)) {
+			struct ast_format *best_fmt_cap;
+			struct ast_format *best_fmt_native;
 			res = ast_translator_best_choice(cap, ast_channel_nativeformats(c), &best_fmt_cap, &best_fmt_native);
 			if (res < 0) {
 				char tmp[256];
@@ -12249,10 +12292,17 @@
 				ast_hangup(c);
 				return NULL;
 			}
-			ast_format_cap_set(ast_channel_nativeformats(c), &best_fmt_native);
-		}
-		ast_best_codec(ast_channel_nativeformats(c), ast_channel_readformat(c));
-		ast_format_copy(ast_channel_writeformat(c), ast_channel_readformat(c));
+			ast_format_cap_add(joint, best_fmt_native, 0);
+			ao2_ref(best_fmt_cap, -1);
+			ao2_ref(best_fmt_native, -1);
+		}
+		ast_channel_nativeformats_set(c, joint);
+		ast_best_codec(ast_channel_nativeformats(c), &format);
+		ast_channel_set_readformat(c, format);
+		ast_channel_set_writeformat(c, format);
+
+		ao2_ref(joint, -1);
+		ao2_ref(format, -1);
 	}
 
 	if (callid) {
@@ -14087,7 +14137,7 @@
 		iax2_getformatname_multiple(buf, len -1, peer->capability);
 	} else  if (!strncasecmp(colname, "codec[", 6)) {
 		char *codecnum, *ptr;
-		struct ast_format tmpfmt;
+		struct ast_format *tmpfmt;
 
 		/* skip over "codec" to the '[' */
 		codecnum = colname + 5;
@@ -14097,7 +14147,7 @@
 			*ptr = '\0';
 		}
 		if((ast_codec_pref_index(&peer->prefs, atoi(codecnum), &tmpfmt))) {
-			ast_copy_string(buf, ast_getformatname(&tmpfmt), len);
+			ast_copy_string(buf, tmpfmt->codec->name, len);
 		} else {
 			buf[0] = '\0';
 		}

Modified: team/group/media_formats/channels/iax2/parser.c
URL: http://svnview.digium.com/svn/asterisk/team/group/media_formats/channels/iax2/parser.c?view=diff&rev=410667&r1=410666&r2=410667
==============================================================================
--- team/group/media_formats/channels/iax2/parser.c (original)
+++ team/group/media_formats/channels/iax2/parser.c Mon Mar 17 08:30:27 2014
@@ -42,6 +42,8 @@
 #include "asterisk/lock.h"
 #include "asterisk/threadstorage.h"
 #include "asterisk/netsock2.h"
+#include "asterisk/format_cache.h"
+#include "asterisk/format_compatibility.h"
 
 #include "include/iax2.h"
 #include "include/parser.h"
@@ -1180,7 +1182,7 @@
 void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f)
 {
 	fr->af.frametype = f->frametype;
-	ast_format_copy(&fr->af.subclass.format, &f->subclass.format);
+	fr->af.subclass.format = f->subclass.format;
 	fr->af.mallocd = 0;				/* Our frame is static relative to the container */
 	fr->af.datalen = f->datalen;
 	fr->af.samples = f->samples;
@@ -1199,7 +1201,8 @@
 		}
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 		/* We need to byte-swap slinear samples from network byte order */
-		if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass.format.id == AST_FORMAT_SLINEAR)) {
+		if ((fr->af.frametype == AST_FRAME_VOICE) &&
+			(ast_format_cmp(fr->af.subclass.format, ast_format_slin) == AST_FORMAT_CMP_EQUAL)) {
 			/* 2 bytes / sample for SLINEAR */
 			ast_swapcopy_samples(fr->af.data.ptr, f->data.ptr, copy_len / 2);
 		} else

Modified: team/group/media_formats/channels/iax2/provision.c
URL: http://svnview.digium.com/svn/asterisk/team/group/media_formats/channels/iax2/provision.c?view=diff&rev=410667&r1=410666&r2=410667
==============================================================================
--- team/group/media_formats/channels/iax2/provision.c (original)
+++ team/group/media_formats/channels/iax2/provision.c Mon Mar 17 08:30:27 2014
@@ -45,6 +45,8 @@
 #include "asterisk/astdb.h"
 #include "asterisk/utils.h"
 #include "asterisk/acl.h"
+#include "asterisk/format_cache.h"
+#include "asterisk/format_compatibility.h"
 
 #include "include/iax2.h"
 #include "include/provision.h"
@@ -345,9 +347,10 @@
 			} else 
 				ast_log(LOG_WARNING, "Ignoring invalid %s '%s' for '%s' at line %d\n", v->name, v->value, s, v->lineno);
 		} else if (!strcasecmp(v->name, "codec")) {
-			struct ast_format tmpfmt;
-			if ((ast_getformatbyname(v->value, &tmpfmt)) > 0) {
-				cur->format = ast_format_to_old_bitfield(&tmpfmt);
+			struct ast_format *tmpfmt;
+			if ((tmpfmt = ast_format_cache_get(v->value))) {
+				cur->format = ast_format_compatibility_format2bitfield(tmpfmt);
+				ao2_ref(tmpfmt, -1);
 			} else
 				ast_log(LOG_WARNING, "Ignoring invalid codec '%s' for '%s' at line %d\n", v->value, s, v->lineno);
 		} else if (!strcasecmp(v->name, "tos")) {

Modified: team/group/media_formats/include/asterisk/format_compatibility.h
URL: http://svnview.digium.com/svn/asterisk/team/group/media_formats/include/asterisk/format_compatibility.h?view=diff&rev=410667&r1=410666&r2=410667
==============================================================================
--- team/group/media_formats/include/asterisk/format_compatibility.h (original)
+++ team/group/media_formats/include/asterisk/format_compatibility.h Mon Mar 17 08:30:27 2014
@@ -32,10 +32,8 @@
 
 #define AST_CODEC_PREF_SIZE 64
 struct ast_codec_pref {
-	/*! This array represents the format id's index in the global format list. */
-	char order[AST_CODEC_PREF_SIZE];
-	/*! This array represents the format's framing size if present. */
-	int framing[AST_CODEC_PREF_SIZE];
+	/*! This array is ordered by preference and contains the codec bitfield. */
+	uint64_t order[AST_CODEC_PREF_SIZE];
 };
 
 /*!
@@ -93,4 +91,38 @@
  */
 int ast_format_compatibility_bitfield2cap(uint64_t bitfield, struct ast_format_cap *cap);
 
+/*!
+ * \brief Codec located at a particular place in the preference index.
+ * \param pref preference structure to get the codec out of
+ * \param index to retrieve from
+ * \param result ast_format structure to store the index value in
+ * \return pointer to input ast_format on success, NULL on failure
+*/
+struct ast_format *ast_codec_pref_index(struct ast_codec_pref *pref, int index, struct ast_format **result);
+
+/*! \brief Remove audio a codec from a preference list */
+void ast_codec_pref_remove(struct ast_codec_pref *pref, struct ast_format *format);
+
+/*! \brief Dump audio codec preference list into a string */
+int ast_codec_pref_string(struct ast_codec_pref *pref, char *buf, size_t size);
+
+/*! \brief Append a audio codec to a preference list, removing it first if it was already there
+*/
+int ast_codec_pref_append(struct ast_codec_pref *pref, struct ast_format *format);
+
+/*! \brief Prepend an audio codec to a preference list, removing it first if it was already there
+*/
+void ast_codec_pref_prepend(struct ast_codec_pref *pref, struct ast_format *format, int only_if_existing);
+
+/*! \brief Shift an audio codec preference list up or down 65 bytes so that it becomes an ASCII string
+ * \note Due to a misunderstanding in how codec preferences are stored, this
+ * list starts at 'B', not 'A'.  For backwards compatibility reasons, this
+ * cannot change.
+ * \param pref A codec preference list structure
+ * \param buf A string denoting codec preference, appropriate for use in line transmission
+ * \param size Size of \a buf
+ * \param right Boolean:  if 0, convert from \a buf to \a pref; if 1, convert from \a pref to \a buf.
+ */
+void ast_codec_pref_convert(struct ast_codec_pref *pref, char *buf, size_t size, int right);
+
 #endif /* _AST_FORMAT_COMPATIBILITY_H */

Modified: team/group/media_formats/include/asterisk/translate.h
URL: http://svnview.digium.com/svn/asterisk/team/group/media_formats/include/asterisk/translate.h?view=diff&rev=410667&r1=410666&r2=410667
==============================================================================
--- team/group/media_formats/include/asterisk/translate.h (original)
+++ team/group/media_formats/include/asterisk/translate.h Mon Mar 17 08:30:27 2014
@@ -291,8 +291,8 @@
  */
 int ast_translator_best_choice(struct ast_format_cap *dst_cap,
 	struct ast_format_cap *src_cap,
-	struct ast_format *dst_fmt_out,
-	struct ast_format *src_fmt_out);
+	struct ast_format **dst_fmt_out,
+	struct ast_format **src_fmt_out);
 
 /*! 
  * \brief Builds a translator path

Modified: team/group/media_formats/main/format_compatibility.c
URL: http://svnview.digium.com/svn/asterisk/team/group/media_formats/main/format_compatibility.c?view=diff&rev=410667&r1=410666&r2=410667
==============================================================================
--- team/group/media_formats/main/format_compatibility.c (original)
+++ team/group/media_formats/main/format_compatibility.c Mon Mar 17 08:30:27 2014
@@ -299,4 +299,153 @@
 	}
 
 	return 0;
+}
+
+struct ast_format *ast_codec_pref_index(struct ast_codec_pref *pref, int idx, struct ast_format **result)
+{
+	if ((idx >= 0) && (idx < sizeof(pref->order)) && pref->order[idx]) {
+		*result = ast_format_compatibility_bitfield2format(pref->order[idx]);
+	} else {
+		*result = NULL;
+	}
+
+	return *result;
+}
+
+int ast_codec_pref_string(struct ast_codec_pref *pref, char *buf, size_t size)
+{
+	int x;
+	struct ast_format *format;
+	size_t total_len, slen;
+	const char *formatname;
+
+	memset(buf, 0, size);
+	total_len = size;
+	buf[0] = '(';
+	total_len--;
+	for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
+		if (total_len <= 0)
+			break;
+		if (!(ast_codec_pref_index(pref, x, &format)))
+			break;
+		slen = strlen(format->codec->name);
+		if (slen > total_len)
+			break;
+		strncat(buf, format->codec->name, total_len - 1); /* safe */
+		total_len -= slen;
+		if (total_len && x < AST_CODEC_PREF_SIZE - 1 && ast_codec_pref_index(pref, x + 1, &format)) {
+			strncat(buf, "|", total_len - 1); /* safe */
+			total_len--;
+		}
+	}
+	if (total_len) {
+		strncat(buf, ")", total_len - 1); /* safe */
+		total_len--;
+	}
+
+	return size - total_len;
+}
+
+/*! \brief Remove codec from pref list */
+void ast_codec_pref_remove(struct ast_codec_pref *pref, struct ast_format *format)
+{
+	uint64_t bitfield = ast_format_compatibility_format2bitfield(format);
+	struct ast_codec_pref oldorder;
+	int x, y = 0;
+
+	if (!pref->order[0]) {
+		return;
+	}
+
+	memcpy(&oldorder, pref, sizeof(oldorder));
+	memset(pref, 0, sizeof(*pref));
+
+	for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
+		if (!oldorder.order[x]) {
+			break;
+		}
+		if (oldorder.order[x] != bitfield) {
+			pref->order[y++] = bitfield;
+		}
+	}
+}
+
+/*! \brief Append codec to list */
+int ast_codec_pref_append(struct ast_codec_pref *pref, struct ast_format *format)
+{
+	uint64_t bitfield = ast_format_compatibility_format2bitfield(format);
+	int x;
+
+	ast_codec_pref_remove(pref, format);
+
+	for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
+		if (!pref->order[x]) {
+			pref->order[x] = bitfield;
+			break;
+		}
+	}
+
+	return x;
+}
+
+/*! \brief Prepend codec to list */
+void ast_codec_pref_prepend(struct ast_codec_pref *pref, struct ast_format *format, int only_if_existing)
+{
+	uint64_t bitfield = ast_format_compatibility_format2bitfield(format);
+	int x;
+
+	/* Now find any existing occurrence, or the end */
+	for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
+		if (!pref->order[x] || pref->order[x] == bitfield)
+			break;
+	}
+
+	/* If we failed to find any occurrence, set to the end */
+	if (x == AST_CODEC_PREF_SIZE) {
+		--x;
+	}
+
+	if (only_if_existing && !pref->order[x]) {
+		return;
+	}
+
+	/* Move down to make space to insert - either all the way to the end,
+	   or as far as the existing location (which will be overwritten) */
+	for (; x > 0; x--) {
+		pref->order[x] = pref->order[x - 1];
+	}
+
+	/* And insert the new entry */
+	pref->order[0] = bitfield;
+}
+
+void ast_codec_pref_convert(struct ast_codec_pref *pref, char *buf, size_t size, int right)
+{
+	size_t f_len;
+	int x, differential = (int) 'A', mem;
+	char *from, *to;
+
+	/* TODO re-evaluate this function.  It is using the order of the formats specified
+	 * in the global format list in a way that may not be safe. */
+	if (right) {
+		from = pref->order;
+		to = buf;
+		mem = size;
+	} else {
+		to = pref->order;
+		from = buf;
+		mem = AST_CODEC_PREF_SIZE;
+	}
+
+	memset(to, 0, mem);
+	for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
+		if (!from[x]) {
+			break;
+		}
+		to[x] = right ? (from[x] + differential) : (from[x] - differential);
+		if (!right && to[x] && (to[x] < f_len)) {
+			ast_format_copy(&pref->formats[x], &f_list[to[x]-1].format);
+		}
+	}
+	ast_format_list_destroy(f_list);
 }




More information about the asterisk-commits mailing list