[asterisk-commits] dvossel: trunk r326855 - in /trunk: channels/ configs/ include/asterisk/ main...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Jul 7 14:39:25 CDT 2011


Author: dvossel
Date: Thu Jul  7 14:39:17 2011
New Revision: 326855

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=326855
Log:
Adds pass-through support for codec CELT.

This patch adds pass-through support for CELT.  CELT
formats are defined in codecs.conf and can be configured
to any sample rate a CELT endpoint supports.  This patch also
addresses a crash in channel.c resulting from a frame list being
freed incorrectly.  This crash was discovered while testing a CELT
translator which had to split encoded audio into multiple frames.
The codec translator is not a part of this patch, but may be
contributed in the future.

Review: https://reviewboard.asterisk.org/r/1294/

Modified:
    trunk/channels/chan_sip.c
    trunk/configs/codecs.conf.sample
    trunk/include/asterisk/format.h
    trunk/main/channel.c
    trunk/main/format.c
    trunk/main/frame.c
    trunk/main/rtp_engine.c
    trunk/res/res_rtp_asterisk.c

Modified: trunk/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_sip.c?view=diff&rev=326855&r1=326854&r2=326855
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Thu Jul  7 14:39:17 2011
@@ -9468,6 +9468,7 @@
 
 		if ((format = ast_rtp_codecs_get_payload_format(newaudiortp, codec))) {
 			unsigned int bit_rate;
+			int val = 0;
 
 			switch ((int) format->id) {
 			case AST_FORMAT_SIREN7:
@@ -9500,20 +9501,21 @@
 					}
 				}
 				break;
+			case AST_FORMAT_CELT:
+				if (sscanf(fmtp_string, "framesize=%30u", &val) == 1) {
+					ast_format_append(format, CELT_ATTR_KEY_FRAME_SIZE, val, AST_FORMAT_ATTR_END);
+				}
 			case AST_FORMAT_SILK:
-				{
-					int val = 0;
-					if (sscanf(fmtp_string, "maxaveragebitrate=%30u", &val) == 1) {
-						ast_format_append(format, SILK_ATTR_KEY_MAX_BITRATE, val, AST_FORMAT_ATTR_END);
-					}
-					if (sscanf(fmtp_string, "usedtx=%30u", &val) == 1) {
-						ast_format_append(format, SILK_ATTR_KEY_DTX, val ? 1 : 0, AST_FORMAT_ATTR_END);
-					}
-					if (sscanf(fmtp_string, "useinbandfec=%30u", &val) == 1) {
-						ast_format_append(format, SILK_ATTR_KEY_FEC, val ? 1 : 0, AST_FORMAT_ATTR_END);
-					}
-					break;
+				if (sscanf(fmtp_string, "maxaveragebitrate=%30u", &val) == 1) {
+					ast_format_append(format, SILK_ATTR_KEY_MAX_BITRATE, val, AST_FORMAT_ATTR_END);
 				}
+				if (sscanf(fmtp_string, "usedtx=%30u", &val) == 1) {
+					ast_format_append(format, SILK_ATTR_KEY_DTX, val ? 1 : 0, AST_FORMAT_ATTR_END);
+				}
+				if (sscanf(fmtp_string, "useinbandfec=%30u", &val) == 1) {
+					ast_format_append(format, SILK_ATTR_KEY_FEC, val ? 1 : 0, AST_FORMAT_ATTR_END);
+				}
+				break;
 			}
 		}
 	}
