[asterisk-commits] file: trunk r187360 - in /trunk: channels/ include/asterisk/ main/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Apr 9 11:19:39 CDT 2009


Author: file
Date: Thu Apr  9 11:19:35 2009
New Revision: 187360

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=187360
Log:
Add support for allowing the channel driver to handle transcoding.

This was accomplished using a set of options and the setoption channel callback.
The core calls into the channel driver using these options and the channel driver
either returns success or failure.

Modified:
    trunk/channels/chan_sip.c
    trunk/include/asterisk/frame.h
    trunk/main/channel.c

Modified: trunk/channels/chan_sip.c
URL: http://svn.digium.com/svn-view/asterisk/trunk/channels/chan_sip.c?view=diff&rev=187360&r1=187359&r2=187360
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Thu Apr  9 11:19:35 2009
@@ -2272,6 +2272,7 @@
 static int sip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
 static int sip_senddigit_begin(struct ast_channel *ast, char digit);
 static int sip_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration);
+static int sip_setoption(struct ast_channel *chan, int option, void *data, int datalen);
 static int sip_queryoption(struct ast_channel *chan, int option, void *data, int *datalen);
 static const char *sip_get_callid(struct ast_channel *chan);
 
@@ -2680,6 +2681,7 @@
 	.early_bridge = ast_rtp_instance_early_bridge,
 	.send_text = sip_sendtext,		/* called with chan locked */
 	.func_channel_read = acf_channel_read,
+	.setoption = sip_setoption,
 	.queryoption = sip_queryoption,
 	.get_pvt_uniqueid = sip_get_callid,
 };
@@ -3921,6 +3923,26 @@
 		ast_free(req->data);
 		req->data = NULL;
 	}
+	return res;
+}
+
+/*! \brief Set an option on a SIP dialog */
+static int sip_setoption(struct ast_channel *chan, int option, void *data, int datalen)
+{
+	int res = -1;
+	struct sip_pvt *p = chan->tech_pvt;
+
+	if (option == AST_OPTION_FORMAT_READ) {
+		int format = *(int *)data;
+		res = ast_rtp_instance_set_read_format(p->rtp, format);
+	} else if (option == AST_OPTION_FORMAT_WRITE) {
+		int format = *(int *)data;
+		res = ast_rtp_instance_set_write_format(p->rtp, format);
+	} else if (option == AST_OPTION_MAKE_COMPATIBLE) {
+		struct ast_channel *peer = data;
+		res = ast_rtp_instance_make_compatible(chan, p->rtp, peer);
+	}
+
 	return res;
 }
 

Modified: trunk/include/asterisk/frame.h
URL: http://svn.digium.com/svn-view/asterisk/trunk/include/asterisk/frame.h?view=diff&rev=187360&r1=187359&r2=187360
==============================================================================
--- trunk/include/asterisk/frame.h (original)
+++ trunk/include/asterisk/frame.h Thu Apr  9 11:19:35 2009
@@ -391,6 +391,15 @@
  */
 #define AST_OPTION_T38_STATE		10
 
+/*! Request that the channel driver deliver frames in a specific format */
+#define AST_OPTION_FORMAT_READ          11
+
+/*! Request that the channel driver be prepared to accept frames in a specific format */
+#define AST_OPTION_FORMAT_WRITE         12
+
+/*! Request that the channel driver make two channels of the same tech type compatible if possible */
+#define AST_OPTION_MAKE_COMPATIBLE      13
+
 struct oprmode {
 	struct ast_channel *peer;
 	int mode;

Modified: trunk/main/channel.c
URL: http://svn.digium.com/svn-view/asterisk/trunk/main/channel.c?view=diff&rev=187360&r1=187359&r2=187360
==============================================================================
--- trunk/main/channel.c (original)
+++ trunk/main/channel.c Thu Apr  9 11:19:35 2009
@@ -3769,7 +3769,7 @@
 static int set_format(struct ast_channel *chan, int fmt, int *rawformat, int *format,
 		      struct ast_trans_pvt **trans, const int direction)
 {
-	int native;
+	int native, native_fmt = ast_best_codec(fmt);
 	int res;
 	char from[200], to[200];
 	
@@ -3780,7 +3780,19 @@
 
 	if (!fmt || !native)	/* No audio requested */
 		return 0;	/* Let's try a call without any sounds (video, text) */
-	
+
+	/* See if the underlying channel driver is capable of performing transcoding for us */
+	if (!ast_channel_setoption(chan, direction ? AST_OPTION_FORMAT_WRITE : AST_OPTION_FORMAT_READ, &native_fmt, sizeof(int*), 0)) {
+		ast_debug(1, "Channel driver natively set channel %s to %s format %s (%d)\n", chan->name,
+			  direction ? "write" : "read", ast_getformatname(native_fmt), native_fmt);
+		chan->nativeformats = *rawformat = *format = native_fmt;
+		if (*trans) {
+			ast_translator_free_path(*trans);
+		}
+		*trans = NULL;
+		return 0;
+	}
+
 	/* Find a translation path from the native format to one of the desired formats */
 	if (!direction)
 		/* reading */
@@ -4201,6 +4213,12 @@
 {
 	int src;
 	int dst;
+
+	/* See if the channel driver can natively make these two channels compatible */
+	if (from->tech->bridge && from->tech->bridge == to->tech->bridge &&
+	    !ast_channel_setoption(from, AST_OPTION_MAKE_COMPATIBLE, to, sizeof(struct ast_channel *), 0)) {
+		return 0;
+	}
 
 	if (from->readformat == to->writeformat && from->writeformat == to->readformat) {
 		/* Already compatible!  Moving on ... */




More information about the asterisk-commits mailing list