diff --git a/src/include/switch_frame.h b/src/include/switch_frame.h index 39843593a5..354bbd0ea5 100644 --- a/src/include/switch_frame.h +++ b/src/include/switch_frame.h @@ -42,6 +42,7 @@ struct switch_frame { switch_codec *codec; void *data; size_t datalen; + size_t buflen; int samples; }; diff --git a/src/mod/mod_codec_g729/mod_codec_g729.c b/src/mod/mod_codec_g729/mod_codec_g729.c index 3181048619..aa598f0673 100644 --- a/src/mod/mod_codec_g729/mod_codec_g729.c +++ b/src/mod/mod_codec_g729/mod_codec_g729.c @@ -84,11 +84,26 @@ static switch_status switch_g729_encode(switch_codec *codec, if (!context) { return SWITCH_STATUS_FALSE; } - - g729_coder(&context->encoder_object, (short *) decoded_data, encoded_data, &cbret); - - *encoded_data_len = codec->implementation->encoded_bytes_per_frame; - + if (decoded_data_len % 160 == 0) { + unsigned int new_len = 0; + INT16 *ddp = decoded_data; + char *edp = encoded_data; + int x; + int loops = (int) decoded_data_len / 160; + + for(x = 0; x < loops && new_len < *encoded_data_len; x++) { + g729_coder(&context->encoder_object, ddp, edp, &cbret); + edp += 10; + ddp += 80; + new_len += 10; + } + if( new_len <= *encoded_data_len ) { + *encoded_data_len = new_len; + } else { + switch_console_printf(SWITCH_CHANNEL_CONSOLE, "buffer overflow!!! %u >= %u\n", new_len, *encoded_data_len); + return SWITCH_STATUS_FALSE; + } + } return SWITCH_STATUS_SUCCESS; } @@ -102,21 +117,35 @@ static switch_status switch_g729_decode(switch_codec *codec, unsigned int *flag) { struct g729_context *context = codec->private; - short *dbuf; - unsigned char *ebuf; - + if (!context) { 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(&context->decoder_object, decoded_data, encoded_data, encoded_data_len); - *decoded_data_len = codec->implementation->bytes_per_frame; - } + if (encoded_data_len % 10 == 0) { + int loops = (int) encoded_data_len / 10; + char *edp = encoded_data; + short *ddp = decoded_data; + int x; + unsigned int new_len = 0; + for(x = 0; x < loops && new_len < *decoded_data_len; x++) { + g729_decoder(&context->decoder_object, ddp, edp, 10); + ddp += 80; + edp += 10; + new_len += 160; + } + 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; } @@ -130,7 +159,7 @@ static const switch_codec_implementation g729_8k_implementation = { /*.bytes_per_frame*/ 320, /*.encoded_bytes_per_frame*/ 20, /*.number_of_channels*/ 1, - /*.pref_frames_per_packet*/ 6, + /*.pref_frames_per_packet*/ 1, /*.max_frames_per_packet*/ 24, /*.init*/ switch_g729_init, /*.encode*/ switch_g729_encode, diff --git a/src/mod/mod_exosip/mod_exosip.c b/src/mod/mod_exosip/mod_exosip.c index 07bda55065..bcc5f07a25 100644 --- a/src/mod/mod_exosip/mod_exosip.c +++ b/src/mod/mod_exosip/mod_exosip.c @@ -225,6 +225,7 @@ static switch_status exosip_on_init(switch_core_session *session) assert(tech_pvt != NULL); tech_pvt->read_frame.data = tech_pvt->read_buf; + tech_pvt->read_frame.buflen = sizeof(tech_pvt->read_buf); switch_console_printf(SWITCH_CHANNEL_CONSOLE, "EXOSIP INIT\n"); diff --git a/src/mod/mod_iaxchan/mod_iaxchan.c b/src/mod/mod_iaxchan/mod_iaxchan.c index 6f91ffd1b9..71a757e445 100644 --- a/src/mod/mod_iaxchan/mod_iaxchan.c +++ b/src/mod/mod_iaxchan/mod_iaxchan.c @@ -354,7 +354,7 @@ static switch_status channel_on_init(switch_core_session *session) assert(channel != NULL); tech_pvt->read_frame.data = tech_pvt->databuf; - + tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf); iax_set_private(tech_pvt->iax_session, tech_pvt); switch_set_flag(tech_pvt, TFLAG_IO); @@ -631,7 +631,6 @@ static switch_status channel_write_frame(switch_core_session *session, switch_fr if (switch_test_flag(tech_pvt, TFLAG_LINEAR)) { switch_swap_linear(frame->data, (int)frame->datalen / 2); } - iax_send_voice(tech_pvt->iax_session, tech_pvt->codec, frame->data, (int)frame->datalen, tech_pvt->write_codec.implementation->samples_per_frame); return SWITCH_STATUS_SUCCESS; diff --git a/src/mod/mod_playback/mod_playback.c b/src/mod/mod_playback/mod_playback.c index b5220043e8..02dc03b793 100644 --- a/src/mod/mod_playback/mod_playback.c +++ b/src/mod/mod_playback/mod_playback.c @@ -58,7 +58,7 @@ void playback_function(switch_core_session *session, char *data) switch_channel_answer(channel); write_frame.data = buf; - + write_frame.buflen = sizeof(buf); if (switch_file_open(&fd, data, SWITCH_FOPEN_READ, SWITCH_FPROT_UREAD, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "OPEN FILE FAILED\n"); diff --git a/src/mod/mod_portaudio/mod_portaudio.c b/src/mod/mod_portaudio/mod_portaudio.c index da0eb4cf16..d659305949 100644 --- a/src/mod/mod_portaudio/mod_portaudio.c +++ b/src/mod/mod_portaudio/mod_portaudio.c @@ -129,6 +129,7 @@ static switch_status channel_on_init(switch_core_session *session) assert(channel != NULL); tech_pvt->read_frame.data = tech_pvt->databuf; + tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf); switch_set_flag(tech_pvt, TFLAG_IO); @@ -361,6 +362,7 @@ static switch_status channel_write_frame(switch_core_session *session, switch_fr } */ + WriteAudioStream(tech_pvt->audio_out, (short *)frame->data, (int)(frame->datalen / sizeof(SAMPLE))); //XXX send voice diff --git a/src/switch_core.c b/src/switch_core.c index a4197a0b67..0a62a795c9 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -523,6 +523,7 @@ SWITCH_DECLARE(switch_status) switch_core_session_read_frame(switch_core_session if (read_frame->codec) { size_t flag = 0; + session->raw_read_frame.datalen = session->raw_read_frame.buflen; status = switch_core_codec_decode(read_frame->codec, session->read_codec, read_frame->data, @@ -549,7 +550,7 @@ SWITCH_DECLARE(switch_status) switch_core_session_read_frame(switch_core_session if ((*frame)->datalen == session->read_codec->implementation->bytes_per_frame) { perfect = TRUE; } else { - if (! session->raw_write_buffer) { + if (! session->raw_read_buffer) { int bytes = session->read_codec->implementation->bytes_per_frame * 10; switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Engaging Read Buffer at %d bytes\n", bytes); switch_buffer_create(session->pool, &session->raw_read_buffer, bytes); @@ -570,7 +571,7 @@ SWITCH_DECLARE(switch_status) switch_core_session_read_frame(switch_core_session session->read_codec->implementation->bytes_per_frame); enc_frame = &session->raw_read_frame; } - + session->enc_read_frame.datalen = session->enc_read_frame.buflen; status = switch_core_codec_encode(session->read_codec, (*frame)->codec, session->raw_read_frame.data, @@ -641,6 +642,8 @@ SWITCH_DECLARE(switch_status) switch_core_session_write_frame(switch_core_sessio if (need_codec) { if (frame->codec) { + + session->raw_write_frame.datalen = session->raw_write_frame.buflen; status = switch_core_codec_decode(frame->codec, session->write_codec, frame->data, @@ -687,6 +690,7 @@ SWITCH_DECLARE(switch_status) switch_core_session_write_frame(switch_core_sessio if (perfect) { enc_frame = write_frame; + session->enc_write_frame.datalen = session->enc_write_frame.buflen; status = switch_core_codec_encode(session->write_codec, frame->codec, enc_frame->data, @@ -728,6 +732,7 @@ SWITCH_DECLARE(switch_status) switch_core_session_write_frame(switch_core_sessio bytes))) { enc_frame = &session->raw_write_frame; + session->enc_write_frame.datalen = session->enc_write_frame.buflen; status = switch_core_codec_encode(session->write_codec, frame->codec, enc_frame->data, @@ -1447,10 +1452,15 @@ SWITCH_DECLARE(switch_core_session *) switch_core_session_request(const switch_e session->endpoint_interface = endpoint_interface; session->raw_write_frame.data = session->raw_write_buf; + session->raw_write_frame.buflen = sizeof(session->raw_write_buf); session->raw_read_frame.data = session->raw_read_buf; + session->raw_read_frame.buflen = sizeof(session->raw_read_buf); + session->enc_write_frame.data = session->enc_write_buf; + session->enc_write_frame.buflen = sizeof(session->enc_write_buf); session->enc_read_frame.data = session->enc_read_buf; + session->enc_read_frame.buflen = sizeof(session->enc_read_buf); switch_mutex_init(&session->mutex, SWITCH_MUTEX_NESTED ,session->pool); switch_thread_cond_create(&session->cond, session->pool);