[svn-commits] kpfleming: trunk r46203 - in /trunk: ./ channels/ include/asterisk/ main/

svn-commits at lists.digium.com svn-commits at lists.digium.com
Wed Oct 25 07:55:11 MST 2006


Author: kpfleming
Date: Wed Oct 25 09:55:11 2006
New Revision: 46203

URL: http://svn.digium.com/view/asterisk?rev=46203&view=rev
Log:
Merged revisions 46082-46083,46152-46153 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r46082 | kpfleming | 2006-10-23 22:45:42 -0500 (Mon, 23 Oct 2006) | 2 lines

add an API call to allow channel drivers to determine which media formats are compatible (passthrough or transcode) with the format an existing channel is already using

........
r46083 | kpfleming | 2006-10-23 22:53:32 -0500 (Mon, 23 Oct 2006) | 2 lines

ensure that the translation matrix is properly lock-protected every place it is used

........
r46152 | kpfleming | 2006-10-24 18:45:19 -0500 (Tue, 24 Oct 2006) | 2 lines

if multiple translators are registered for the same source/dest combination, ensure that the lowest-cost one is always inserted earlier in the list

........
r46153 | kpfleming | 2006-10-24 19:10:54 -0500 (Tue, 24 Oct 2006) | 2 lines

code zone experiment: don't offer formats in the outbound INVITE that aren't either passthrough or translatable

........

Modified:
    trunk/   (props changed)
    trunk/channels/chan_sip.c
    trunk/include/asterisk/translate.h
    trunk/main/translate.c

Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Modified: trunk/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_sip.c?rev=46203&r1=46202&r2=46203&view=diff
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Wed Oct 25 09:55:11 2006
@@ -142,6 +142,7 @@
 #include "asterisk/abstract_jb.h"
 #include "asterisk/compiler.h"
 #include "asterisk/threadstorage.h"
+#include "asterisk/translate.h"
 
 #ifndef FALSE
 #define FALSE    0
@@ -927,7 +928,7 @@
 	unsigned int sipoptions;		/*!< Supported SIP options on the other end */
 	struct ast_codec_pref prefs;		/*!< codec prefs */
 	int capability;				/*!< Special capability (codec) */
-	int jointcapability;			/*!< Supported capability at both ends (codecs ) */
+	int jointcapability;			/*!< Supported capability at both ends (codecs) */
 	int peercapability;			/*!< Supported peer capability */
 	int prefcodec;				/*!< Preferred codec (outbound only) */
 	int noncodeccapability;			/*!< DTMF RFC2833 telephony-event */
@@ -6091,15 +6092,13 @@
 	if (p->redirip.sin_addr.s_addr) {
 		dest.sin_port = p->redirip.sin_port;
 		dest.sin_addr = p->redirip.sin_addr;
-		if (p->redircodecs)
-			capability = p->redircodecs;
 	} else {
 		dest.sin_addr = p->ourip;
 		dest.sin_port = sin.sin_port;
 	}
 
 	/* Ok, let's start working with codec selection here */
-	capability = p->jointcapability;
+	capability = ast_translate_available_formats(p->jointcapability, p->prefcodec);
 
 	if (option_debug > 1) {
 		char codecbuf[BUFSIZ];
@@ -6107,26 +6106,25 @@
 		ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec));
 	}
 	
-	if ((ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP))) {
+	if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) {
 		ast_build_string(&m_audio_next, &m_audio_left, " %d", 191);
 		ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000);
 	}
 
 	/* Check if we need video in this call */
-	if((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) {
+	if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) {
 		if (p->vrtp) {
 			needvideo = TRUE;
 			if (option_debug > 1)
-				ast_log(LOG_DEBUG, "This call needs video offers! \n");
+				ast_log(LOG_DEBUG, "This call needs video offers!\n");
 		} else if (option_debug > 1)
-			ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled ! \n");
+			ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n");
 	}
 		
 
 	/* Ok, we need video. Let's add what we need for video and set codecs.
 	   Video is handled differently than audio since we can not transcode. */
 	if (needvideo) {
-
 		/* Determine video destination */
 		if (p->vredirip.sin_addr.s_addr) {
 			vdest.sin_addr = p->vredirip.sin_addr;
@@ -6142,31 +6140,8 @@
 			snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate);
 		if (debug) 
 			ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port));	
