[Freeswitch-svn] [commit] r2483 - in freeswitch/trunk/src: include mod/codecs/mod_g726 mod/endpoints/mod_sofia

Freeswitch SVN anthm at freeswitch.org
Sat Sep 2 19:04:26 EDT 2006


Author: anthm
Date: Sat Sep  2 19:04:25 2006
New Revision: 2483

Added:
   freeswitch/trunk/src/include/switch_bitpack.h
Modified:
   freeswitch/trunk/src/include/switch_types.h
   freeswitch/trunk/src/mod/codecs/mod_g726/Makefile
   freeswitch/trunk/src/mod/codecs/mod_g726/mod_g726.c
   freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c

Log:
pack this mutha %^%$^&

Added: freeswitch/trunk/src/include/switch_bitpack.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/include/switch_bitpack.h	Sat Sep  2 19:04:25 2006
@@ -0,0 +1,272 @@
+/* 
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2005/2006, Anthony Minessale II <anthmct at yahoo.com>
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ *
+ * The Initial Developer of the Original Code is
+ * Anthony Minessale II <anthmct at yahoo.com>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 
+ * Anthony Minessale II <anthmct at yahoo.com>
+ *
+ *
+ * switch_utils.h -- Compatability and Helper Code
+ *
+ */
+/*! \file switch_bitpack.h
+    \brief BITPACKING code for RFC3551 and AAL2 packing
+
+*/
+#ifndef SWITCH_BITPACK_H
+#define SWITCH_BITPACK_H
+BEGIN_EXTERN_C
+
+#include <switch.h>
+
+#ifdef DEBUG_BITS
+static char bb[80] = "";
+static inline char *print_bits(switch_byte_t byte, char *x)
+{
+
+    int i,j = 0;
+    x[j++] = '[';
+    for (i=7;i>=0;i--) {
+        x[j++] = (byte & (1 << i)) ? '1' : '0';
+    }
+    x[j++] = ']';
+    x[j++] = '\0';
+    return x;
+}
+#endif
+
+
+
+/*!
+  \defgroup bp1 Bitpacking 
+  \ingroup core1
+  \{ 
+*/
+
+static const int8_t SWITCH_BITPACKED_MASKS[] = {0, 1, 3, 7, 15, 31, 63, 127, 255};
+static const int8_t SWITCH_REVERSE_BITPACKED_MASKS[] = {255, 254, 252, 248, 240, 224, 192, 128};
+
+/*!
+  \brief Initialize a bitpack object
+  \param pack the pack object
+  \param bitlen the number of bits per packet
+  \param buf the buffer to use for storage
+  \param buflen the length of the storage buffer
+  \param mode RFC3551 or AAL2 mode (curse you backwards folks) 
+*/
+static inline void switch_bitpack_init(switch_bitpack_t *pack, int32_t bitlen, switch_byte_t *buf, uint32_t buflen, switch_bitpack_mode_t mode)
+{
+	memset(pack, 0, sizeof(*pack));
+	memset(buf, 0, buflen);
+	pack->frame_bits = bitlen;
+	pack->buf = buf;
+	pack->buflen = buflen;
+	pack->cur = pack->buf;
+	pack->mode = mode;
+}
+
+static inline void pack_check_over(switch_bitpack_t *pack)
+{
+	switch_byte_t this = pack->this;	
+
+	if (pack->over) {
+		pack->bits_cur = pack->over;
+
+		if (pack->mode == SWITCH_BITPACK_MODE_RFC3551) {
+			this &= SWITCH_BITPACKED_MASKS[pack->over];
+			this <<= pack->under;
+			*pack->cur |= this;
+			pack->cur++;
+		} else {
+			switch_byte_t mask = SWITCH_BITS_PER_BYTE - pack->over;
+			this &= SWITCH_REVERSE_BITPACKED_MASKS[mask];
+			this >>= mask;
+
+			*pack->cur <<= pack->over;
+			*pack->cur |= this;
+			pack->cur++;
+		}
+
+
+		pack->bytes++;
+		pack->over = pack->under = 0;
+	}	
+}
+
+/*!
+  \brief finalize a bitpack object
+  \param pack the pack/unpack object
+*/
+static inline int8_t switch_bitpack_done(switch_bitpack_t *pack)
+{
+
+	if (pack->bits_cur && pack->bits_cur < SWITCH_BITS_PER_BYTE) {
+		pack->bytes++;
+		if (pack->mode == SWITCH_BITPACK_MODE_AAL2) {
+            *pack->cur <<= SWITCH_BITS_PER_BYTE - pack->bits_cur;
+        }
+	}
+
+	if (pack->over) {
+		pack_check_over(pack);
+	}
+	return 0;
+}
+
+
+/*!
+  \brief pull data out of a bitpack object into it's buffer
+  \param unpack the pack/unpack object
+  \param in a 1 byte int packed with bits
+  \return -1 if the buffer is full otherwise 0
+*/
+static inline int8_t switch_bitpack_out(switch_bitpack_t *unpack, switch_byte_t in)
+{
+	switch_byte_t this;
+
+	if (unpack->cur - unpack->buf > unpack->buflen) {
+		return -1;
+	}
+
+	unpack->bits_cur = 0;
+	unpack->this = this = in;
+
+
+
+	pack_check_over(unpack);
+	while(unpack->bits_cur <= SWITCH_BITS_PER_BYTE) {
+		switch_byte_t next = unpack->bits_cur + unpack->frame_bits;
+		switch_byte_t under_in;
+		switch_byte_t mask;
+		this = unpack->this;
+
+		if (next > SWITCH_BITS_PER_BYTE) {
+			unpack->over = next - SWITCH_BITS_PER_BYTE;
+			unpack->under = unpack->frame_bits - unpack->over;
+
+			if (unpack->mode == SWITCH_BITPACK_MODE_RFC3551) {
+				mask = SWITCH_BITS_PER_BYTE - unpack->under;
+
+				under_in = this & SWITCH_REVERSE_BITPACKED_MASKS[mask];
+				under_in >>= mask;
+				*unpack->cur |= under_in;
+			} else {
+				mask = unpack->under;
+				under_in = this & SWITCH_BITPACKED_MASKS[mask];
+				*unpack->cur <<= mask;
+				*unpack->cur |= under_in;
+			}
+
+			break;
+		}
+
+		if (unpack->mode == SWITCH_BITPACK_MODE_RFC3551) {
+			this >>= unpack->bits_cur;
+			this &= SWITCH_BITPACKED_MASKS[unpack->frame_bits];
+			*unpack->cur |= this;
+			unpack->cur++;
+		} else {
+			this >>= (SWITCH_BITS_PER_BYTE - next);
+			this &= SWITCH_BITPACKED_MASKS[unpack->frame_bits];
+
+			*unpack->cur |= this;
+			unpack->cur++;
+		}
+
+		unpack->bits_cur = next;
+		unpack->bytes++;
+
+
+	}
+
+
+	return 0;
+}
+
+
+/*!
+  \brief pack data into a bitpack object's buffer
+  \param pack the pack/unpack object
+  \param in a 1 byte int with 1 packet worth of bits
+  \return -1 if the buffer is full otherwise 0
+*/
+static inline int8_t switch_bitpack_in(switch_bitpack_t *pack, switch_byte_t in)
+{
+	int next = pack->bits_cur + pack->frame_bits;
+
+	if (pack->cur - pack->buf > pack->buflen) {
+		return -1;
+	} 
+
+	pack->bits_tot += pack->frame_bits;
+
+	if (next > SWITCH_BITS_PER_BYTE) {
+		int a = 0, b = 0, rem, nxt;
+		rem = SWITCH_BITS_PER_BYTE - pack->bits_cur;
+		nxt = pack->frame_bits - rem ;
+		if (pack->mode == SWITCH_BITPACK_MODE_RFC3551) {
+			a = in & SWITCH_BITPACKED_MASKS[rem];
+			b = in >> rem;
+			a <<= pack->shiftby;
+			*pack->cur |= a;
+			pack->cur++;
+			*pack->cur |= b;
+			pack->bits_cur = pack->shiftby = nxt;
+		} else {
+			a = in >> nxt;
+			b = in & SWITCH_BITPACKED_MASKS[nxt];
+			*pack->cur <<= rem;
+			*pack->cur |= a;
+			pack->cur++;
+			*pack->cur |= b;
+			pack->bits_cur = nxt;
+			
+		}
+		pack->bytes++;
+
+	} else {
+
+		if (pack->mode == SWITCH_BITPACK_MODE_RFC3551) {
+			in <<= pack->shiftby;
+			*pack->cur |= in;
+			pack->shiftby += pack->frame_bits;
+		} else {
+			*pack->cur <<= pack->frame_bits;
+			*pack->cur |= in;
+		}
+
+		if (next == SWITCH_BITS_PER_BYTE) {
+			pack->cur++;			
+			pack->bytes++;
+			pack->bits_cur = pack->shiftby = 0;
+		} else {
+			pack->bits_cur = next;
+		}
+	}
+
+	return 0;
+}
+///\}
+
+END_EXTERN_C
+#endif