@@ -10829,7 +10831,7 @@
 {
 	int rtp_code;
 	struct ast_format_list fmt;
-
+	int val = 0;
 
 	if (debug)
 		ast_verbose("Adding codec %d (%s) to SDP\n", format->id, ast_getformatname(format));
@@ -10872,20 +10874,22 @@
 		/* Indicate that we only expect 64Kbps */
 		ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=64000\r\n", rtp_code);
 		break;
+	case AST_FORMAT_CELT:
+		if (!ast_format_get_value(format, CELT_ATTR_KEY_FRAME_SIZE, &val) && val > 0) {
+			ast_str_append(a_buf, 0, "a=fmtp:%d framesize=%u\r\n", rtp_code, val);
+		}
+		break;
 	case AST_FORMAT_SILK:
-		{
-			int val = 0;
-			if (!ast_format_get_value(format, SILK_ATTR_KEY_MAX_BITRATE, &val) && val > 5000 && val < 40000) {
-				ast_str_append(a_buf, 0, "a=fmtp:%d maxaveragebitrate=%u\r\n", rtp_code, val);
-			}
-			if (!ast_format_get_value(format, SILK_ATTR_KEY_DTX, &val)) {
-				ast_str_append(a_buf, 0, "a=fmtp:%d usedtx=%u\r\n", rtp_code, val ? 1 : 0);
-			}
-			if (!ast_format_get_value(format, SILK_ATTR_KEY_FEC, &val)) {
-				ast_str_append(a_buf, 0, "a=fmtp:%d useinbandfec=%u\r\n", rtp_code, val ? 1 : 0);
-			}
-			break;
-		}
+		if (!ast_format_get_value(format, SILK_ATTR_KEY_MAX_BITRATE, &val) && val > 5000 && val < 40000) {
+			ast_str_append(a_buf, 0, "a=fmtp:%d maxaveragebitrate=%u\r\n", rtp_code, val);
+		}
+		if (!ast_format_get_value(format, SILK_ATTR_KEY_DTX, &val)) {
+			ast_str_append(a_buf, 0, "a=fmtp:%d usedtx=%u\r\n", rtp_code, val ? 1 : 0);
+		}
+		if (!ast_format_get_value(format, SILK_ATTR_KEY_FEC, &val)) {
+			ast_str_append(a_buf, 0, "a=fmtp:%d useinbandfec=%u\r\n", rtp_code, val ? 1 : 0);
+		}
+		break;
 	}
 
 	if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size))

Modified: trunk/configs/codecs.conf.sample
URL: http://svnview.digium.com/svn/asterisk/trunk/configs/codecs.conf.sample?view=diff&rev=326855&r1=326854&r2=326855
==============================================================================
--- trunk/configs/codecs.conf.sample (original)
+++ trunk/configs/codecs.conf.sample Thu Jul  7 14:39:17 2011
@@ -126,7 +126,6 @@
 fec=true
 packetloss_percentage=10;
 
-
 [silk24]
 type=silk
 samprate=24000
@@ -134,3 +133,21 @@
 fec=true
 packetloss_percentage=10;
 
+
+; Default custom CELT codec definitions. Only one custom CELT definition is allowed
+; per a sample rate.
+;[celt44]
+;type=celt
+;samprate=44100  ; The samplerate in hz. This option is required.
+;framesize=480   ; The framesize option represents the duration of each frame in samples.
+                 ; This must be a factor of 2.  This option is only advertised in an SDP
+                 ; when it is set.  Otherwise a default of framesize of 480 is assumed
+                 ; internally
+
+;[celt48]
+;type=celt
+;samprate=48000
+
+;[celt32]
+;type=celt
+;samprate=32000

Modified: trunk/include/asterisk/format.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/format.h?view=diff&rev=326855&r1=326854&r2=326855
==============================================================================
--- trunk/include/asterisk/format.h (original)
+++ trunk/include/asterisk/format.h Thu Jul  7 14:39:17 2011
@@ -28,6 +28,7 @@
 
 #include "asterisk/astobj2.h"
 #include "asterisk/silk.h"
+#include "asterisk/celt.h"
 #define AST_FORMAT_ATTR_SIZE 128
 #define AST_FORMAT_INC 100000
 
@@ -99,6 +100,7 @@
 	/*! Raw 16-bit Signed Linear (192000 Hz) PCM.  maybe we're taking this too far. */
 	AST_FORMAT_SLINEAR192       = 27 + AST_FORMAT_TYPE_AUDIO,
 	AST_FORMAT_SPEEX32          = 28 + AST_FORMAT_TYPE_AUDIO,
+	AST_FORMAT_CELT             = 29 + AST_FORMAT_TYPE_AUDIO,
 
 	/*! H.261 Video */
 	AST_FORMAT_H261             = 1 + AST_FORMAT_TYPE_VIDEO,

