[asterisk-commits] jrose: branch group/media_formats-reviewed-trunk r418635 - in /team/group/med...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jul 15 12:03:05 CDT 2014


Author: jrose
Date: Tue Jul 15 12:03:01 2014
New Revision: 418635

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=418635
Log:
media formats: Get chan_iax2 to be runnable/usable in media formats branch

This patch fixes a missing symbol in chan_iax2, gets codec preferences to
be read and interpreted properly, and restores the ability to make basic
chan_iax2 calls. While codec preferences are read and interpreted properly
with this patch, they still aren't being applied (that's in progress)

(issue ASTERISK-23958)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/3747/

Modified:
    team/group/media_formats-reviewed-trunk/channels/chan_iax2.c
    team/group/media_formats-reviewed-trunk/channels/iax2/parser.c
    team/group/media_formats-reviewed-trunk/include/asterisk/format_compatibility.h
    team/group/media_formats-reviewed-trunk/main/format_compatibility.c

Modified: team/group/media_formats-reviewed-trunk/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/team/group/media_formats-reviewed-trunk/channels/chan_iax2.c?view=diff&rev=418635&r1=418634&r2=418635
==============================================================================
--- team/group/media_formats-reviewed-trunk/channels/chan_iax2.c (original)
+++ team/group/media_formats-reviewed-trunk/channels/chan_iax2.c Tue Jul 15 12:03:01 2014
@@ -1883,8 +1883,24 @@
 		return 1;
 	}
 
-	ast_format_compatibility_bitfield2cap(*formats, cap);
+	/* We want to add the formats to the cap in the preferred order */
+	for (i = 0; i < AST_CODEC_PREF_SIZE; i++) {
+		uint64_t pref_as_bitfield = ast_codec_pref_order_value_to_format_bitfield(pref->order[i]);
+
+		if (!pref_as_bitfield) {
+			break;
+		}
+
+		if (ast_format_compatibility_bitfield2cap(pref_as_bitfield, cap)) {
+			ao2_ref(cap, -1);
+			return 1;
+		}
+	}
+
 	res = ast_format_cap_update_by_allow_disallow(cap, list, allowing);
+	*formats = ast_format_compatibility_cap2bitfield(cap);
+
+	ast_codec_pref_remove_missing(pref, *formats);
 
 	for (i = 0; i < ast_format_cap_count(cap); i++) {
 		struct ast_format *fmt = ast_format_cap_get_format(cap, i);
@@ -3756,7 +3772,7 @@
 	struct iax2_peer *peer;
 	struct ast_str *codec_buf = ast_str_alloca(64);
 	struct ast_str *encmethods = ast_str_alloca(256);
-	int x = 0, load_realtime = 0;
+	int load_realtime = 0;
 
 	switch (cmd) {
 	case CLI_INIT:
@@ -3808,19 +3824,10 @@
 		ast_cli(a->fd, "  Codecs       : ");
 		ast_cli(a->fd, "%s\n", iax2_getformatname_multiple(peer->capability, &codec_buf));
 
-		ast_cli(a->fd, "  Codec Order  : (");
-		for(x = 0; x < AST_CODEC_PREF_SIZE; x++) {
-			struct ast_format *tmpfmt;
-			if(!(ast_codec_pref_index(&peer->prefs, x, &tmpfmt)))
-				break;
-			ast_cli(a->fd, "%s", ast_format_get_name(tmpfmt));
-			if(x < 31 && ast_codec_pref_index(&peer->prefs, x+1, &tmpfmt))
-				ast_cli(a->fd, "|");
-		}
-
-		if (!x)
-			ast_cli(a->fd, "none");
-		ast_cli(a->fd, ")\n");
+		ast_cli(a->fd, "  Codec Order  : ");
+		if (ast_codec_pref_string(&peer->prefs, cbuf, sizeof(cbuf)) != -1) {
+			ast_cli(a->fd, "%s\n", cbuf);
+		}
 
 		ast_cli(a->fd, "  Status       : ");
 		peer_status(peer, status, sizeof(status));
@@ -6005,7 +6012,7 @@
 	int voice = 0;
 	int genuine = 0;
 	int adjust;
-	int rate = ast_format_get_sample_rate(f->subclass.format) / 1000;
+	int rate = 0;
 	struct timeval *delivery = NULL;
 
 
@@ -6017,6 +6024,7 @@
 	*/
 	if (f->frametype == AST_FRAME_VOICE) {
 		voice = 1;
+		rate = ast_format_get_sample_rate(f->subclass.format) / 1000;
 		delivery = &f->delivery;
 	} else if (f->frametype == AST_FRAME_IAX) {
 		genuine = 1;
@@ -6126,8 +6134,9 @@
 		}
 	}
 	p->lastsent = ms;
-	if (voice)
+	if (voice) {
 		p->nextpred = p->nextpred + f->samples / rate;
+	}
 	return ms;
 }
 

