From ded7fa6c6fc1716f24cb7a33ccaceb782c0450a2 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 29 Aug 2006 21:07:24 +0000 Subject: [PATCH] g726 work git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@2432 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/mod/codecs/mod_g726/mod_g726.c | 32 ++++++++++------- src/mod/endpoints/mod_sofia/mod_sofia.c | 48 ++++++++++++++++--------- 2 files changed, 52 insertions(+), 28 deletions(-) diff --git a/src/mod/codecs/mod_g726/mod_g726.c b/src/mod/codecs/mod_g726/mod_g726.c index 945419be29..98f51fa9c1 100644 --- a/src/mod/codecs/mod_g726/mod_g726.c +++ b/src/mod/codecs/mod_g726/mod_g726.c @@ -34,20 +34,27 @@ static const char modname[] = "mod_g726"; +typedef struct { + g726_state context; + uint8_t flag; + uint8_t bytes; +} 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; - g726_state *context = NULL; + g726_handle_t *handle; encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); decoding = (flags & SWITCH_CODEC_FLAG_DECODE); - if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(g726_state))))) { + if (!(encoding || decoding) || (!(handle = switch_core_alloc(codec->memory_pool, sizeof(*handle))))) { return SWITCH_STATUS_FALSE; } else { - g726_init_state(context); - codec->private_info = context; + g726_init_state(&handle->context); + codec->private_info = handle; + handle->bytes = codec->implementation->encoded_bytes_per_frame / (codec->implementation->microseconds_per_frame / 1000); return SWITCH_STATUS_SUCCESS; } } @@ -75,7 +82,8 @@ static switch_status_t switch_g726_encode(switch_codec_t *codec, unsigned int *flag) { - g726_state *context = codec->private_info; + 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; @@ -112,17 +120,17 @@ static switch_status_t switch_g726_encode(switch_codec_t *codec, uint32_t loops = decoded_data_len / (sizeof(*ddp)); for (x = 0; x < loops && new_len < *encoded_data_len; x++) { - int sample = encoder(*ddp, AUDIO_ENCODING_LINEAR, context); - *edp = sample; - edp++; - + if (handle->flag & 0x80) { + edp[new_len++] = ((handle->flag & 0xf) << handle->bytes) | encoder(*ddp, AUDIO_ENCODING_LINEAR, context); + handle->flag = 0; + } else { + handle->flag = 0x80 | encoder(*ddp, AUDIO_ENCODING_LINEAR, context); + } ddp++; - new_len++; } if (new_len <= *encoded_data_len) { - printf("encode %d->%d %d\n", decoded_data_len, elen, new_len / 2); - *encoded_data_len = new_len / 2; + *encoded_data_len = new_len; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "buffer overflow!!! %u >= %u\n", new_len, *encoded_data_len); return SWITCH_STATUS_FALSE; diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 2b00614374..33ef0f386b 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -590,27 +590,17 @@ static void deactivate_rtp(private_object_t *tech_pvt) } } - - - -static switch_status_t activate_rtp(private_object_t *tech_pvt) +static switch_status_t tech_set_codec(private_object_t *tech_pvt) { - int bw, ms; switch_channel_t *channel; - const char *err = NULL; - switch_rtp_flag_t flags; - - assert(tech_pvt != NULL); - - channel = switch_core_session_get_channel(tech_pvt->session); - assert(channel != NULL); - assert(tech_pvt->codecs[tech_pvt->codec_index] != NULL); - if (switch_rtp_ready(tech_pvt->rtp_session)) { + if (tech_pvt->read_codec.implementation) { return SWITCH_STATUS_SUCCESS; } + channel = switch_core_session_get_channel(tech_pvt->session); + assert(channel != NULL); if (switch_core_codec_init(&tech_pvt->read_codec, tech_pvt->rm_encoding, @@ -648,7 +638,31 @@ static switch_status_t activate_rtp(private_object_t *tech_pvt) switch_core_session_set_write_codec(tech_pvt->session, &tech_pvt->write_codec); } } + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t activate_rtp(private_object_t *tech_pvt) +{ + int bw, ms; + switch_channel_t *channel; + const char *err = NULL; + switch_rtp_flag_t flags; + switch_status_t status; + + assert(tech_pvt != NULL); + + channel = switch_core_session_get_channel(tech_pvt->session); + assert(channel != NULL); + + + if (switch_rtp_ready(tech_pvt->rtp_session)) { + return SWITCH_STATUS_SUCCESS; + } + + if ((status = tech_set_codec(tech_pvt)) != SWITCH_STATUS_SUCCESS) { + return status; + } bw = tech_pvt->read_codec.implementation->bits_per_second; ms = tech_pvt->read_codec.implementation->microseconds_per_frame; @@ -993,7 +1007,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); - + if (!switch_test_flag(tech_pvt, TFLAG_EARLY_MEDIA)) { switch_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Asked to send early media by %s\n", msg->from); @@ -1006,7 +1020,6 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi nua_respond(tech_pvt->nh, SIP_183_SESSION_PROGRESS, //SIPTAG_CONTACT(tech_pvt->contact), SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str), TAG_END()); - //nua_respond(tech_pvt->nh, SIP_200_OK, SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str), TAG_END()); } } break; @@ -1157,6 +1170,9 @@ static uint8_t negotiate_sdp(switch_core_session_t *session, sdp_session_t *sdp) } if (match) { + if (tech_set_codec(tech_pvt) != SWITCH_STATUS_SUCCESS) { + match = 0; + } break; } }