Modified: trunk/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/channel.c?view=diff&rev=326855&r1=326854&r2=326855
==============================================================================
--- trunk/main/channel.c (original)
+++ trunk/main/channel.c Thu Jul  7 14:39:17 2011
@@ -1081,6 +1081,8 @@
 		AST_FORMAT_SPEEX,
 		/*! SILK is pretty awesome. */
 		AST_FORMAT_SILK,
+		/*! CELT supports crazy high sample rates */
+		AST_FORMAT_CELT,
 		/*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough
 		    to use it */
 		AST_FORMAT_LPC10,
@@ -5019,12 +5021,13 @@
 		   from the single frame we passed in; if so, feed each one of them to the
 		   channel, freeing each one after it has been written */
 		if ((f != fr) && AST_LIST_NEXT(f, frame_list)) {
-			struct ast_frame *cur, *next;
+			struct ast_frame *cur, *next = NULL;
 			unsigned int skip = 0;
 
-			for (cur = f, next = AST_LIST_NEXT(cur, frame_list);
-			     cur;
-			     cur = next, next = cur ? AST_LIST_NEXT(cur, frame_list) : NULL) {
+			cur = f;
+			while (cur) {
+				next = AST_LIST_NEXT(cur, frame_list);
+				AST_LIST_NEXT(cur, frame_list) = NULL;
 				if (!skip) {
 					if ((res = chan->tech->write(chan, cur)) < 0) {
 						chan->_softhangup |= AST_SOFTHANGUP_DEV;
@@ -5037,6 +5040,7 @@
 					}
 				}
 				ast_frfree(cur);
+				cur = next;
 			}
 
 			/* reset f so the code below doesn't attempt to free it */

Modified: trunk/main/format.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/format.c?view=diff&rev=326855&r1=326854&r2=326855
==============================================================================
--- trunk/main/format.c (original)
+++ trunk/main/format.c Thu Jul  7 14:39:17 2011
@@ -748,6 +748,15 @@
 		} else {
 			return 8000;
 		}
+	case AST_FORMAT_CELT:
+	{
+		int samplerate;
+		if (!(ast_format_get_value(format,
+			CELT_ATTR_KEY_SAMP_RATE,
+			&samplerate))) {
+			return samplerate;
+		}
+	}
 	default:
 		return 8000;
 	}
@@ -1085,6 +1094,32 @@
 	return -1;
 }
 