Modified: team/group/media_formats-reviewed-trunk/channels/iax2/parser.c
URL: http://svnview.digium.com/svn/asterisk/team/group/media_formats-reviewed-trunk/channels/iax2/parser.c?view=diff&rev=418635&r1=418634&r2=418635
==============================================================================
--- team/group/media_formats-reviewed-trunk/channels/iax2/parser.c (original)
+++ team/group/media_formats-reviewed-trunk/channels/iax2/parser.c Tue Jul 15 12:03:01 2014
@@ -1183,6 +1183,7 @@
 {
 	fr->af.frametype = f->frametype;
 	fr->af.subclass.format = f->subclass.format;
+	fr->af.subclass.integer = f->subclass.integer;
 	fr->af.mallocd = 0;				/* Our frame is static relative to the container */
 	fr->af.datalen = f->datalen;
 	fr->af.samples = f->samples;

Modified: team/group/media_formats-reviewed-trunk/include/asterisk/format_compatibility.h
URL: http://svnview.digium.com/svn/asterisk/team/group/media_formats-reviewed-trunk/include/asterisk/format_compatibility.h?view=diff&rev=418635&r1=418634&r2=418635
==============================================================================
--- team/group/media_formats-reviewed-trunk/include/asterisk/format_compatibility.h (original)
+++ team/group/media_formats-reviewed-trunk/include/asterisk/format_compatibility.h Tue Jul 15 12:03:01 2014
@@ -37,6 +37,29 @@
 	/*! Framing size of the codec */
 	unsigned int framing[AST_CODEC_PREF_SIZE];
 };
+
+/*!
+ * \brief Convert an ast_codec_pref order value into a format bitfield
+ *
+ * \param order_value value being converted
+ *
+ * \return the bitfield value of the order_value format
+ */
+uint64_t ast_codec_pref_order_value_to_format_bitfield(uint64_t order_value);
+
+/*!
+ * \brief Convert a format bitfield into an ast_codec_pref order value
+ *
+ * \param bitfield value being converted
+ *
+ * \return the ast_codec_pref order value of the most significant format
+ *  in the bitfield.
+ *
+ * \note This is really meant to be used on single format bitfields.
+ *  It will work with multiformat bitfields, but it can only return the
+ *  index of the most significant one if that is the case.
+ */
+uint64_t ast_codec_pref_format_bitfield_to_order_value(uint64_t bitfield);
 
 /*!
  * \brief Convert a format structure to its respective bitfield
@@ -105,10 +128,23 @@
 /*! \brief Convert a preference structure to a capabilities structure */
 void ast_codec_pref_to_cap(struct ast_codec_pref *pref, struct ast_format_cap *cap);
 
-/*! \brief Remove audio a codec from a preference list */
-void ast_codec_pref_remove(struct ast_codec_pref *pref, struct ast_format *format);
+/*! \brief Removes format from the pref list that aren't in the bitfield */
+void ast_codec_pref_remove_missing(struct ast_codec_pref *pref, uint64_t bitfield);
 
-/*! \brief Dump audio codec preference list into a string */
+/*!
+ * \brief Dump audio codec preference list into a string
+ *
+ * \param pref preference structure to dump string representation of order for
+ * \param buf character buffer to put string into
+ * \param size size of the character buffer
+ *
+ * \return -1 on error. Otherwise returns the remaining spaaaaaace in the buffer.
+ *
+ * \note Format is (codec1|codec2|codec3|...) -- if the list is too long for the
+ *  size of the buffer, codecs will be written until they exceed the length
+ *  remaining in which case the list will be closed with '...)' after the last
+ *  writable codec.
+ */
 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

Modified: team/group/media_formats-reviewed-trunk/main/format_compatibility.c
URL: http://svnview.digium.com/svn/asterisk/team/group/media_formats-reviewed-trunk/main/format_compatibility.c?view=diff&rev=418635&r1=418634&r2=418635
==============================================================================
--- team/group/media_formats-reviewed-trunk/main/format_compatibility.c (original)
+++ team/group/media_formats-reviewed-trunk/main/format_compatibility.c Tue Jul 15 12:03:01 2014
@@ -336,41 +336,35 @@
 	return 0;
 }
 
-#if 0
-#error BUGBUG: these procedures need to be converted
 void ast_codec_pref_convert(struct ast_codec_pref *pref, char *buf, size_t size, int right)
 {
-	size_t f_len;
-	const struct ast_format_list *f_list = ast_format_list_get(&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. */
+	static int differential = (int) 'A';
+	int x;
+
 	if (right) {
-		from = pref->order;
-		to = buf;
-		mem = size;
+		for (x = 0; x < AST_CODEC_PREF_SIZE && x < size; x++) {
+			if (!pref->order[x]) {
+				break;
+			}
+
+			buf[x] = pref->order[x] + differential;
+		}
+
+		buf[x] = '\0';
 	} 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);
-}
-
-#endif
+		for (x = 0; x < AST_CODEC_PREF_SIZE && x < size; x++) {
+			if (buf[x] == '\0') {
+				break;
+			}
+
+			pref->order[x] = buf[x] - differential;
+		}
+
+		if (x < size) {
+			pref->order[x] = 0;
+		}
+	}
+}
 
 struct ast_format *ast_codec_pref_index(struct ast_codec_pref *pref, int idx, struct ast_format **result)
 {
@@ -398,71 +392,171 @@
 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;
+	struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+	size_t total_len;
+	char *cur;
+
+	if (!cap) {
+		return -1;
+	}
+
+	/* This function is useless if you have less than a 6 character buffer.
+	 * '(...)' is six characters. */
+	if (size < 6) {
+		return -1;
+	}
+
+	/* Convert the preferences into a format cap so that we can read the formst names */
+	for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
+		uint64_t bitfield = ast_codec_pref_order_value_to_format_bitfield(pref->order[x]);
+		if (!bitfield) {
+			break;
+		}
+
+		ast_format_compatibility_bitfield2cap(bitfield, cap);
+	}
+
+	/* We know that at a minimum, 3 characters are used - (, ), and \0 */
+	total_len = size - 3;
 
 	memset(buf, 0, size);
