From 0ce22f5ac7d1a5ecf6599db1693b316ba21a98b2 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Sat, 10 Dec 2005 02:12:03 +0000 Subject: [PATCH] g729 codec add (this needs to leave somwhere else) git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@106 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/mod/mod_codec_g729/mod_codec_g729.c | 193 +++++++++++++++++ src/mod/mod_codec_g729/mod_codec_g729.vcproj | 209 +++++++++++++++++++ 2 files changed, 402 insertions(+) create mode 100644 src/mod/mod_codec_g729/mod_codec_g729.c create mode 100644 src/mod/mod_codec_g729/mod_codec_g729.vcproj diff --git a/src/mod/mod_codec_g729/mod_codec_g729.c b/src/mod/mod_codec_g729/mod_codec_g729.c new file mode 100644 index 0000000000..b441ac9880 --- /dev/null +++ b/src/mod/mod_codec_g729/mod_codec_g729.c @@ -0,0 +1,193 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005/2006, Anthony Minessale II + * + * 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 + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Anthony Minessale II + * + * + * mod_codec_g729.c -- G729 Codec Module + * + */ +#include "switch.h" +#include "g729.h" + +static const char modname[] = "mod_codec_g729"; + +struct g729_context { + struct dec_state *decoder_object; + struct cod_state *encoder_object; +}; + +static switch_status switch_g729_init(switch_codec *codec, switch_codec_flag flags, const struct switch_codec_settings *codec_settings) +{ + struct dec_state *decoder_object = NULL; + struct cod_state *encoder_object = NULL; + struct g729_context *context = NULL; + int encoding, decoding; + + encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); + decoding = (flags & SWITCH_CODEC_FLAG_DECODE); + + if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) { + return SWITCH_STATUS_FALSE; + } else { + if ((encoding) && (!(encoder_object = switch_core_alloc(codec->memory_pool, sizeof(*encoder_object))))) { + return SWITCH_STATUS_FALSE; + } + if ((decoding) && (!(decoder_object = switch_core_alloc(codec->memory_pool, sizeof(*decoder_object))))) { + return SWITCH_STATUS_FALSE; + } + if (encoder_object) { + g729_init_coder(encoder_object, 0); + } + if (decoder_object) { + g729_init_decoder(decoder_object); + } + context->decoder_object = decoder_object; + context->encoder_object = encoder_object; + codec->private = context; + + return SWITCH_STATUS_SUCCESS; + } +} + +static switch_status switch_g729_destroy(switch_codec *codec) +{ + codec->private = NULL; + return SWITCH_STATUS_SUCCESS; +} + + +static switch_status switch_g729_encode(switch_codec *codec, + switch_codec *other_codec, + void *decoded_data, + size_t decoded_data_len, + void *encoded_data, + size_t *encoded_data_len, + unsigned int *flag) +{ + struct g729_context *context = codec->private; + struct cod_state *encoder_object = context->encoder_object; + short *dbuf; + unsigned char *ebuf; + int cbret = 0; + + if (!context) + return SWITCH_STATUS_FALSE; + + dbuf = decoded_data; + ebuf = encoded_data; + + if (decoded_data_len < (size_t)codec->implementation->samples_per_frame*2 || *encoded_data_len < (size_t)codec->implementation->encoded_bytes_per_frame) + return SWITCH_STATUS_FALSE; + + g729_coder(encoder_object, (short *) dbuf, ebuf, &cbret); + + *encoded_data_len = (codec->implementation->encoded_bytes_per_frame / 2); + + return SWITCH_STATUS_SUCCESS; +} + + +static switch_status switch_g729_decode(switch_codec *codec, + switch_codec *other_codec, + void *encoded_data, + size_t encoded_data_len, + void *decoded_data, + size_t *decoded_data_len, + unsigned int *flag) +{ + struct g729_context *context = codec->private; + struct dec_state *decoder_object = context->decoder_object; + short *dbuf; + unsigned char *ebuf; + + if (!context) + return SWITCH_STATUS_FALSE; + + dbuf = decoded_data; + ebuf = encoded_data; + + if ((encoded_data_len * 2) < (size_t)codec->implementation->encoded_bytes_per_frame) + return SWITCH_STATUS_FALSE; + + if (*flag & SWITCH_CODEC_FLAG_SILENCE) { + memset(dbuf, 0, codec->implementation->bytes_per_frame); + *decoded_data_len = codec->implementation->bytes_per_frame; + } else { + g729_decoder(decoder_object, decoded_data, (void *) encoded_data, (int)encoded_data_len); + *decoded_data_len = codec->implementation->bytes_per_frame; + } + + return SWITCH_STATUS_SUCCESS; +} + +/* Registration */ + +static const switch_codec_implementation g729_8k_implementation = { + /*.samples_per_second*/ 8000, + /*.bits_per_second*/ 64000, + /*.microseconds_per_frame*/ 20000, + /*.samples_per_frame*/ 160, + /*.bytes_per_frame*/ 320, + /*.encoded_bytes_per_frame*/ 20, + /*.number_of_channels*/ 1, + /*.pref_frames_per_packet*/ 6, + /*.max_frames_per_packet*/ 24, + /*.init*/ switch_g729_init, + /*.encode*/ switch_g729_encode, + /*.decode*/ switch_g729_decode, + /*.destroy*/ switch_g729_destroy, +}; + +static const switch_codec_interface g729_codec_interface = { + /*.interface_name*/ "g729", + /*.codec_type*/ SWITCH_CODEC_TYPE_AUDIO, + /*.ianacode*/ 18, + /*.iananame*/ "G729", + /*.implementations*/ &g729_8k_implementation, +}; + +static switch_loadable_module_interface g729_module_interface = { + /*.module_name*/ modname, + /*.endpoint_interface*/ NULL, + /*.timer_interface*/ NULL, + /*.dialplan_interface*/ NULL, + /*.codec_interface*/ &g729_codec_interface, + /*.application_interface*/ NULL +}; + + +SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface, char *filename) { + /* connect my internal structure to the blank pointer passed to me */ + *interface = &g729_module_interface; + + /* indicate that the module should continue to be loaded */ + return SWITCH_STATUS_SUCCESS; +} + + + + + diff --git a/src/mod/mod_codec_g729/mod_codec_g729.vcproj b/src/mod/mod_codec_g729/mod_codec_g729.vcproj new file mode 100644 index 0000000000..618de67774 --- /dev/null +++ b/src/mod/mod_codec_g729/mod_codec_g729.vcproj @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +