fix bug 2 (core was hacking the buffer size value)

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@576 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2006-02-09 17:01:32 +00:00
parent 95fbe70503
commit ef6d92ae7d
2 changed files with 165 additions and 160 deletions

View File

@ -1,175 +1,177 @@
/* /*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com> * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
* *
* Version: MPL 1.1 * Version: MPL 1.1
* *
* The contents of this file are subject to the Mozilla Public License Version * 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 * 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 * the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/ * http://www.mozilla.org/MPL/
* *
* Software distributed under the License is distributed on an "AS IS" basis, * Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the * for the specific language governing rights and limitations under the
* License. * License.
* *
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* *
* The Initial Developer of the Original Code is * The Initial Developer of the Original Code is
* Anthony Minessale II <anthmct@yahoo.com> * Anthony Minessale II <anthmct@yahoo.com>
* Portions created by the Initial Developer are Copyright (C) * Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved. * the Initial Developer. All Rights Reserved.
* *
* Contributor(s): * Contributor(s):
* *
* Anthony Minessale II <anthmct@yahoo.com> * Anthony Minessale II <anthmct@yahoo.com>
* Michael Jerris <mike@jerris.com> * Michael Jerris <mike@jerris.com>
* *
* mod_codec_gsm.c -- gsm Codec Module * mod_codec_gsm.c -- gsm Codec Module
* *
*/ */
#include "switch.h" #include "switch.h"
#include "gsm.h" #include "gsm.h"
static const char modname[] = "mod_codec_gsm"; static const char modname[] = "mod_codec_gsm";
struct gsm_context { struct gsm_context {
gsm encoder; gsm encoder;
gsm decoder; gsm decoder;
}; };
static switch_status switch_gsm_init(switch_codec *codec, switch_codec_flag flags, static switch_status switch_gsm_init(switch_codec *codec, switch_codec_flag flags,
const struct switch_codec_settings *codec_settings) const struct switch_codec_settings *codec_settings)
{ {
struct gsm_context *context; struct gsm_context *context;
int encoding, decoding; int encoding, decoding;
encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
decoding = (flags & SWITCH_CODEC_FLAG_DECODE); decoding = (flags & SWITCH_CODEC_FLAG_DECODE);
if (!(encoding || decoding)) { if (!(encoding || decoding)) {
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} else { } else {
context = switch_core_alloc(codec->memory_pool, sizeof(*context)); context = switch_core_alloc(codec->memory_pool, sizeof(*context));
if (encoding) if (encoding)
context->encoder = gsm_create(); context->encoder = gsm_create();
if (decoding) if (decoding)
context->decoder = gsm_create(); context->decoder = gsm_create();
} }
codec->private = context; codec->private = context;
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
static switch_status switch_gsm_destroy(switch_codec *codec) static switch_status switch_gsm_destroy(switch_codec *codec)
{ {
struct gsm_context *context = codec->private; struct gsm_context *context = codec->private;
int encoding = (codec->flags & SWITCH_CODEC_FLAG_ENCODE); int encoding = (codec->flags & SWITCH_CODEC_FLAG_ENCODE);
int decoding = (codec->flags & SWITCH_CODEC_FLAG_DECODE); int decoding = (codec->flags & SWITCH_CODEC_FLAG_DECODE);
if (encoding) if (encoding)
gsm_destroy(context->encoder); gsm_destroy(context->encoder);
if (decoding) if (decoding)
gsm_destroy(context->decoder); gsm_destroy(context->decoder);
codec->private = NULL; codec->private = NULL;
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
static switch_status switch_gsm_encode(switch_codec *codec, switch_codec *other_codec, void *decoded_data, static switch_status switch_gsm_encode(switch_codec *codec, switch_codec *other_codec, void *decoded_data,
size_t decoded_data_len, int decoded_rate, void *encoded_data, size_t decoded_data_len, int decoded_rate, void *encoded_data,
size_t *encoded_data_len, int *encoded_rate, unsigned int *flag) size_t *encoded_data_len, int *encoded_rate, unsigned int *flag)
{ {
struct gsm_context *context = codec->private; struct gsm_context *context = codec->private;
int cbret = 0; int cbret = 0;
if (!context) { if (!context) {
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }
if (decoded_data_len % 320 == 0) { if (decoded_data_len % 320 == 0) {
unsigned int new_len = 0; unsigned int new_len = 0;
gsm_signal * ddp = decoded_data; gsm_signal * ddp = decoded_data;
gsm_byte * edp = encoded_data; gsm_byte * edp = encoded_data;
int x; int x;
int loops = (int) decoded_data_len / 320; int loops = (int) decoded_data_len / 320;
for (x = 0; x < loops && new_len < *encoded_data_len; x++) { for (x = 0; x < loops && new_len < *encoded_data_len; x++) {
gsm_encode(context->encoder, ddp, edp); gsm_encode(context->encoder, ddp, edp);
edp += 33; edp += 33;
ddp += 160; ddp += 160;
new_len += 33; new_len += 33;
} }
if (new_len <= *encoded_data_len) { if (new_len <= *encoded_data_len) {
*encoded_data_len = new_len; *encoded_data_len = new_len;
} else { } else {
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "buffer overflow!!! %u >= %u\n", new_len, *encoded_data_len); switch_console_printf(SWITCH_CHANNEL_CONSOLE, "buffer overflow!!! %u >= %u\n", new_len, *encoded_data_len);
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }
} }
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
static switch_status switch_gsm_decode(switch_codec *codec, switch_codec *other_codec, void *encoded_data, static switch_status switch_gsm_decode(switch_codec *codec, switch_codec *other_codec, void *encoded_data,
size_t encoded_data_len, int encoded_rate, void *decoded_data, size_t encoded_data_len, int encoded_rate, void *decoded_data,
size_t *decoded_data_len, int *decoded_rate, unsigned int *flag) size_t *decoded_data_len, int *decoded_rate, unsigned int *flag)
{ {
struct gsm_context *context = codec->private; struct gsm_context *context = codec->private;
if (!context) { if (!context) {
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }
if (encoded_data_len % 33 == 0) {
int loops = (int) encoded_data_len / 33;
gsm_byte * edp = encoded_data;
gsm_signal * ddp = decoded_data;
int x;
unsigned int new_len = 0;
for (x = 0; x < loops && new_len < *decoded_data_len; x++) {
gsm_decode(context->decoder, edp, ddp);
ddp += 160;
edp += 33;
new_len += 320;
}
if (new_len <= *decoded_data_len) {
*decoded_data_len = new_len;
} else {
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "buffer overflow!!!\n");
return SWITCH_STATUS_FALSE;
}
} else {
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "yo this frame is an odd size [%d]\n", encoded_data_len);
}
return SWITCH_STATUS_SUCCESS;
}
if (encoded_data_len % 33 == 0) {
/* Registration */ int loops = (int) encoded_data_len / 33;
static const switch_codec_implementation gsm_8k_implementation = { gsm_byte * edp = encoded_data;
/*.samples_per_second */ 8000, gsm_signal * ddp = decoded_data;
/*.bits_per_second */ 13200, int x;
/*.microseconds_per_frame */ 20000, unsigned int new_len = 0;
/*.samples_per_frame */ 160,
/*.bytes_per_frame */ 320, for (x = 0; x < loops && new_len < *decoded_data_len; x++) {
/*.encoded_bytes_per_frame */ 33, gsm_decode(context->decoder, edp, ddp);
/*.number_of_channels */ 1, ddp += 160;
/*.pref_frames_per_packet */ 1, edp += 33;
/*.max_frames_per_packet */ 1, new_len += 320;
/*.init */ switch_gsm_init, }
/*.encode */ switch_gsm_encode, if (new_len <= *decoded_data_len) {
/*.decode */ switch_gsm_decode, *decoded_data_len = new_len;
/*.destroy */ switch_gsm_destroy, } else {
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "buffer overflow!!! %d %d\n", new_len, *decoded_data_len);
return SWITCH_STATUS_FALSE;
}
} else {
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "yo this frame is an odd size [%d]\n", encoded_data_len);
}
return SWITCH_STATUS_SUCCESS;
}
/* Registration */
static const switch_codec_implementation gsm_8k_implementation = {
/*.samples_per_second */ 8000,
/*.bits_per_second */ 13200,
/*.microseconds_per_frame */ 20000,
/*.samples_per_frame */ 160,
/*.bytes_per_frame */ 320,
/*.encoded_bytes_per_frame */ 33,
/*.number_of_channels */ 1,
/*.pref_frames_per_packet */ 1,
/*.max_frames_per_packet */ 1,
/*.init */ switch_gsm_init,
/*.encode */ switch_gsm_encode,
/*.decode */ switch_gsm_decode,
/*.destroy */ switch_gsm_destroy,
}; };
static const switch_codec_interface gsm_codec_interface = { static const switch_codec_interface gsm_codec_interface = {
/*.interface_name */ "gsm", /*.interface_name */ "gsm",
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 3, /*.ianacode */ 3,
/*.iananame */ "gsm", /*.iananame */ "gsm",
/*.implementations */ &gsm_8k_implementation, /*.implementations */ &gsm_8k_implementation,
}; };
static switch_loadable_module_interface gsm_module_interface = { static switch_loadable_module_interface gsm_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 */ &gsm_codec_interface, /*.codec_interface */ &gsm_codec_interface,
/*.application_interface */ NULL /*.application_interface */ NULL
}; };
SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface, SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface,
char *filename) char *filename)
{ {
/* connect my internal structure to the blank pointer passed to me */ /* connect my internal structure to the blank pointer passed to me */
*interface = &gsm_module_interface; *interface = &gsm_module_interface;
/* indicate that the module should continue to be loaded */ /* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }

View File

@ -330,7 +330,7 @@ SWITCH_DECLARE(switch_status) switch_core_codec_encode(switch_codec *codec,
return SWITCH_STATUS_GENERR; return SWITCH_STATUS_GENERR;
} }
*encoded_data_len = decoded_data_len;
return codec->implementation->encode(codec, return codec->implementation->encode(codec,
other_codec, other_codec,
decoded_data, decoded_data,
@ -352,6 +352,8 @@ SWITCH_DECLARE(switch_status) switch_core_codec_decode(switch_codec *codec,
assert(encoded_data != NULL); assert(encoded_data != NULL);
assert(decoded_data != NULL); assert(decoded_data != NULL);
if (!codec->implementation) { if (!codec->implementation) {
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Codec is not initilized!\n"); switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Codec is not initilized!\n");
return SWITCH_STATUS_GENERR; return SWITCH_STATUS_GENERR;
@ -362,7 +364,7 @@ SWITCH_DECLARE(switch_status) switch_core_codec_decode(switch_codec *codec,
return SWITCH_STATUS_GENERR; return SWITCH_STATUS_GENERR;
} }
*decoded_data_len = encoded_data_len;
return codec->implementation->decode(codec, return codec->implementation->decode(codec,
other_codec, other_codec,
encoded_data, encoded_data,
@ -1090,6 +1092,7 @@ SWITCH_DECLARE(switch_status) switch_core_session_write_frame(switch_core_sessio
if (need_codec) { if (need_codec) {
if (frame->codec) { if (frame->codec) {
session->raw_write_frame.datalen = session->raw_write_frame.buflen; session->raw_write_frame.datalen = session->raw_write_frame.buflen;
status = switch_core_codec_decode(frame->codec, status = switch_core_codec_decode(frame->codec,
session->write_codec, session->write_codec,
frame->data, frame->data,