pack this mutha %^%$^&

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@2483 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2006-09-02 23:04:25 +00:00
parent 1bfe008b7f
commit 8543778b7c
5 changed files with 495 additions and 204 deletions

View File

@ -0,0 +1,272 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005/2006, Anthony Minessale II <anthmct@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@yahoo.com>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Anthony Minessale II <anthmct@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

View File

@ -72,6 +72,32 @@ BEGIN_EXTERN_C
#define SWITCH_HTDOCS_DIR SWITCH_PREFIX_DIR SWITCH_PATH_SEPARATOR "htdocs" #define SWITCH_HTDOCS_DIR SWITCH_PREFIX_DIR SWITCH_PATH_SEPARATOR "htdocs"
#endif #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 { struct switch_directories {
char *base_dir; char *base_dir;
char *mod_dir; char *mod_dir;
@ -417,6 +443,7 @@ SWITCH_CODEC_FLAG_SILENCE_START = (1 << 2) - Start period of silence
SWITCH_CODEC_FLAG_SILENCE_STOP = (1 << 3) - End period of silence SWITCH_CODEC_FLAG_SILENCE_STOP = (1 << 3) - End period of silence
SWITCH_CODEC_FLAG_SILENCE = (1 << 4) - Silence SWITCH_CODEC_FLAG_SILENCE = (1 << 4) - Silence
SWITCH_CODEC_FLAG_FREE_POOL = (1 << 5) - Free codec's pool on destruction SWITCH_CODEC_FLAG_FREE_POOL = (1 << 5) - Free codec's pool on destruction
SWITCH_CODEC_FLAG_AAL2 = (1 << 6) - USE AAL2 Bitpacking
</pre> </pre>
*/ */
typedef enum { typedef enum {
@ -426,7 +453,7 @@ typedef enum {
SWITCH_CODEC_FLAG_SILENCE_STOP = (1 << 3), SWITCH_CODEC_FLAG_SILENCE_STOP = (1 << 3),
SWITCH_CODEC_FLAG_SILENCE = (1 << 4), SWITCH_CODEC_FLAG_SILENCE = (1 << 4),
SWITCH_CODEC_FLAG_FREE_POOL = (1 << 5), SWITCH_CODEC_FLAG_FREE_POOL = (1 << 5),
SWITCH_CODEC_FLAG_AAL2 = (1 << 6)
} switch_codec_flag_t; } switch_codec_flag_t;

View File

@ -5,7 +5,7 @@ all: depends $(MODNAME).$(DYNAMIC_LIB_EXTEN)
depends: depends:
MAKE=$(MAKE) $(BASE)/build/buildlib.sh $(BASE) install codec/g726 --prefix=$(PREFIX) 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) $(CFLAGS) -fPIC -c $(MODNAME).c -o $(MODNAME).o
$(CC) $(SOLINK) $(MODNAME).o -o $(MODNAME).$(DYNAMIC_LIB_EXTEN) $(LDFLAGS) $(CC) $(SOLINK) $(MODNAME).o -o $(MODNAME).$(DYNAMIC_LIB_EXTEN) $(LDFLAGS)

View File