Modified: freeswitch/trunk/src/include/switch_types.h
==============================================================================
--- freeswitch/trunk/src/include/switch_types.h	(original)
+++ freeswitch/trunk/src/include/switch_types.h	Sat Sep  2 19:04:25 2006
@@ -72,6 +72,32 @@
 #define SWITCH_HTDOCS_DIR SWITCH_PREFIX_DIR SWITCH_PATH_SEPARATOR "htdocs"
 #endif
 
+#define SWITCH_BITS_PER_BYTE 8
+typedef uint8_t switch_byte_t;
+
+typedef enum {
+	SWITCH_BITPACK_MODE_RFC3551,
+	SWITCH_BITPACK_MODE_AAL2
+} switch_bitpack_mode_t;
+
+
+typedef struct {
+	switch_byte_t *buf;
+	uint32_t buflen;
+	switch_byte_t *cur;
+	uint32_t bytes;
+	uint32_t bits_tot;
+	switch_byte_t bits_cur;
+	switch_byte_t bits_rem;
+	switch_byte_t frame_bits;
+	switch_byte_t shiftby;
+	switch_byte_t this;
+	switch_byte_t under;
+	switch_byte_t over;
+	switch_bitpack_mode_t mode;
+} switch_bitpack_t;
+
+
 struct switch_directories {
 	char *base_dir;
 	char *mod_dir;
@@ -417,6 +443,7 @@
 SWITCH_CODEC_FLAG_SILENCE_STOP =	(1 <<  3) - End period of silence
 SWITCH_CODEC_FLAG_SILENCE =			(1 <<  4) - Silence
 SWITCH_CODEC_FLAG_FREE_POOL =		(1 <<  5) - Free codec's pool on destruction
+SWITCH_CODEC_FLAG_AAL2 =			(1 <<  6) - USE AAL2 Bitpacking
 </pre>
 */
 typedef enum {
@@ -426,7 +453,7 @@
 	SWITCH_CODEC_FLAG_SILENCE_STOP =	(1 <<  3),
 	SWITCH_CODEC_FLAG_SILENCE =			(1 <<  4),
 	SWITCH_CODEC_FLAG_FREE_POOL =		(1 <<  5),
-
+	SWITCH_CODEC_FLAG_AAL2 =			(1 <<  6)
 } switch_codec_flag_t;
 
 

Modified: freeswitch/trunk/src/mod/codecs/mod_g726/Makefile
==============================================================================
--- freeswitch/trunk/src/mod/codecs/mod_g726/Makefile	(original)
+++ freeswitch/trunk/src/mod/codecs/mod_g726/Makefile	Sat Sep  2 19:04:25 2006
@@ -5,7 +5,7 @@
 depends:
 	MAKE=$(MAKE) $(BASE)/build/buildlib.sh $(BASE) install codec/g726 --prefix=$(PREFIX)
 
-$(MODNAME).$(DYNAMIC_LIB_EXTEN): $(MODNAME).c
+$(MODNAME).$(DYNAMIC_LIB_EXTEN): $(MODNAME).c ../../../include/switch_bitpack.h
 	$(CC) $(CFLAGS) -fPIC -c $(MODNAME).c -o $(MODNAME).o
 	$(CC) $(SOLINK) $(MODNAME).o -o $(MODNAME).$(DYNAMIC_LIB_EXTEN) $(LDFLAGS)
 

Modified: freeswitch/trunk/src/mod/codecs/mod_g726/mod_g726.c
==============================================================================
--- freeswitch/trunk/src/mod/codecs/mod_g726/mod_g726.c	(original)
+++ freeswitch/trunk/src/mod/codecs/mod_g726/mod_g726.c	Sat Sep  2 19:04:25 2006
@@ -31,29 +31,31 @@
  */  
 #include "switch.h"
 #include "g72x.h"
-#define BITS_IN_A_BYTE 8
+#include "switch_bitpack.h"
 
 static const char modname[] = "mod_g726";
 
+typedef int (*encoder_t)(int, int, g726_state *);
+typedef int (*decoder_t)(int, int, g726_state *);
 
+
 typedef struct {
 	g726_state context;
-	uint8_t buf[5];
-	uint8_t *ptr;
 	uint8_t bits_per_frame;
-	uint8_t bits;
-	uint8_t bbits;
-	uint8_t ecount;
-	uint8_t d_bits;
-	uint8_t d_bbits;
-	uint8_t dcount;
-	uint8_t save;
+	encoder_t encoder;
+	decoder_t decoder;
+	switch_bitpack_t pack;
+	switch_bitpack_t unpack;
+	switch_bitpack_mode_t mode;
+	switch_byte_t loops;
+	switch_byte_t bytes;
+	switch_byte_t buf[160];
 } g726_handle_t;
 
 static switch_status_t switch_g726_init(switch_codec_t *codec, switch_codec_flag_t flags,
 									  const switch_codec_settings_t *codec_settings) 
 {
-	int encoding, decoding;
+	switch_byte_t encoding, decoding;
 	g726_handle_t *handle;
 
 	encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
@@ -62,10 +64,40 @@
 	if (!(encoding || decoding) || (!(handle = switch_core_alloc(codec->memory_pool, sizeof(*handle))))) {
 		return SWITCH_STATUS_FALSE;
 	} else {
+		handle->bytes = codec->implementation->encoded_bytes_per_frame;
+		
+		switch(handle->bytes) {
+		case 100:
+			handle->encoder = g726_40_encoder;
+			handle->decoder = g726_40_decoder;
+			handle->loops = 160;
+			break;
+		case 80:
+			handle->encoder = g726_32_encoder;
+			handle->decoder = g726_32_decoder;
+			handle->loops = 40;
+			break;
+		case 60:
+			handle->encoder = g726_24_encoder;
+			handle->decoder = g726_24_decoder;
+			handle->loops = 160;
+			break;
+		case 40:
+			handle->encoder = g726_16_encoder;
+			handle->decoder = g726_16_decoder;
+			handle->loops = 160;
+			break;
+		default:
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "invalid Encoding Size %d!\n", codec->implementation->encoded_bytes_per_frame);
+			return SWITCH_STATUS_FALSE;
+			break;
+		}
+
 		g726_init_state(&handle->context);
 		codec->private_info = handle;
-		handle->bits_per_frame = (uint8_t)(codec->implementation->bits_per_second / (codec->implementation->samples_per_second));
-		handle->ptr = handle->buf;
+		handle->bits_per_frame = codec->implementation->bits_per_second / (codec->implementation->samples_per_second);
+		handle->mode = (flags & SWITCH_CODEC_FLAG_AAL2 || strstr(codec->implementation->iananame, "AAL2")) 
+			? SWITCH_BITPACK_MODE_AAL2 : SWITCH_BITPACK_MODE_RFC3551;
 		return SWITCH_STATUS_SUCCESS;
 	}
 }