-
-		/* For video, we can't negotiate video offers. Let's compare the incoming call with what we got. */
-		if (p->prefcodec) {
-			int videocapability = (capability & p->prefcodec) & AST_FORMAT_VIDEO_MASK; /* Outbound call */
-		
-			/*! \todo XXX We need to select one codec, not many, since there's no transcoding */
-
-			/* Now, merge this video capability into capability while removing unsupported codecs */
-			if (!videocapability) {
-				needvideo = FALSE;
-				if (option_debug > 2)
-					ast_log(LOG_DEBUG, "** No compatible video codecs... Disabling video.\n");
-			} 
-
-			/* Replace video capabilities with the new videocapability */
-			capability = (capability & AST_FORMAT_AUDIO_MASK) | videocapability;
-
-			if (option_debug > 4) {
-				char codecbuf[BUFSIZ];
-				if (videocapability)
-					ast_log(LOG_DEBUG, "** Our video codec selection is: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), videocapability));
-				ast_log(LOG_DEBUG, "** Capability now set to : %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability));
-			}
-		}
-	}
+	}
+
 	if (debug) 
 		ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port));	
 

Modified: trunk/include/asterisk/translate.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/translate.h?rev=46203&r1=46202&r2=46203&view=diff
==============================================================================
--- trunk/include/asterisk/translate.h (original)
+++ trunk/include/asterisk/translate.h Wed Oct 25 09:55:11 2006
@@ -205,11 +205,25 @@
 
 /*!
  * \brief Returns the number of steps required to convert from 'src' to 'dest'.
- * \param dest Destination format
- * \param src Source format
+ * \param dest destination format
+ * \param src source format
  * \return the number of translation steps required, or -1 if no path is available
  */
 unsigned int ast_translate_path_steps(unsigned int dest, unsigned int src);
+
+/*!
+ * \brief Mask off unavailable formats from a format bitmask
+ * \param dest possible destination formats
+ * \param src source formats
+ * \return the destination formats that are available in the source or translatable
+ *
+ * The result will include all formats from 'dest' that are either present
+ * in 'src' or translatable from a format present in 'src'.
+ *
+ * Note that only a single audio format and a single video format can be
+ * present in 'src', or the function will produce unexpected results.
+ */
+unsigned int ast_translate_available_formats(unsigned int dest, unsigned int src);
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }

Modified: trunk/main/translate.c
URL: http://svn.digium.com/view/asterisk/trunk/main/translate.c?rev=46203&r1=46202&r2=46203&view=diff
==============================================================================
--- trunk/main/translate.c (original)
+++ trunk/main/translate.c Wed Oct 25 09:55:11 2006
@@ -63,6 +63,9 @@
  * until step->dstfmt == desired_format.
  *
  * Array indexes are 'src' and 'dest', in that order.
+ *
+ * Note: the lock in the 'translators' list is also used to protect
+ * this structure.
  */
 static struct translator_path tr_matrix[MAX_FORMAT][MAX_FORMAT];
 
@@ -253,18 +256,22 @@
 	source = powerof(source);
 	dest = powerof(dest);
 	
+	AST_LIST_LOCK(&translators);
+
 	while (source != dest) {
 		struct ast_trans_pvt *cur;
 		struct ast_translator *t = tr_matrix[source][dest].step;
 		if (!t) {
 			ast_log(LOG_WARNING, "No translator path from %s to %s\n", 
 				ast_getformatname(source), ast_getformatname(dest));
+			AST_LIST_UNLOCK(&translators);
 			return NULL;
 		}
 		if (!(cur = newpvt(t))) {
 			ast_log(LOG_WARNING, "Failed to build translator step from %d to %d\n", source, dest);
 			if (head)
 				ast_translator_free_path(head);	
+			AST_LIST_UNLOCK(&translators);
 			return NULL;
 		}
 		if (!head)
@@ -276,6 +283,8 @@
 		/* Keep going if this isn't the final destination */
 		source = cur->t->dstfmt;
 	}
+
+	AST_LIST_UNLOCK(&translators);
 	return head;
 }
 
@@ -560,6 +569,7 @@
 int __ast_register_translator(struct ast_translator *t, struct ast_module *mod)
 {
 	static int added_cli = 0;
+	struct ast_translator *u;
 
 	if (!mod) {
 		ast_log(LOG_WARNING, "Missing module pointer, you need to supply one\n");
@@ -617,7 +627,24 @@
 		ast_cli_register_multiple(cli_translate, sizeof(cli_translate) / sizeof(struct ast_cli_entry));
 		added_cli++;
 	}
-	AST_LIST_INSERT_HEAD(&translators, t, list);
+
+	/* find any existing translators that provide this same srcfmt/dstfmt,
+	   and put this one in order based on cost */
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&translators, u, list) {
+		if ((u->srcfmt == t->srcfmt) &&
+		    (u->dstfmt == t->dstfmt) &&
+		    (u->cost > t->cost)) {
+			AST_LIST_INSERT_BEFORE_CURRENT(&translators, t, list);
+			t = NULL;
+		}
+	}
+	AST_LIST_TRAVERSE_SAFE_END;
+
+	/* if no existing translator was found for this format combination,
+	   add it to the beginning of the list */
+	if (t)
+		AST_LIST_INSERT_HEAD(&translators, t, list);
+
 	rebuild_matrix(0);
 	AST_LIST_UNLOCK(&translators);
 	return 0;
@@ -637,7 +664,7 @@
 			break;
 		}
 	}
-	AST_LIST_TRAVERSE_SAFE_END
+	AST_LIST_TRAVERSE_SAFE_END;
 	rebuild_matrix(0);
 	AST_LIST_UNLOCK(&translators);
 	return (u ? 0 : -1);
@@ -693,12 +720,70 @@
 
 unsigned int ast_translate_path_steps(unsigned int dest, unsigned int src)
 {
+	unsigned int res = -1;
+
 	/* convert bitwise format numbers into array indices */
 	src = powerof(src);
 	dest = powerof(dest);
-	if (!tr_matrix[src][dest].step)
-		return -1;
-	else
-		return tr_matrix[src][dest].multistep + 1;
-}
-
+
+	AST_LIST_LOCK(&translators);
+
+	if (tr_matrix[src][dest].step)
+		res = tr_matrix[src][dest].multistep + 1;
+
+	AST_LIST_UNLOCK(&translators);
+
+	return res;
+}
+
+unsigned int ast_translate_available_formats(unsigned int dest, unsigned int src)
+{
+	unsigned int res = dest;
+	unsigned int x;
+	unsigned int src_audio = powerof(src & AST_FORMAT_AUDIO_MASK);
+	unsigned int src_video = powerof(src & AST_FORMAT_VIDEO_MASK);
+
+	/* if we don't have a source format, we just have to try all
+	   possible destination formats */
+	if (!src)
+		return dest;
+
+	AST_LIST_LOCK(&translators);
+
+	for (x = 1; x < AST_FORMAT_MAX_AUDIO; x <<= 1) {
+		/* if this is not a desired format, nothing to do */
+		if (!dest & x)
+			continue;
+
+		/* if the source is supplying this format, then
+		   we can leave it in the result */
+		if (src & x)
+			continue;
+
+		/* if we don't have a translation path from the src
+		   to this format, remove it from the result */
+		if (!tr_matrix[src_audio][powerof(x)].step)
+			res &= ~x;
+	}
+
+	/* roll over into video formats */
+	for (; x < AST_FORMAT_MAX_VIDEO; x <<= 1) {
+		/* if this is not a desired format, nothing to do */
+		if (!dest & x)
+			continue;
+
+		/* if the source is supplying this format, then
+		   we can leave it in the result */
+		if (src & x)
+			continue;
+
+		/* if we don't have a translation path from the src
+		   to this format, remove it from the result */
+		if (!tr_matrix[src_video][powerof(x)].step)
+			res &= ~x;
+	}
+
+	AST_LIST_UNLOCK(&translators);
+
+	return res;
+}



More information about the svn-commits mailing list