+static int custom_celt_format(struct ast_format_list *entry, unsigned int maxbitrate, unsigned int framesize)
+{
+	if (!entry->samplespersecond) {
+		ast_log(LOG_WARNING, "Custom CELT format definition '%s' requires sample rate to be defined.\n", entry->name);
+	}
+	ast_format_set(&entry->format, AST_FORMAT_CELT, 0);
+	if (!has_interface(&entry->format)) {
+		return -1;
+	}
+
+	snprintf(entry->desc, sizeof(entry->desc), "CELT Custom Format %dkhz", entry->samplespersecond/1000);
+
+	ast_format_append(&entry->format,
+		CELT_ATTR_KEY_SAMP_RATE, entry->samplespersecond,
+		CELT_ATTR_KEY_MAX_BITRATE, maxbitrate,
+		CELT_ATTR_KEY_FRAME_SIZE, framesize,
+		AST_FORMAT_ATTR_END);
+
+	entry->fr_len = 80;
+	entry->min_ms = 20;
+	entry->max_ms = 20;
+	entry->inc_ms = 20;
+	entry->def_ms = 20;
+	return 0;
+}
+
 static int custom_silk_format(struct ast_format_list *entry, unsigned int maxbitrate, int usedtx, int usefec, int packetloss_percentage)
 {
 	if (!entry->samplespersecond) {
@@ -1144,6 +1179,8 @@
 {
 	if (!strcasecmp(name, "silk")) {
 		*id = AST_FORMAT_SILK;
+	} else if (!strcasecmp(name, "celt")) {
+		*id = AST_FORMAT_CELT;
 	} else {
 		*id = 0;
 		return -1;
@@ -1163,8 +1200,14 @@
 		*result = 24000;
 	} else if (!strcasecmp(rate, "32000")) {
 		*result = 32000;
+	} else if (!strcasecmp(rate, "44100")) {
+		*result = 44100;
 	} else if (!strcasecmp(rate, "48000")) {
 		*result = 48000;
+	} else if (!strcasecmp(rate, "96000")) {
+		*result = 96000;
+	} else if (!strcasecmp(rate, "192000")) {
+		*result = 192000;
 	} else {
 		*result = 0;
 		return -1;
@@ -1184,6 +1227,7 @@
 	struct {
 		enum ast_format_id id;
 		unsigned int maxbitrate;
+		unsigned int framesize;
 		unsigned int packetloss_percentage;
 		int usefec;
 		int usedtx;
@@ -1221,6 +1265,11 @@
 					ast_log(LOG_WARNING, "maxbitrate '%s' at line %d of %s is not supported.\n",
 						var->value, var->lineno, FORMAT_CONFIG);
 				}
+			} else if (!strcasecmp(var->name, "framesize")) {
+				if (sscanf(var->value, "%30u", &settings.framesize) != 1) {
+					ast_log(LOG_WARNING, "framesize '%s' at line %d of %s is not supported.\n",
+						var->value, var->lineno, FORMAT_CONFIG);
+				}
 			} else if (!strcasecmp(var->name, "dtx")) {
 				settings.usedtx = ast_true(var->value) ? 1 : 0;
 			} else if (!strcasecmp(var->name, "fec")) {
@@ -1239,6 +1288,11 @@
 				add_it = 1;
 			}
 			break;
+		case AST_FORMAT_CELT:
+			if (!(custom_celt_format(&entry, settings.maxbitrate, settings.framesize))) {
+				add_it = 1;
+			}
+			break;
 		default:
 			ast_log(LOG_WARNING, "Can not create custom format %s\n", entry.name);
 		}

Modified: trunk/main/frame.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/frame.c?view=diff&rev=326855&r1=326854&r2=326855
==============================================================================
--- trunk/main/frame.c (original)
+++ trunk/main/frame.c Thu Jul  7 14:39:17 2011
@@ -1011,6 +1011,10 @@
 		} else {
 			return 160;
 		}
+	case AST_FORMAT_CELT:
+		/* TODO The assumes 20ms delivery right now, which is incorrect */
+		samples = ast_format_rate(&f->subclass.format) / 50;
+		break;
 	default:
 		ast_log(LOG_WARNING, "Unable to calculate samples for format %s\n", ast_getformatname(&f->subclass.format));
 	}

Modified: trunk/main/rtp_engine.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/rtp_engine.c?view=diff&rev=326855&r1=326854&r2=326855
==============================================================================
--- trunk/main/rtp_engine.c (original)
+++ trunk/main/rtp_engine.c Thu Jul  7 14:39:17 2011
@@ -1931,6 +1931,10 @@
 		set_next_mime_type(format, 0, "audio", "SILK", ast_format_rate(format));
 		add_static_payload(-1, format, 0);
 		break;
+	case AST_FORMAT_CELT:
+		set_next_mime_type(format, 0, "audio", "CELT", ast_format_rate(format));
+		add_static_payload(-1, format, 0);
+		break;
 	default:
 		break;
 	}

Modified: trunk/res/res_rtp_asterisk.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_rtp_asterisk.c?view=diff&rev=326855&r1=326854&r2=326855
==============================================================================
--- trunk/res/res_rtp_asterisk.c (original)
+++ trunk/res/res_rtp_asterisk.c Thu Jul  7 14:39:17 2011
@@ -1254,6 +1254,7 @@
 		case AST_FORMAT_SPEEX16:
 		case AST_FORMAT_SPEEX32:
 		case AST_FORMAT_SILK:
+		case AST_FORMAT_CELT:
 		case AST_FORMAT_G723_1:
 		case AST_FORMAT_SIREN7:
 		case AST_FORMAT_SIREN14:




More information about the asterisk-commits mailing list