Author: anthm Date: Sun Oct 8 22:24:43 2006 New Revision: 3006 Modified: freeswitch/trunk/src/include/switch_core.h freeswitch/trunk/src/include/switch_module_interfaces.h freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c freeswitch/trunk/src/mod/applications/mod_rss/mod_rss.c freeswitch/trunk/src/mod/codecs/mod_g711/mod_g711.c freeswitch/trunk/src/mod/codecs/mod_g722/mod_g722.c freeswitch/trunk/src/mod/codecs/mod_g723_1/mod_g723_1.c freeswitch/trunk/src/mod/codecs/mod_g726/mod_g726.c freeswitch/trunk/src/mod/codecs/mod_g729/mod_g729.c freeswitch/trunk/src/mod/codecs/mod_gsm/mod_gsm.c freeswitch/trunk/src/mod/codecs/mod_ilbc/mod_ilbc.c freeswitch/trunk/src/mod/codecs/mod_l16/mod_l16.c freeswitch/trunk/src/mod/codecs/mod_lpc10/mod_lpc10.c freeswitch/trunk/src/mod/codecs/mod_speex/mod_speex.c freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c freeswitch/trunk/src/mod/endpoints/mod_iax/mod_iax.c freeswitch/trunk/src/mod/endpoints/mod_portaudio/mod_portaudio.c freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c freeswitch/trunk/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c freeswitch/trunk/src/mod/endpoints/mod_woomera/mod_woomera.c freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c freeswitch/trunk/src/switch_core.c freeswitch/trunk/src/switch_ivr.c freeswitch/trunk/src/switch_rtp.c Log: refine code Modified: freeswitch/trunk/src/include/switch_core.h ============================================================================== --- freeswitch/trunk/src/include/switch_core.h (original) +++ freeswitch/trunk/src/include/switch_core.h Sun Oct 8 22:24:43 2006 @@ -832,13 +832,14 @@ \return SWITCH_STATUS_SUCCESS if the handle is allocated */ SWITCH_DECLARE(switch_status_t) switch_core_codec_init(switch_codec_t *codec, - char *codec_name, - uint32_t rate, - int ms, - int channels, - uint32_t flags, - const switch_codec_settings_t *codec_settings, - switch_memory_pool_t *pool); + char *codec_name, + char *fmtp, + uint32_t rate, + int ms, + int channels, + uint32_t flags, + const switch_codec_settings_t *codec_settings, + switch_memory_pool_t *pool); /*! \brief Encode data using a codec handle Modified: freeswitch/trunk/src/include/switch_module_interfaces.h ============================================================================== --- freeswitch/trunk/src/include/switch_module_interfaces.h (original) +++ freeswitch/trunk/src/include/switch_module_interfaces.h Sun Oct 8 22:24:43 2006 @@ -442,6 +442,10 @@ const switch_codec_interface_t *codec_interface; /*! the specific implementation of the above codec */ const switch_codec_implementation_t *implementation; + /*! fmtp line from remote sdp */ + char *fmtp_in; + /*! fmtp line for local sdp */ + char *fmtp_out; /*! codec settings for this handle */ switch_codec_settings_t codec_settings; /*! flags to modify behaviour */ @@ -460,6 +464,8 @@ switch_payload_t ianacode; /*! the IANA code name */ char *iananame; + /*! default fmtp to send (can be overridden by the init function) */ + char *fmtp; /*! samples transferred per second */ uint32_t samples_per_second; /*! bits transferred per second */ Modified: freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c ============================================================================== --- freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c (original) +++ freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c Sun Oct 8 22:24:43 2006 @@ -2343,6 +2343,7 @@ /* Setup a Signed Linear codec for reading audio. */ if (switch_core_codec_init(&member.read_codec, "L16", + NULL, //conference->rate, read_codec->implementation->samples_per_second, //conference->interval, @@ -2380,6 +2381,7 @@ /* Setup a Signed Linear codec for writing audio. */ if (switch_core_codec_init(&member.write_codec, "L16", + NULL, conference->rate, //read_codec->implementation->samples_per_second, conference->interval, Modified: freeswitch/trunk/src/mod/applications/mod_rss/mod_rss.c ============================================================================== --- freeswitch/trunk/src/mod/applications/mod_rss/mod_rss.c (original) +++ freeswitch/trunk/src/mod/applications/mod_rss/mod_rss.c Sun Oct 8 22:24:43 2006 @@ -255,6 +255,7 @@ if (switch_core_codec_init(&speech_codec, "L16", + NULL, (int)rate, interval, 1, Modified: freeswitch/trunk/src/mod/codecs/mod_g711/mod_g711.c ============================================================================== --- freeswitch/trunk/src/mod/codecs/mod_g711/mod_g711.c (original) +++ freeswitch/trunk/src/mod/codecs/mod_g711/mod_g711.c Sun Oct 8 22:24:43 2006 @@ -193,6 +193,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 0, /*.iananame */ "PCMU", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ 19200, /*.microseconds_per_frame */ 60000, @@ -213,6 +214,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 0, /*.iananame */ "PCMU", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ 96000, /*.microseconds_per_frame */ 30000, @@ -233,6 +235,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 0, /*.iananame */ "PCMU", + /*.fmtp */ NULL, /*.samples_per_second */ 16000, /*.bits_per_second */ 128000, /*.microseconds_per_frame */ 20000, @@ -254,6 +257,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 0, /*.iananame */ "PCMU", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ 64000, /*.microseconds_per_frame */ 20000, @@ -276,6 +280,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 8, /*.iananame */ "PCMA", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ 64000, /*.microseconds_per_frame */ 20000, Modified: freeswitch/trunk/src/mod/codecs/mod_g722/mod_g722.c ============================================================================== --- freeswitch/trunk/src/mod/codecs/mod_g722/mod_g722.c (original) +++ freeswitch/trunk/src/mod/codecs/mod_g722/mod_g722.c Sun Oct 8 22:24:43 2006 @@ -125,6 +125,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 9, /*.iananame */ "G722", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ 64000, /*.microseconds_per_frame */ 20000, @@ -144,6 +145,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 9, /*.iananame */ "G722", + /*.fmtp */ NULL, /*.samples_per_second */ 16000, /*.bits_per_second */ 64000, /*.microseconds_per_frame */ 20000, Modified: freeswitch/trunk/src/mod/codecs/mod_g723_1/mod_g723_1.c ============================================================================== --- freeswitch/trunk/src/mod/codecs/mod_g723_1/mod_g723_1.c (original) +++ freeswitch/trunk/src/mod/codecs/mod_g723_1/mod_g723_1.c Sun Oct 8 22:24:43 2006 @@ -183,6 +183,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 4, /*.iananame */ "G723", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ 6300, /*.microseconds_per_frame */ 30000, Modified: freeswitch/trunk/src/mod/codecs/mod_g726/mod_g726.c ============================================================================== --- freeswitch/trunk/src/mod/codecs/mod_g726/mod_g726.c (original) +++ freeswitch/trunk/src/mod/codecs/mod_g726/mod_g726.c Sun Oct 8 22:24:43 2006 @@ -219,6 +219,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 127, /*.iananame */ "G726-16", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ 16000, /*.microseconds_per_frame */ 20000, @@ -239,6 +240,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 126, /*.iananame */ "G726-24", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ 24000, /*.microseconds_per_frame */ 20000, @@ -258,6 +260,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 2, /*.iananame */ "G726-32", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ 32000, /*.microseconds_per_frame */ 20000, @@ -277,6 +280,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 125, /*.iananame */ "G726-40", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ 40000, /*.microseconds_per_frame */ 20000, @@ -298,6 +302,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 124, /*.iananame */ "AAL2-G726-16", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ 16000, /*.microseconds_per_frame */ 20000, @@ -318,6 +323,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 123, /*.iananame */ "AAL2-G726-24", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ 24000, /*.microseconds_per_frame */ 20000, @@ -337,6 +343,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 2, /*.iananame */ "AAL2-G726-32", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ 32000, /*.microseconds_per_frame */ 20000, @@ -356,6 +363,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 122, /*.iananame */ "AAL2-G726-40", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ 40000, /*.microseconds_per_frame */ 20000, Modified: freeswitch/trunk/src/mod/codecs/mod_g729/mod_g729.c ============================================================================== --- freeswitch/trunk/src/mod/codecs/mod_g729/mod_g729.c (original) +++ freeswitch/trunk/src/mod/codecs/mod_g729/mod_g729.c Sun Oct 8 22:24:43 2006 @@ -222,6 +222,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 18, /*.iananame */ "G729", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ 32000, /*.microseconds_per_frame */ 10000, @@ -241,6 +242,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 18, /*.iananame */ "G729", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ 64000, /*.microseconds_per_frame */ 20000, Modified: freeswitch/trunk/src/mod/codecs/mod_gsm/mod_gsm.c ============================================================================== --- freeswitch/trunk/src/mod/codecs/mod_gsm/mod_gsm.c (original) +++ freeswitch/trunk/src/mod/codecs/mod_gsm/mod_gsm.c Sun Oct 8 22:24:43 2006 @@ -136,6 +136,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 3, /*.iananame */ "gsm", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ 13200, /*.microseconds_per_frame */ 20000, Modified: freeswitch/trunk/src/mod/codecs/mod_ilbc/mod_ilbc.c ============================================================================== --- freeswitch/trunk/src/mod/codecs/mod_ilbc/mod_ilbc.c (original) +++ freeswitch/trunk/src/mod/codecs/mod_ilbc/mod_ilbc.c Sun Oct 8 22:24:43 2006 @@ -189,6 +189,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 97, /*.iananame */ "iLBC", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ NO_OF_BYTES_30MS*8*8000/BLOCKL_30MS, /*.microseconds_per_frame */ 30000, @@ -208,6 +209,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 97, /*.iananame */ "iLBC", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ NO_OF_BYTES_20MS*8*8000/BLOCKL_20MS, /*.microseconds_per_frame */ 20000, @@ -230,6 +232,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 102, /*.iananame */ "iLBC", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ NO_OF_BYTES_30MS*8*8000/BLOCKL_30MS, /*.microseconds_per_frame */ 30000, @@ -249,6 +252,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 102, /*.iananame */ "iLBC102", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ NO_OF_BYTES_20MS*8*8000/BLOCKL_20MS, /*.microseconds_per_frame */ 20000, @@ -270,6 +274,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 97, /*.iananame */ "iLBC20ms", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ NO_OF_BYTES_20MS*8*8000/BLOCKL_20MS, /*.microseconds_per_frame */ 20000, Modified: freeswitch/trunk/src/mod/codecs/mod_l16/mod_l16.c ============================================================================== --- freeswitch/trunk/src/mod/codecs/mod_l16/mod_l16.c (original) +++ freeswitch/trunk/src/mod/codecs/mod_l16/mod_l16.c Sun Oct 8 22:24:43 2006 @@ -93,6 +93,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 10, /*.iananame */ "L16", + /*.fmtp */ NULL, /*.samples_per_second = */ 32000, /*.bits_per_second = */ 512000, /*.microseconds_per_frame = */ 20000, @@ -112,6 +113,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 10, /*.iananame */ "L16", + /*.fmtp */ NULL, /*.samples_per_second = */ 22050, /*.bits_per_second = */ 352800, /*.microseconds_per_frame = */ 20000, @@ -132,6 +134,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 10, /*.iananame */ "L16", + /*.fmtp */ NULL, /*.samples_per_second = */ 16000, /*.bits_per_second = */ 256000, /*.microseconds_per_frame = */ 20000, @@ -152,6 +155,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 10, /*.iananame */ "L16", + /*.fmtp */ NULL, /*.samples_per_second = */ 8000, /*.bits_per_second = */ 128000, /*.microseconds_per_frame = */ 20000, @@ -173,6 +177,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 10, /*.iananame */ "L16", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ 128000, /*.microseconds_per_frame */ 30000, @@ -194,6 +199,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 10, /*.iananame */ "L16", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ 256000, /*.microseconds_per_frame */ 60000, @@ -214,6 +220,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 10, /*.iananame */ "L16", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ 512000, /*.microseconds_per_frame */ 120000, Modified: freeswitch/trunk/src/mod/codecs/mod_lpc10/mod_lpc10.c ============================================================================== --- freeswitch/trunk/src/mod/codecs/mod_lpc10/mod_lpc10.c (original) +++ freeswitch/trunk/src/mod/codecs/mod_lpc10/mod_lpc10.c Sun Oct 8 22:24:43 2006 @@ -171,6 +171,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 7, /*.iananame */ "LPC", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ 240, /*.microseconds_per_frame */ 22500, Modified: freeswitch/trunk/src/mod/codecs/mod_speex/mod_speex.c ============================================================================== --- freeswitch/trunk/src/mod/codecs/mod_speex/mod_speex.c (original) +++ freeswitch/trunk/src/mod/codecs/mod_speex/mod_speex.c Sun Oct 8 22:24:43 2006 @@ -271,6 +271,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 102, /*.iananame */ "speex", + /*.fmtp */ NULL, /*.samples_per_second */ 32000, /*.bits_per_second */ 256000, /*.nanoseconds_per_frame */ 20000, @@ -290,6 +291,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 99, /*.iananame */ "speex", + /*.fmtp */ NULL, /*.samples_per_second */ 16000, /*.bits_per_second */ 22000, /*.nanoseconds_per_frame */ 20000, @@ -310,6 +312,7 @@ /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 98, /*.iananame */ "speex", + /*.fmtp */ NULL, /*.samples_per_second */ 8000, /*.bits_per_second */ 11000, /*.nanoseconds_per_frame */ 20000, Modified: freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c ============================================================================== --- freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c (original) +++ freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c Sun Oct 8 22:24:43 2006 @@ -304,6 +304,7 @@ if (switch_core_codec_init(&tech_pvt->read_codec, tech_pvt->codec_name, + NULL, tech_pvt->codec_rate, ms, 1, @@ -321,6 +322,7 @@ if (switch_core_codec_init(&tech_pvt->write_codec, tech_pvt->codec_name, + NULL, tech_pvt->codec_rate, ms, 1, @@ -1735,7 +1737,7 @@ name = "ilbc"; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "compare %s %d to %s %d\n", payloads[x].name, payloads[x].id, name, tech_pvt->codecs[y]->ianacode); - if (tech_pvt->codecs[y]->ianacode > 96) { + if (tech_pvt->codecs[y]->ianacode > 95) { match = strcasecmp(name, payloads[x].name) ? 0 : 1; } else { match = (payloads[x].id == tech_pvt->codecs[y]->ianacode) ? 1 : 0; Modified: freeswitch/trunk/src/mod/endpoints/mod_iax/mod_iax.c ============================================================================== --- freeswitch/trunk/src/mod/endpoints/mod_iax/mod_iax.c (original) +++ freeswitch/trunk/src/mod/endpoints/mod_iax/mod_iax.c Sun Oct 8 22:24:43 2006 @@ -373,6 +373,7 @@ } if (switch_core_codec_init(&tech_pvt->read_codec, dname, + NULL, srate, interval, 1, @@ -383,6 +384,7 @@ } else { if (switch_core_codec_init(&tech_pvt->write_codec, dname, + NULL, srate, interval, 1, Modified: freeswitch/trunk/src/mod/endpoints/mod_portaudio/mod_portaudio.c ============================================================================== --- freeswitch/trunk/src/mod/endpoints/mod_portaudio/mod_portaudio.c (original) +++ freeswitch/trunk/src/mod/endpoints/mod_portaudio/mod_portaudio.c Sun Oct 8 22:24:43 2006 @@ -768,6 +768,7 @@ if (switch_core_codec_init(&tech_pvt->read_codec, "L16", + NULL, sample_rate, codec_ms, 1, @@ -778,6 +779,7 @@ } else { if (switch_core_codec_init(&tech_pvt->write_codec, "L16", + NULL, sample_rate, codec_ms, 1, Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c ============================================================================== --- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (original) +++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c Sun Oct 8 22:24:43 2006 @@ -250,6 +250,8 @@ char *contact_url; char *from_str; char *rm_encoding; + char *rm_fmtp; + char *fmtp_out; char *remote_sdp_str; char *local_sdp_str; char *dest; @@ -632,7 +634,7 @@ } } - if (tech_pvt->te > 96) { + if (tech_pvt->te > 95) { snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %d", tech_pvt->te); } @@ -640,16 +642,26 @@ if (tech_pvt->rm_encoding) { snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=rtpmap:%d %s/%ld\n", tech_pvt->pt, tech_pvt->rm_encoding, tech_pvt->rm_rate); + if (tech_pvt->fmtp_out) { + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=fmtp:%d %s\n", tech_pvt->pt, tech_pvt->fmtp_out); + } + if (tech_pvt->read_codec.implementation) { + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=ptime:%d\n", tech_pvt->read_codec.implementation->microseconds_per_frame / 1000); + } + } else if (tech_pvt->num_codecs) { int i; for (i = 0; i < tech_pvt->num_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); + if (imp->fmtp) { + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=fmtp:%d %s\n", imp->ianacode, imp->fmtp); + } snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=ptime:%d\n", imp->microseconds_per_frame / 1000); } } - if (tech_pvt->te > 96) { + if (tech_pvt->te > 95) { snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=rtpmap:%d telephone-event/8000\na=fmtp:%d 0-16\n", tech_pvt->te, tech_pvt->te); } @@ -1126,6 +1138,7 @@ if (switch_core_codec_init(&tech_pvt->read_codec, tech_pvt->rm_encoding, + tech_pvt->rm_fmtp, tech_pvt->rm_rate, tech_pvt->codec_ms, 1, @@ -1138,6 +1151,7 @@ } else { if (switch_core_codec_init(&tech_pvt->write_codec, tech_pvt->rm_encoding, + tech_pvt->rm_fmtp, tech_pvt->rm_rate, tech_pvt->codec_ms, 1, @@ -1158,6 +1172,7 @@ switch_core_session_set_read_codec(tech_pvt->session, &tech_pvt->read_codec); switch_core_session_set_write_codec(tech_pvt->session, &tech_pvt->write_codec); + tech_pvt->fmtp_out = switch_core_session_strdup(tech_pvt->session, tech_pvt->write_codec.fmtp_out); } } return SWITCH_STATUS_SUCCESS; @@ -1771,8 +1786,9 @@ for (i = 0; i < tech_pvt->num_codecs; i++) { const switch_codec_implementation_t *imp = tech_pvt->codecs[i]; - - if (map->rm_pt < 97) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Codec Compare [%s:%d]/[%s:%d]\n", + map->rm_encoding, map->rm_pt, imp->iananame, imp->ianacode); + if (map->rm_pt < 96) { match = (map->rm_pt == imp->ianacode) ? 1 : 0; } else { match = strcasecmp(map->rm_encoding, imp->iananame) ? 0 : 1; @@ -1784,6 +1800,7 @@ tech_pvt->rm_rate = map->rm_rate; tech_pvt->codec_ms = imp->microseconds_per_frame / 1000; tech_pvt->remote_sdp_audio_ip = switch_core_session_strdup(session, (char *)sdp->sdp_connection->c_address); + tech_pvt->rm_fmtp = switch_core_session_strdup(session, (char *)map->rm_fmtp); tech_pvt->remote_sdp_audio_port = (switch_port_t)m->m_port; break; } else { @@ -1872,6 +1889,9 @@ private_object_t *tech_pvt = NULL; switch_core_session_t *session = sofia_private ? sofia_private->session : NULL; const char *replaces_str; + char *uuid; + switch_core_session_t *other_session = NULL; + switch_channel_t *other_channel = NULL; tl_gets(tags, NUTAG_CALLSTATE_REF(ss_state), @@ -1917,6 +1937,12 @@ if (r_sdp) { if (switch_test_flag(tech_pvt, TFLAG_NOMEDIA)) { switch_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA); + switch_channel_set_flag(channel, CF_EARLY_MEDIA); + if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE)) && (other_session = switch_core_session_locate(uuid))) { + other_channel = switch_core_session_get_channel(other_session); + switch_channel_pre_answer(other_channel); + switch_core_session_rwunlock(other_session); + } return; } else { sdp_parser_t *parser = sdp_parse(tech_pvt->home, r_sdp, (int)strlen(r_sdp), 0); @@ -1933,12 +1959,12 @@ sdp_parser_free(parser); } - if (match) { tech_choose_port(tech_pvt); activate_rtp(tech_pvt); switch_channel_set_variable(channel, "endpoint_disposition", "EARLY MEDIA"); switch_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA); + switch_channel_set_flag(channel, CF_EARLY_MEDIA); return; } switch_channel_set_variable(channel, "endpoint_disposition", "NO CODECS"); @@ -1983,7 +2009,7 @@ switch_channel_set_state(channel, CS_INIT); switch_set_flag_locked(tech_pvt, TFLAG_READY); switch_core_session_thread_launch(session); - + if (replaces_str && (replaces = sip_replaces_make(tech_pvt->home, replaces_str)) && (bnh = nua_handle_by_replaces(nua, replaces))) { sofia_private_t *b_private; @@ -2068,6 +2094,11 @@ if (switch_test_flag(tech_pvt, TFLAG_NOMEDIA)) { switch_set_flag_locked(tech_pvt, TFLAG_ANS); switch_channel_set_flag(channel, CF_ANSWERED); + if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE)) && (other_session = switch_core_session_locate(uuid))) { + other_channel = switch_core_session_get_channel(other_session); + switch_channel_answer(other_channel); + switch_core_session_rwunlock(other_session); + } return; } else { sdp_parser_t *parser = sdp_parse(tech_pvt->home, r_sdp, (int)strlen(r_sdp), 0); Modified: freeswitch/trunk/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c ============================================================================== --- freeswitch/trunk/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c (original) +++ freeswitch/trunk/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c Sun Oct 8 22:24:43 2006 @@ -346,7 +346,7 @@ } if (switch_core_codec_init - (&tech_pvt->read_codec, "L16", rate, 20, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, + (&tech_pvt->read_codec, "L16", NULL, rate, 20, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s Cannot set read codec\n", switch_channel_get_name(channel)); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); @@ -354,7 +354,7 @@ } if (switch_core_codec_init - (&tech_pvt->write_codec, "L16", rate, 20, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, + (&tech_pvt->write_codec, "L16", NULL, rate, 20, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s Cannot set read codec\n", switch_channel_get_name(channel)); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); Modified: freeswitch/trunk/src/mod/endpoints/mod_woomera/mod_woomera.c ============================================================================== --- freeswitch/trunk/src/mod/endpoints/mod_woomera/mod_woomera.c (original) +++ freeswitch/trunk/src/mod/endpoints/mod_woomera/mod_woomera.c Sun Oct 8 22:24:43 2006 @@ -211,7 +211,7 @@ tech_pvt->frame.data = tech_pvt->databuf; if (switch_core_codec_init - (&tech_pvt->read_codec, "L16", rate, 30, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, + (&tech_pvt->read_codec, "L16", NULL, rate, 30, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s Cannot set read codec\n", switch_channel_get_name(channel)); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); @@ -219,7 +219,7 @@ } if (switch_core_codec_init - (&tech_pvt->write_codec, "L16", rate, 30, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, + (&tech_pvt->write_codec, "L16", NULL, rate, 30, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s Cannot set read codec\n", switch_channel_get_name(channel)); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); Modified: freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c ============================================================================== --- freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c (original) +++ freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c Sun Oct 8 22:24:43 2006 @@ -1985,6 +1985,7 @@ if (switch_core_codec_init(&tto->codec, "L16", + NULL, read_codec->implementation->samples_per_second, read_codec->implementation->microseconds_per_frame / 1000, read_codec->implementation->number_of_channels, Modified: freeswitch/trunk/src/switch_core.c ============================================================================== --- freeswitch/trunk/src/switch_core.c (original) +++ freeswitch/trunk/src/switch_core.c Sun Oct 8 22:24:43 2006 @@ -652,7 +652,7 @@ return session->write_codec; } -SWITCH_DECLARE(switch_status_t) switch_core_codec_init(switch_codec_t *codec, char *codec_name, uint32_t rate, int ms, +SWITCH_DECLARE(switch_status_t) switch_core_codec_init(switch_codec_t *codec, char *codec_name, char *fmtp, uint32_t rate, int ms, int channels, uint32_t flags, const switch_codec_settings_t *codec_settings, switch_memory_pool_t *pool) @@ -684,7 +684,7 @@ codec->codec_interface = codec_interface; codec->implementation = implementation; codec->flags = flags; - + if (pool) { codec->memory_pool = pool; } else { @@ -692,6 +692,10 @@ return status; } switch_set_flag(codec, SWITCH_CODEC_FLAG_FREE_POOL); + } + + if (fmtp) { + codec->fmtp_in = switch_core_strdup(codec->memory_pool, fmtp); } implementation->init(codec, flags, codec_settings); Modified: freeswitch/trunk/src/switch_ivr.c ============================================================================== --- freeswitch/trunk/src/switch_ivr.c (original) +++ freeswitch/trunk/src/switch_ivr.c Sun Oct 8 22:24:43 2006 @@ -378,6 +378,7 @@ codec_name = "L16"; if (switch_core_codec_init(&codec, codec_name, + NULL, read_codec->implementation->samples_per_second, read_codec->implementation->microseconds_per_frame / 1000, read_codec->implementation->number_of_channels, @@ -710,6 +711,7 @@ if (switch_core_codec_init(&codec, codec_name, + NULL, fh->samplerate, interval, fh->channels, @@ -1177,6 +1179,7 @@ if (switch_core_codec_init(&codec, codec_name, + NULL, (int)rate, interval, 1, @@ -1239,7 +1242,7 @@ { switch_core_thread_session_t *his_thread, *data = obj; int *stream_id_p; - int stream_id = 0, ans_a = 0, ans_b = 0; + int stream_id = 0, pre_b = 0, ans_a = 0, ans_b = 0, originator = 0; switch_input_callback_function_t input_callback; switch_core_session_message_t msg = {0}; void *user_data; @@ -1265,10 +1268,13 @@ chan_a = switch_core_session_get_channel(session_a); chan_b = switch_core_session_get_channel(session_b); - ans_a = switch_channel_test_flag(chan_a, CF_ANSWERED); - ans_b = switch_channel_test_flag(chan_b, CF_ANSWERED); + if ((originator = switch_channel_test_flag(chan_a, CF_ORIGINATOR))) { + pre_b = switch_channel_test_flag(chan_a, CF_EARLY_MEDIA); + ans_b = switch_channel_test_flag(chan_b, CF_ANSWERED); + } + switch_channel_set_flag(chan_a, CF_BRIDGED); while (switch_channel_ready(chan_a) && data->running > 0 && his_thread->running > 0) { @@ -1292,21 +1298,19 @@ } if (!switch_channel_test_flag(chan_a, CF_HOLD)) { - /* If this call is running on early media and it answers for real, pass it along... */ - if (!ans_b && switch_channel_test_flag(chan_a, CF_ANSWERED)) { - if (!switch_channel_test_flag(chan_b, CF_ANSWERED)) { - switch_channel_answer(chan_b); - } - ans_b++; - } - - if (!ans_a && switch_channel_test_flag(chan_b, CF_ANSWERED)) { - if (!switch_channel_test_flag(chan_a, CF_ANSWERED)) { + + if (!ans_a && originator) { + if (!ans_b && switch_channel_test_flag(chan_b, CF_ANSWERED)) { switch_channel_answer(chan_a); + ans_a++; + } else if (!pre_b && switch_channel_test_flag(chan_b, CF_EARLY_MEDIA)) { + switch_channel_pre_answer(chan_a); + pre_b++; } - ans_a++; + switch_yield(10000); + continue; } - + if (switch_core_session_dequeue_private_event(session_a, &event) == SWITCH_STATUS_SUCCESS) { switch_channel_set_flag(chan_b, CF_HOLD); switch_ivr_parse_event(session_a, event); @@ -1931,17 +1935,16 @@ } endfor1: - + if (session && !switch_channel_test_flag(caller_channel, CF_NOMEDIA)) { switch_codec_t *read_codec = NULL; - switch_channel_pre_answer(caller_channel); read_codec = switch_core_session_get_read_codec(session); - assert(read_codec != NULL); if (!(pass = (uint8_t)switch_test_flag(read_codec, SWITCH_CODEC_FLAG_PASSTHROUGH))) { if (switch_core_codec_init(&write_codec, "L16", + NULL, read_codec->implementation->samples_per_second, read_codec->implementation->microseconds_per_frame / 1000, 1, @@ -1965,6 +1968,7 @@ while ((!caller_channel || switch_channel_ready(caller_channel)) && check_channel_status(peer_channels, peer_sessions, and_argc, &idx, file, key) && ((time(NULL) - start) < (time_t)timelimit_sec)) { + /* read from the channel while we wait if the audio is up on it */ if (session && !switch_channel_test_flag(caller_channel, CF_NOMEDIA) && (switch_channel_test_flag(caller_channel, CF_ANSWERED) || switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA))) { @@ -2007,13 +2011,17 @@ goto done; } - if (caller_channel && switch_channel_test_flag(peer_channel, CF_ANSWERED)) { + if (caller_channel) { char *val; - if (switch_channel_test_flag(peer_channel, CF_NOMEDIA) && (val = switch_channel_get_variable(peer_channel, SWITCH_R_SDP_VARIABLE))) { switch_channel_set_variable(caller_channel, SWITCH_L_SDP_VARIABLE, val); } - switch_channel_answer(caller_channel); + + if (switch_channel_test_flag(peer_channel, CF_ANSWERED)) { + switch_channel_answer(caller_channel); + } else if (switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) { + switch_channel_pre_answer(caller_channel); + } } if (switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) { Modified: freeswitch/trunk/src/switch_rtp.c ============================================================================== --- freeswitch/trunk/src/switch_rtp.c (original) +++ freeswitch/trunk/src/switch_rtp.c Sun Oct 8 22:24:43 2006 @@ -1317,6 +1317,7 @@ if (switch_core_codec_init(&rtp_session->vad_data.vad_codec, codec->implementation->iananame, + NULL, codec->implementation->samples_per_second, codec->implementation->microseconds_per_frame / 1000, codec->implementation->number_of_channels,