@@ -77,29 +109,8 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-typedef int (*encoder_t)(int, int, g726_state *);
-typedef int (*decoder_t)(int, int, g726_state *);
 
 
-static void print_bits(uint8_t byte)
-{
-	int i;
-
-	for (i=7;i>=0;i--) {
-		//for (i=0;i<=7;i++) {
-		if(byte & (1 << i)) {
-			printf("1");
-		} else {
-			printf("0");
-		}
-	}
-}
-
-
-
-
-
-
 static switch_status_t switch_g726_encode(switch_codec_t *codec, 
 										switch_codec_t *other_codec, 
 										void *decoded_data,
@@ -116,28 +127,8 @@
 	g726_handle_t *handle = codec->private_info;
 	g726_state *context = &handle->context;
 	uint32_t len = codec->implementation->bytes_per_frame;
-	uint32_t elen = codec->implementation->encoded_bytes_per_frame;
-	encoder_t encoder;
+	//uint32_t elen = codec->implementation->encoded_bytes_per_frame;
 
-	switch(elen) {
-	case 100:
-		encoder = g726_40_encoder;
-		break;
-	case 80:
-		encoder = g726_32_encoder;
-		break;
-	case 60:
-		encoder = g726_24_encoder;
-		break;
-	case 40:
-		encoder = g726_16_encoder;
-		break;
-	default:
-		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "invalid Encoding Size %d!\n", elen);
-		return SWITCH_STATUS_FALSE;
-		break;
-	}
-
 	if (!context) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error!\n");
 		return SWITCH_STATUS_FALSE;