@ -31,29 +31,31 @@
*/ */
#include "switch.h" #include "switch.h"
#include "g72x.h" #include "g72x.h"
#define BITS_IN_A_BYTE 8 #include "switch_bitpack.h"
static const char modname[] = "mod_g726"; static const char modname[] = "mod_g726";
typedef int (*encoder_t)(int, int, g726_state *);
typedef int (*decoder_t)(int, int, g726_state *);
typedef struct { typedef struct {
g726_state context; g726_state context;
uint8_t buf[5];
uint8_t *ptr;
uint8_t bits_per_frame; uint8_t bits_per_frame;
uint8_t bits; encoder_t encoder;
uint8_t bbits; decoder_t decoder;
uint8_t ecount; switch_bitpack_t pack;
uint8_t d_bits; switch_bitpack_t unpack;
uint8_t d_bbits; switch_bitpack_mode_t mode;
uint8_t dcount; switch_byte_t loops;
uint8_t save; switch_byte_t bytes;
switch_byte_t buf[160];
} g726_handle_t; } g726_handle_t;
static switch_status_t switch_g726_init(switch_codec_t *codec, switch_codec_flag_t flags, static switch_status_t switch_g726_init(switch_codec_t *codec, switch_codec_flag_t flags,
const switch_codec_settings_t *codec_settings) const switch_codec_settings_t *codec_settings)
{ {
int encoding, decoding; switch_byte_t encoding, decoding;
g726_handle_t *handle; g726_handle_t *handle;
encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
@ -62,10 +64,40 @@ static switch_status_t switch_g726_init(switch_codec_t *codec, switch_codec_flag
if (!(encoding || decoding) || (!(handle = switch_core_alloc(codec->memory_pool, sizeof(*handle))))) { if (!(encoding || decoding) || (!(handle = switch_core_alloc(codec->memory_pool, sizeof(*handle))))) {
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} else { } 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); g726_init_state(&handle->context);
codec->private_info = handle; codec->private_info = handle;
handle->bits_per_frame = (uint8_t)(codec->implementation->bits_per_second / (codec->implementation->samples_per_second)); handle->bits_per_frame = codec->implementation->bits_per_second / (codec->implementation->samples_per_second);
handle->ptr = handle->buf; handle->mode = (flags & SWITCH_CODEC_FLAG_AAL2 || strstr(codec->implementation->iananame, "AAL2"))
? SWITCH_BITPACK_MODE_AAL2 : SWITCH_BITPACK_MODE_RFC3551;
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
} }
@ -77,27 +109,6 @@ static switch_status_t switch_g726_destroy(switch_codec_t *codec)
return SWITCH_STATUS_SUCCESS; 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, static switch_status_t switch_g726_encode(switch_codec_t *codec,
@ -116,27 +127,7 @@ static switch_status_t switch_g726_encode(switch_codec_t *codec,
g726_handle_t *handle = codec->private_info; g726_handle_t *handle = codec->private_info;
g726_state *context = &handle->context; g726_state *context = &handle->context;
uint32_t len = codec->implementation->bytes_per_frame; uint32_t len = codec->implementation->bytes_per_frame;
uint32_t elen = codec->implementation->encoded_bytes_per_frame; //uint32_t elen = codec->implementation->encoded_bytes_per_frame;
encoder_t encoder;
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) { if (!context) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error!\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error!\n");
@ -147,72 +138,18 @@ static switch_status_t switch_g726_encode(switch_codec_t *codec,
uint32_t new_len = 0; uint32_t new_len = 0;
int16_t *ddp = decoded_data; int16_t *ddp = decoded_data;
uint8_t *edp = encoded_data; uint8_t *edp = encoded_data;
uint32_t x; int x;
uint32_t loops = decoded_data_len / (sizeof(*ddp)); uint32_t loops = decoded_data_len / (sizeof(*ddp));
switch_bitpack_init(&handle->pack, handle->bits_per_frame, edp, *encoded_data_len, handle->mode);
for (x = 0; x < loops && new_len < *encoded_data_len; x++) { for (x = 0; x < loops && new_len < *encoded_data_len; x++) {
int edata = encoder(*ddp, AUDIO_ENCODING_LINEAR, context); int edata = handle->encoder(*ddp, AUDIO_ENCODING_LINEAR, context);
int bits = handle->bbits + handle->bits_per_frame; switch_bitpack_in(&handle->pack, edata);
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);
//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));
}
ddp++; ddp++;
} }
switch_bitpack_done(&handle->pack);
new_len = handle->pack.bytes;
if (new_len <= *encoded_data_len) { if (new_len <= *encoded_data_len) {
*encoded_data_len = new_len; *encoded_data_len = new_len;
@ -242,85 +179,26 @@ static switch_status_t switch_g726_decode(switch_codec_t *codec,
g726_handle_t *handle = codec->private_info; g726_handle_t *handle = codec->private_info;
g726_state *context = &handle->context; 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;
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);
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; int16_t *ddp = decoded_data;
int x; uint32_t new_len = 0, z = 0, y;
uint32_t new_len = 0;
for (x = 0; x < loops && new_len < *decoded_data_len; x++) { switch_byte_t *in = (switch_byte_t *) encoded_data;
int in = 0;
int bits = 0;
int8_t over = 0;
int8_t under = 0;
if (handle->save) { if (!handle || !context) {
in = handle->save; return SWITCH_STATUS_FALSE;
handle->save = 0;
} }
handle->d_bits += handle->bits_per_frame; while (z < encoded_data_len && new_len <= *decoded_data_len) {
bits = handle->d_bbits + handle->bits_per_frame; switch_bitpack_init(&handle->unpack, handle->bits_per_frame, handle->buf, sizeof(handle->buf), handle->mode);
for (y = 0; y < handle->loops; y++) {
if (bits > BITS_IN_A_BYTE) { switch_bitpack_out(&handle->unpack, in[z++]);
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;
} }
for(y = 0; y < handle->bytes; y++) {
*ddp++ = handle->decoder(handle->buf[y], AUDIO_ENCODING_LINEAR, context);
handle->dcount++;
*ddp++ = decoder(in, AUDIO_ENCODING_LINEAR, context);
new_len += 2; new_len += 2;
} }
switch_bitpack_done(&handle->unpack);
}
if (new_len <= *decoded_data_len) { if (new_len <= *decoded_data_len) {
*decoded_data_len = new_len; *decoded_data_len = new_len;
@ -329,7 +207,6 @@ static switch_status_t switch_g726_decode(switch_codec_t *codec,
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }
}
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
@ -361,7 +238,7 @@ static const switch_codec_implementation_t g726_16k_implementation = {
static const switch_codec_implementation_t g726_24k_implementation = { static const switch_codec_implementation_t g726_24k_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 2, /*.ianacode */ 126,
/*.iananame */ "G726-24", /*.iananame */ "G726-24",
/*.samples_per_second */ 8000, /*.samples_per_second */ 8000,
/*.bits_per_second */ 24000, /*.bits_per_second */ 24000,
@ -399,7 +276,7 @@ static const switch_codec_implementation_t g726_32k_implementation = {
static const switch_codec_implementation_t g726_40k_implementation = { static const switch_codec_implementation_t g726_40k_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 2, /*.ianacode */ 125,
/*.iananame */ "G726-40", /*.iananame */ "G726-40",
/*.samples_per_second */ 8000, /*.samples_per_second */ 8000,
/*.bits_per_second */ 40000, /*.bits_per_second */ 40000,
@ -416,32 +293,142 @@ static const switch_codec_implementation_t g726_40k_implementation = {
/*.destroy */ switch_g726_destroy, /*.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 = { const switch_codec_interface_t g726_16k_codec_interface = {
/*.interface_name */ "G.726 16k", /*.interface_name */ "G.726 16k",
/*.implementations */ &g726_16k_implementation, /*.implementations */ &g726_16k_implementation,
}; };
const switch_codec_interface_t g726_24k_codec_interface = { const switch_codec_interface_t g726_24k_codec_interface = {
/*.interface_name */ "G.726 24k", /*.interface_name */ "G.726 24k",
/*.implementations */ &g726_24k_implementation, /*.implementations */ &g726_24k_implementation,
/*.next */ &g726_16k_codec_interface /*.next */ &g726_16k_codec_interface
}; };
const switch_codec_interface_t g726_32k_codec_interface = { const switch_codec_interface_t g726_32k_codec_interface = {
/*.interface_name */ "G.726 32k", /*.interface_name */ "G.726 32k",
/*.implementations */ &g726_32k_implementation, /*.implementations */ &g726_32k_implementation,
/*.next */ &g726_24k_codec_interface /*.next */ &g726_24k_codec_interface
}; };
const switch_codec_interface_t g726_40k_codec_interface = { const switch_codec_interface_t g726_40k_codec_interface = {
/*.interface_name */ "G.726 40k", /*.interface_name */ "G.726 40k",
/*.implementations */ &g726_40k_implementation, /*.implementations */ &g726_40k_implementation,
/*.next */ &g726_32k_codec_interface /*.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 = { static switch_loadable_module_interface_t g726_module_interface = {
/*.module_name */ modname, /*.module_name */ modname,
/*.endpoint_interface */ NULL, /*.endpoint_interface */ NULL,
/*.timer_interface */ NULL, /*.timer_interface */ NULL,
/*.dialplan_interface */ NULL, /*.dialplan_interface */ NULL,
/*.codec_interface */ &g726_40k_codec_interface, /*.codec_interface */ &aal2_g726_40k_codec_interface,
/*.application_interface */ NULL /*.application_interface */ NULL
}; };

View File

@ -125,6 +125,7 @@ struct sofia_profile {
su_root_t *s_root; su_root_t *s_root;
sip_alias_node_t *aliases; sip_alias_node_t *aliases;
switch_payload_t te; switch_payload_t te;
uint32_t codec_flags;
}; };
@ -300,7 +301,7 @@ static void set_local_sdp(private_object_t *tech_pvt)
for (i = 0; i < tech_pvt->num_codecs; i++) { for (i = 0; i < tech_pvt->num_codecs; i++) {
const switch_codec_implementation_t *imp = tech_pvt->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=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 @@ static switch_status_t tech_set_codec(private_object_t *tech_pvt)
tech_pvt->rm_rate, tech_pvt->rm_rate,
tech_pvt->codec_ms, tech_pvt->codec_ms,
1, 1,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE | tech_pvt->profile->codec_flags,
NULL, NULL,
switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { 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"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
@ -619,7 +620,7 @@ static switch_status_t tech_set_codec(private_object_t *tech_pvt)
tech_pvt->rm_rate, tech_pvt->rm_rate,
tech_pvt->codec_ms, tech_pvt->codec_ms,
1, 1,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE | tech_pvt->profile->codec_flags,
NULL, NULL,
switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { 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"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
@ -1683,6 +1684,10 @@ static switch_status_t config_sofia(int reload)
profile->sipdomain = switch_core_strdup(profile->pool, val); profile->sipdomain = switch_core_strdup(profile->pool, val);
} else if (!strcmp(var, "ext-sip-ip")) { } else if (!strcmp(var, "ext-sip-ip")) {
profile->extsipip = switch_core_strdup(profile->pool, val); 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")) { } else if (!strcmp(var, "username")) {
profile->username = switch_core_strdup(profile->pool, val); profile->username = switch_core_strdup(profile->pool, val);
} else if (!strcmp(var, "context")) { } else if (!strcmp(var, "context")) {