-	total_len = size;
+
+	/* This character has already been accounted for total_len purposes */
 	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(ast_format_get_name(format));
-		if (slen > total_len)
-			break;
-		strncat(buf, ast_format_get_name(format), 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--;
-	}
+	cur = buf + 1;
+
+	/* Loop through the formats and write as many into the buffer as we can */
+	for (x = 0; x < ast_format_cap_count(cap); x++) {
+		size_t name_len;
+		struct ast_format *fmt = ast_format_cap_get_format(cap, x);
+		const char *name = ast_format_get_name(fmt);
+
+		name_len = strlen(name);
+
+		/* all entries after the first need a delimiter character */
+		if (x) {
+			name_len++;
+		}
+
+		/* Terminate the list early if we don't have room for the entry.
+		 * If it's not the last entry in the list, save enough room to write '...'.
+		 */
+		if (((x == ast_format_cap_count(cap) - 1) && (total_len < name_len)) ||
+				((x < ast_format_cap_count(cap) - 1) && (total_len < name_len + 3))) {
+			strcpy(cur, "...");
+			cur += 3;
+			total_len -= 3;
+			ao2_ref(fmt, -1);
+			break;
+		}
+
+		sprintf(cur, "%s%s", x ? "|" : "", name);
+		cur += name_len;
+		total_len -= name_len;
+
+		ao2_ref(fmt, -1);
+	}
+	ao2_ref(cap, -1);
+
+	/* These two characters have already been accounted for total_len purposes */
+	cur[0] = ')';
+	cur[1] = '\0';
 
 	return size - total_len;
 }
 
+static void codec_pref_remove_index(struct ast_codec_pref *pref, int codec_pref_index)
+{
+	int x;
+
+	for (x = codec_pref_index; x < AST_CODEC_PREF_SIZE; x++) {
+		pref->order[x] = pref->order[x + 1];
+		pref->framing[x] = pref->framing[x + 1];
+		if (!pref->order[x]) {
+			return;
+		}
+	}
+}
+
 /*! \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;
+static void codec_pref_remove(struct ast_codec_pref *pref, int format_index)
+{
+	int x;
 
 	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;
-		}
-	}
+		if (!pref->order[x]) {
+			break;
+		}
+
+		if (pref->order[x] == format_index) {
+			codec_pref_remove_index(pref, x);
+			break;
+		}
+	}
+}
+
+void ast_codec_pref_remove_missing(struct ast_codec_pref *pref, uint64_t bitfield)
+{
+	int x;
+
+	if (!pref->order[0]) {
+		return;
+	}
+
+	for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
+		uint64_t format_as_bitfield = ast_codec_pref_order_value_to_format_bitfield(pref->order[x]);
+		if (!pref->order[x]) {
+			break;
+		}
+
+		/* If this format isn't in the bitfield, remove it from the prefs. */
+		if (!(format_as_bitfield & bitfield)) {
+			codec_pref_remove_index(pref, x);
+		}
+	}
+}
+
+uint64_t ast_codec_pref_order_value_to_format_bitfield(uint64_t order_value)
+{
+	if (!order_value) {
+		return 0;
+	}
+
+	return 1 << (order_value - 1);
+}
+
+uint64_t ast_codec_pref_format_bitfield_to_order_value(uint64_t bitfield)
+{
+	int format_index = 1;
+
+	if (!bitfield) {
+		return 0;
+	}
+
+	while (bitfield > 1) {
+		bitfield = bitfield >> 1;
+		format_index++;
+	}
+
+	return format_index;
 }
 
 /*! \brief Append codec to list */
 int ast_codec_pref_append(struct ast_codec_pref *pref, struct ast_format *format, unsigned int framing)
 {
 	uint64_t bitfield = ast_format_compatibility_format2bitfield(format);
-	int x;
-
-	ast_codec_pref_remove(pref, format);
+	int format_index = ast_codec_pref_format_bitfield_to_order_value(bitfield);
+	int x;
+
+	codec_pref_remove(pref, format_index);
 
 	for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
 		if (!pref->order[x]) {
-			pref->order[x] = bitfield;
+			pref->order[x] = format_index;
 			pref->framing[x] = framing;
 			break;
 		}




More information about the asterisk-commits mailing list