@@ -147,72 +138,18 @@
 		uint32_t new_len = 0;
 		int16_t *ddp = decoded_data;
 		uint8_t *edp = encoded_data;
-		uint32_t x;
+		int x;
 		uint32_t loops = decoded_data_len / (sizeof(*ddp));
 
-		for (x = 0; x < loops && new_len < *encoded_data_len; x++) {
-			int edata = encoder(*ddp, AUDIO_ENCODING_LINEAR, context);
-			int bits = handle->bbits + handle->bits_per_frame;
-			
-			handle->ecount++;
-			if (!handle->bbits) {
-				//printf("new byte assign the %d bits\n", handle->bits_per_frame);
-				*handle->ptr = edata;
-			} else if (bits <= BITS_IN_A_BYTE) {
-				int shift_by = ((handle->bits_per_frame * (handle->ecount -1)));
-				//printf ("shift by %d and add %d bits\n", shift_by, handle->bits_per_frame);
-				//*handle->ptr <<= shift_by;
-				//*handle->ptr |= edata;
-				if (shift_by);
+		switch_bitpack_init(&handle->pack, handle->bits_per_frame, edp, *encoded_data_len, handle->mode);
 
-				//printf("edata\n");
-				//print_bits(edata);
-				//printf("\n");
-				
-				*handle->ptr <<= shift_by;
-				*handle->ptr |= edata;
-
-				//printf("handle\n");
-				//print_bits(*handle->ptr);
-				//printf("\n");				
-
-			} else {
-				int remain, next, rdata, ndata;
-
-				remain = BITS_IN_A_BYTE - handle->bits_per_frame;
-				next = handle->bits_per_frame - remain;
-				rdata = edata;
-				ndata = edata;
-
-				*handle->ptr += (uint8_t)(edata << remain);
-				*handle->ptr = ndata;
-
-				handle->bbits = 0;
-				handle->ecount = 0;
-			}
-			handle->bits = bits;
-			handle->bbits += handle->bits_per_frame;
-
-			if (0) {
-			for(x = 0; x < 5; x++) {
-				print_bits(handle->buf[x]);
-				printf(" ");
-			}
-			printf("\n");
-			}
-
-			if ((handle->bits % BITS_IN_A_BYTE) == 0) {
-				int bytes = handle->bits / BITS_IN_A_BYTE, count;
-				for(count = 0; count < bytes; count++) {
-					edp[new_len++] = handle->buf[count];
-				}
-				handle->bits = handle->bbits = 0;
-				handle->ptr = handle->buf;
-				handle->ecount = 0;
-				memset(handle->buf, 0, sizeof(handle->buf));
-			}
+		for (x = 0; x < loops && new_len < *encoded_data_len; x++) {
+			int edata = handle->encoder(*ddp, AUDIO_ENCODING_LINEAR, context);
+			switch_bitpack_in(&handle->pack, edata);
 			ddp++;
 		}
+		switch_bitpack_done(&handle->pack);
+		new_len = handle->pack.bytes;
 
 		if (new_len <= *encoded_data_len) {
 			*encoded_data_len = new_len;
@@ -242,95 +179,35 @@
 
 	g726_handle_t *handle = codec->private_info;
 	g726_state *context = &handle->context;
-	//uint32_t len = codec->implementation->bytes_per_frame;
-	uint32_t elen = codec->implementation->encoded_bytes_per_frame;
-	decoder_t decoder;
+	int16_t *ddp = decoded_data;
+	uint32_t new_len = 0, z = 0, y;
 
+	switch_byte_t *in = (switch_byte_t *) encoded_data;
 
-	switch(elen) {
-	case 100:
-		decoder = g726_40_decoder;
-		break;
-	case 80:
-		decoder = g726_32_decoder;
-		break;
-	case 60:
-		decoder = g726_24_decoder;
-		break;
-	case 40:
-		decoder = g726_16_decoder;
-		break;
-	default:
-		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "invalid Encoding Size %d!\n", elen);
+	if (!handle || !context) {
 		return SWITCH_STATUS_FALSE;
-		break;
 	}
 
-	if (!context) {
-		return SWITCH_STATUS_FALSE;
-
-	}
-
-
-	{
-
-		int loops = ((int)encoded_data_len * BITS_IN_A_BYTE) / handle->bits_per_frame;
-		int8_t *edp = encoded_data;
-		int16_t *ddp = decoded_data;
-		int x;
-		uint32_t new_len = 0;
-
-		for (x = 0; x < loops && new_len < *decoded_data_len; x++) {
-			int in = 0;
-			int bits = 0;
-			int8_t over = 0;
-			int8_t under = 0;
-
-			if (handle->save) {
-				in = handle->save;
-				handle->save = 0;
-			}
-			
-			handle->d_bits += handle->bits_per_frame;
-			bits = handle->d_bbits + handle->bits_per_frame;
-
-			if (bits > BITS_IN_A_BYTE) {
-				int tmp;
-				over = bits - BITS_IN_A_BYTE;
-				under = handle->bits_per_frame - over;
-				handle->dcount = 0;
-				tmp = *edp >> (BITS_IN_A_BYTE - (handle->bits_per_frame * handle->dcount));
-				in = tmp >> over;
-				handle->save = tmp;
-				handle->save  &= (1 << under) - 1;
-				edp++;
-			} else if (bits == BITS_IN_A_BYTE) {
-				handle->d_bbits = 0;
-				in = *edp;
-				edp++;
-				handle->dcount = 0;
-			} else {
-				in |= *edp >> (BITS_IN_A_BYTE - (handle->bits_per_frame * handle->dcount));
-				handle->d_bbits = bits;
-			}
-
-			
-
-			handle->dcount++;
-
-			*ddp++ = decoder(in, AUDIO_ENCODING_LINEAR, context);
-			new_len += 2;
+	while (z < encoded_data_len && new_len <= *decoded_data_len) {
+		switch_bitpack_init(&handle->unpack, handle->bits_per_frame, handle->buf, sizeof(handle->buf), handle->mode);
+		for (y = 0; y < handle->loops; y++) {
+			switch_bitpack_out(&handle->unpack, in[z++]);
 		}
-
-		if (new_len <= *decoded_data_len) {
-			*decoded_data_len = new_len;
-		} else {
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "buffer overflow!!!\n");
-			return SWITCH_STATUS_FALSE;
+		for(y = 0; y < handle->bytes; y++) {
+			*ddp++ = handle->decoder(handle->buf[y], AUDIO_ENCODING_LINEAR, context);
+            new_len += 2;
 		}
-
+		switch_bitpack_done(&handle->unpack);
 	}
+	
+	if (new_len <= *decoded_data_len) {
+		*decoded_data_len = new_len;
+	} else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "buffer overflow!!!\n");
+		return SWITCH_STATUS_FALSE;
+	}
 
+
 	return SWITCH_STATUS_SUCCESS;
 
 }
@@ -361,7 +238,7 @@
 
 static const switch_codec_implementation_t g726_24k_implementation = { 
 	/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, 
-	/*.ianacode */ 2, 
+	/*.ianacode */ 126, 
 	/*.iananame */ "G726-24", 
 	/*.samples_per_second */ 8000, 
 	/*.bits_per_second */ 24000, 
@@ -399,7 +276,7 @@
 
 static const switch_codec_implementation_t g726_40k_implementation = { 
 	/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, 
-	/*.ianacode */ 2, 
+	/*.ianacode */ 125, 
 	/*.iananame */ "G726-40", 
 	/*.samples_per_second */ 8000,
 	/*.bits_per_second */ 40000, 
@@ -416,32 +293,142 @@
 	/*.destroy */ switch_g726_destroy, 
 };
 
+
+
+static const switch_codec_implementation_t aal2_g726_16k_implementation = { 
+	/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, 
+	/*.ianacode */ 124, 
+	/*.iananame */ "AAL2-G726-16", 
+	/*.samples_per_second */ 8000, 
+	/*.bits_per_second */ 16000, 
+	/*.microseconds_per_frame */ 20000, 
+	/*.samples_per_frame */ 160, 
+	/*.bytes_per_frame */ 320, 
+	/*.encoded_bytes_per_frame */ 40, 
+	/*.number_of_channels */ 1, 
+	/*.pref_frames_per_packet */ 1, 
+	/*.max_frames_per_packet */ 1, 
+	/*.init */ switch_g726_init, 
+	/*.encode */ switch_g726_encode, 
+	/*.decode */ switch_g726_decode, 
+	/*.destroy */ switch_g726_destroy, 
+};
+
+
+static const switch_codec_implementation_t aal2_g726_24k_implementation = { 
+	/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, 
+	/*.ianacode */ 123, 
+	/*.iananame */ "AAL2-G726-24", 
+	/*.samples_per_second */ 8000, 
+	/*.bits_per_second */ 24000, 
+	/*.microseconds_per_frame */ 20000, 
+	/*.samples_per_frame */ 160, 
+	/*.bytes_per_frame */ 320, 
+	/*.encoded_bytes_per_frame */ 60, 
+	/*.number_of_channels */ 1, 
+	/*.pref_frames_per_packet */ 1, 
+	/*.max_frames_per_packet */ 1, 
+	/*.init */ switch_g726_init, 
+	/*.encode */ switch_g726_encode, 
+	/*.decode */ switch_g726_decode, 
+	/*.destroy */ switch_g726_destroy, 
+};
+
+static const switch_codec_implementation_t aal2_g726_32k_implementation = { 
+	/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, 
+	/*.ianacode */ 2, 
+	/*.iananame */ "AAL2-G726-32", 
+	/*.samples_per_second */ 8000, 
+	/*.bits_per_second */ 32000, 
+	/*.microseconds_per_frame */ 20000, 
+	/*.samples_per_frame */ 160, 
+	/*.bytes_per_frame */ 320, 
+	/*.encoded_bytes_per_frame */ 80, 
+	/*.number_of_channels */ 1, 
+	/*.pref_frames_per_packet */ 1, 
+	/*.max_frames_per_packet */ 1, 
+	/*.init */ switch_g726_init, 
+	/*.encode */ switch_g726_encode, 
+	/*.decode */ switch_g726_decode, 
+	/*.destroy */ switch_g726_destroy, 
+};
+
+static const switch_codec_implementation_t aal2_g726_40k_implementation = { 
+	/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, 
+	/*.ianacode */ 122, 
+	/*.iananame */ "AAL2-G726-40", 
+	/*.samples_per_second */ 8000,
+	/*.bits_per_second */ 40000, 
+	/*.microseconds_per_frame */ 20000, 
+	/*.samples_per_frame */ 160, 
+	/*.bytes_per_frame */ 320, 
+	/*.encoded_bytes_per_frame */ 100, 
+	/*.number_of_channels */ 1, 
+	/*.pref_frames_per_packet */ 1, 
+	/*.max_frames_per_packet */ 1, 
+	/*.init */ switch_g726_init, 
+	/*.encode */ switch_g726_encode, 
+	/*.decode */ switch_g726_decode, 
+	/*.destroy */ switch_g726_destroy, 
+};
+
 const switch_codec_interface_t g726_16k_codec_interface = { 
 	/*.interface_name */ "G.726 16k", 
 	/*.implementations */ &g726_16k_implementation, 
 };
+
 const switch_codec_interface_t g726_24k_codec_interface = { 
 	/*.interface_name */ "G.726 24k", 
 	/*.implementations */ &g726_24k_implementation, 
 	/*.next */ &g726_16k_codec_interface
 };
+
 const switch_codec_interface_t g726_32k_codec_interface = { 
 	/*.interface_name */ "G.726 32k", 
 	/*.implementations */ &g726_32k_implementation, 
 	/*.next */ &g726_24k_codec_interface
 };
+
 const switch_codec_interface_t g726_40k_codec_interface = { 
 	/*.interface_name */ "G.726 40k", 
 	/*.implementations */ &g726_40k_implementation, 
 	/*.next */ &g726_32k_codec_interface
 };
 
+
+
+const switch_codec_interface_t aal2_g726_16k_codec_interface = { 
+	/*.interface_name */ "G.726 16k (aal2)", 
+	/*.implementations */ &aal2_g726_16k_implementation, 
+	/*.next */ &g726_40k_codec_interface
+};
+
+const switch_codec_interface_t aal2_g726_24k_codec_interface = { 
+	/*.interface_name */ "G.726 24k (aal2)", 
+	/*.implementations */ &aal2_g726_24k_implementation, 
+	/*.next */ &aal2_g726_16k_codec_interface
+};
+
+const switch_codec_interface_t aal2_g726_32k_codec_interface = { 
+	/*.interface_name */ "G.726 32k (aal2)", 
+	/*.implementations */ &aal2_g726_32k_implementation, 
+	/*.next */ &aal2_g726_24k_codec_interface
+};
+
+const switch_codec_interface_t aal2_g726_40k_codec_interface = { 
+	/*.interface_name */ "G.726 40k (aal2)", 
+	/*.implementations */ &aal2_g726_40k_implementation, 
+	/*.next */ &aal2_g726_32k_codec_interface
+};
+
+
+
 static switch_loadable_module_interface_t g726_module_interface = { 
 	/*.module_name */ modname, 
 	/*.endpoint_interface */ NULL, 
 	/*.timer_interface */ NULL, 
 	/*.dialplan_interface */ NULL, 
-	/*.codec_interface */ &g726_40k_codec_interface, 
+	/*.codec_interface */ &aal2_g726_40k_codec_interface, 
 	/*.application_interface */ NULL 
 };
 

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c	Sat Sep  2 19:04:25 2006
@@ -125,6 +125,7 @@
 	su_root_t *s_root;
 	sip_alias_node_t *aliases;
 	switch_payload_t te;
+	uint32_t codec_flags;
 };
 
 
@@ -300,7 +301,7 @@
 		for (i = 0; i < tech_pvt->num_codecs; i++) {
 			const switch_codec_implementation_t *imp = tech_pvt->codecs[i];
 			snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=rtpmap:%d %s/%d\n", imp->ianacode, imp->iananame, imp->samples_per_second);
-			snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=ptime:%d", imp->microseconds_per_frame / 1000);
+			snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=ptime:%d\n", imp->microseconds_per_frame / 1000);
 		}
 	}
 	
@@ -607,7 +608,7 @@
 							   tech_pvt->rm_rate,
 							   tech_pvt->codec_ms,
 							   1,
-							   SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
+							   SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE | tech_pvt->profile->codec_flags,
 							   NULL,
 							   switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
@@ -619,7 +620,7 @@
 								   tech_pvt->rm_rate,
 								   tech_pvt->codec_ms,
 								   1,
-								   SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
+								   SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE | tech_pvt->profile->codec_flags,
 								   NULL,
 								   switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
@@ -1683,6 +1684,10 @@
 				profile->sipdomain = switch_core_strdup(profile->pool, val);
 			} else if (!strcmp(var, "ext-sip-ip")) {
 				profile->extsipip = switch_core_strdup(profile->pool, val);
+			} else if (!strcmp(var, "bitpacking")) {
+				if (!strcasecmp(val, "aal2")) {
+					profile->codec_flags = SWITCH_CODEC_FLAG_AAL2;
+				} 
 			} else if (!strcmp(var, "username")) {
 				profile->username = switch_core_strdup(profile->pool, val);
 			} else if (!strcmp(var, "context")) {



More information about the Freeswitch-svn mailing list