From 89725b879f66d567431a9069cc6012be00c1788a Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Tue, 24 Apr 2012 13:09:14 +0000 Subject: Re #1474: merged r4054-r4079 git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4082 74dad513-b988-da41-8d7b-12977e46ad98 --- pjmedia/include/pjmedia/echo.h | 7 +- pjmedia/include/pjmedia/sound_port.h | 15 ++ pjmedia/src/pjmedia-audiodev/coreaudio_dev.c | 5 + pjmedia/src/pjmedia-codec/passthrough.c | 3 +- pjmedia/src/pjmedia/sound_port.c | 41 +++- pjsip-apps/src/pjsystest/systest.c | 9 +- pjsip/build/pjsip_core.vcproj | 352 --------------------------- pjsip/src/pjsip-simple/evsub.c | 18 +- pjsip/src/pjsip-ua/sip_inv.c | 2 +- pjsip/src/pjsua-lib/pjsua_call.c | 6 +- 10 files changed, 73 insertions(+), 385 deletions(-) diff --git a/pjmedia/include/pjmedia/echo.h b/pjmedia/include/pjmedia/echo.h index ba7f8897..4ed62ee9 100644 --- a/pjmedia/include/pjmedia/echo.h +++ b/pjmedia/include/pjmedia/echo.h @@ -95,8 +95,13 @@ typedef enum pjmedia_echo_flag * created for the echo canceller will use simple FIFO mechanism, i.e. * without using WSOLA to expand and shrink audio samples. */ - PJMEDIA_ECHO_USE_SIMPLE_FIFO = 32 + PJMEDIA_ECHO_USE_SIMPLE_FIFO = 32, + /** + * If PJMEDIA_ECHO_USE_SW_ECHO flag is specified, software echo canceller + * will be used instead of device EC. + */ + PJMEDIA_ECHO_USE_SW_ECHO = 64 } pjmedia_echo_flag; diff --git a/pjmedia/include/pjmedia/sound_port.h b/pjmedia/include/pjmedia/sound_port.h index 2bc98d4d..07d15c4a 100644 --- a/pjmedia/include/pjmedia/sound_port.h +++ b/pjmedia/include/pjmedia/sound_port.h @@ -76,6 +76,8 @@ enum pjmedia_snd_port_option /** * This structure specifies the parameters to create the sound port. + * Use pjmedia_snd_port_param_default() to initialize this structure with + * default values (mostly zeroes) */ typedef struct pjmedia_snd_port_param { @@ -88,8 +90,21 @@ typedef struct pjmedia_snd_port_param * Sound port creation options. */ unsigned options; + + /** + * Echo cancellation options/flags. + */ + unsigned ec_options; + } pjmedia_snd_port_param; +/** + * Initialize pjmedia_snd_port_param with default values. + * + * @param prm The parameter. + */ +PJ_DECL(void) pjmedia_snd_port_param_default(pjmedia_snd_port_param *prm); + /** * This opaque type describes sound device port connection. * Sound device port is not a media port, but it is used to connect media diff --git a/pjmedia/src/pjmedia-audiodev/coreaudio_dev.c b/pjmedia/src/pjmedia-audiodev/coreaudio_dev.c index c5a3e621..d0718979 100644 --- a/pjmedia/src/pjmedia-audiodev/coreaudio_dev.c +++ b/pjmedia/src/pjmedia-audiodev/coreaudio_dev.c @@ -1964,6 +1964,11 @@ static pj_status_t ca_stream_set_cap(pjmedia_aud_stream *s, strm->cf->io_comp = io_comp; strm->param.ec_enabled = *(pj_bool_t*)pval; + PJ_LOG(4, (THIS_FILE, "Using %s audio unit", + (desc.componentSubType == + kAudioUnitSubType_RemoteIO? "RemoteIO": + "VoiceProcessingIO"))); + return PJ_SUCCESS; } #endif diff --git a/pjmedia/src/pjmedia-codec/passthrough.c b/pjmedia/src/pjmedia-codec/passthrough.c index ef34bd19..c2f9f9a4 100644 --- a/pjmedia/src/pjmedia-codec/passthrough.c +++ b/pjmedia/src/pjmedia-codec/passthrough.c @@ -261,7 +261,8 @@ static pj_status_t pack_amr ( codec_private_t *codec_data, pj_bzero(info, sizeof(*info)); if (len == 0) { - info->frame_type = (pj_uint8_t)(enc_setting->amr_nb? 14 : 15); + /* DTX */ + info->frame_type = 15; } else { info->frame_type = pjmedia_codec_amr_get_mode2(enc_setting->amr_nb, len); diff --git a/pjmedia/src/pjmedia/sound_port.c b/pjmedia/src/pjmedia/sound_port.c index d99d3049..f42e5b51 100644 --- a/pjmedia/src/pjmedia/sound_port.c +++ b/pjmedia/src/pjmedia/sound_port.c @@ -52,6 +52,7 @@ struct pjmedia_snd_port unsigned samples_per_frame; unsigned bits_per_sample; unsigned options; + unsigned prm_ec_options; /* software ec */ pjmedia_echo_state *ec_state; @@ -187,6 +188,12 @@ static pj_status_t rec_cb_ext(void *user_data, pjmedia_frame *frame) return PJ_SUCCESS; } +/* Initialize with default values (zero) */ +PJ_DEF(void) pjmedia_snd_port_param_default(pjmedia_snd_port_param *prm) +{ + pj_bzero(prm, sizeof(*prm)); +} + /* * Start the sound stream. * This may be called even when the sound stream has already been started. @@ -226,11 +233,14 @@ static pj_status_t start_sound_device( pj_pool_t *pool, pj_memcpy(¶m_copy, &snd_port->aud_param, sizeof(param_copy)); if (param_copy.flags & PJMEDIA_AUD_DEV_CAP_EC) { /* EC is wanted */ - if (snd_port->aud_caps & PJMEDIA_AUD_DEV_CAP_EC) { + if ((snd_port->prm_ec_options & PJMEDIA_ECHO_USE_SW_ECHO) == 0 && + snd_port->aud_caps & PJMEDIA_AUD_DEV_CAP_EC) + { /* Device supports EC */ /* Nothing to do */ } else { - /* Device doesn't support EC, remove EC settings from + /* Application wants to use software EC or device + * doesn't support EC, remove EC settings from * device parameters */ param_copy.flags &= ~(PJMEDIA_AUD_DEV_CAP_EC | @@ -262,11 +272,13 @@ static pj_status_t start_sound_device( pj_pool_t *pool, (snd_port->clock_rate / snd_port->samples_per_frame); - /* Create software EC if parameter specifies EC but device - * doesn't support EC. Only do this if the format is PCM! + /* Create software EC if parameter specifies EC and + * (app specifically requests software EC or device + * doesn't support EC). Only do this if the format is PCM! */ if ((snd_port->aud_param.flags & PJMEDIA_AUD_DEV_CAP_EC) && - (snd_port->aud_caps & PJMEDIA_AUD_DEV_CAP_EC)==0 && + ((snd_port->aud_caps & PJMEDIA_AUD_DEV_CAP_EC)==0 || + (snd_port->prm_ec_options & PJMEDIA_ECHO_USE_SW_ECHO) != 0) && param_copy.ext_fmt.id == PJMEDIA_FORMAT_PCM) { if ((snd_port->aud_param.flags & PJMEDIA_AUD_DEV_CAP_EC_TAIL)==0) { @@ -277,7 +289,8 @@ static pj_status_t start_sound_device( pj_pool_t *pool, } status = pjmedia_snd_port_set_ec(snd_port, pool, - snd_port->aud_param.ec_tail_ms, 0); + snd_port->aud_param.ec_tail_ms, + snd_port->prm_ec_options); if (status != PJ_SUCCESS) { pjmedia_aud_stream_destroy(snd_port->aud_stream); snd_port->aud_stream = NULL; @@ -338,7 +351,7 @@ PJ_DEF(pj_status_t) pjmedia_snd_port_create( pj_pool_t *pool, pjmedia_snd_port_param param; pj_status_t status; - PJ_UNUSED_ARG(options); + pjmedia_snd_port_param_default(¶m); status = pjmedia_aud_dev_default_param(rec_id, ¶m.base); if (status != PJ_SUCCESS) @@ -352,6 +365,7 @@ PJ_DEF(pj_status_t) pjmedia_snd_port_create( pj_pool_t *pool, param.base.samples_per_frame = samples_per_frame; param.base.bits_per_sample = bits_per_sample; param.options = options; + param.ec_options = 0; return pjmedia_snd_port_create2(pool, ¶m, p_port); } @@ -371,7 +385,7 @@ PJ_DEF(pj_status_t) pjmedia_snd_port_create_rec( pj_pool_t *pool, pjmedia_snd_port_param param; pj_status_t status; - PJ_UNUSED_ARG(options); + pjmedia_snd_port_param_default(¶m); status = pjmedia_aud_dev_default_param(dev_id, ¶m.base); if (status != PJ_SUCCESS) @@ -384,6 +398,7 @@ PJ_DEF(pj_status_t) pjmedia_snd_port_create_rec( pj_pool_t *pool, param.base.samples_per_frame = samples_per_frame; param.base.bits_per_sample = bits_per_sample; param.options = options; + param.ec_options = 0; return pjmedia_snd_port_create2(pool, ¶m, p_port); } @@ -404,7 +419,7 @@ PJ_DEF(pj_status_t) pjmedia_snd_port_create_player( pj_pool_t *pool, pjmedia_snd_port_param param; pj_status_t status; - PJ_UNUSED_ARG(options); + pjmedia_snd_port_param_default(¶m); status = pjmedia_aud_dev_default_param(dev_id, ¶m.base); if (status != PJ_SUCCESS) @@ -417,6 +432,7 @@ PJ_DEF(pj_status_t) pjmedia_snd_port_create_player( pj_pool_t *pool, param.base.samples_per_frame = samples_per_frame; param.base.bits_per_sample = bits_per_sample; param.options = options; + param.ec_options = 0; return pjmedia_snd_port_create2(pool, ¶m, p_port); } @@ -445,8 +461,9 @@ PJ_DEF(pj_status_t) pjmedia_snd_port_create2(pj_pool_t *pool, snd_port->channel_count = prm->base.channel_count; snd_port->samples_per_frame = prm->base.samples_per_frame; snd_port->bits_per_sample = prm->base.bits_per_sample; - pj_memcpy(&snd_port->aud_param, prm, sizeof(snd_port->aud_param)); + pj_memcpy(&snd_port->aud_param, &prm->base, sizeof(snd_port->aud_param)); snd_port->options = prm->options; + snd_port->prm_ec_options = prm->ec_options; ptime_usec = prm->base.samples_per_frame * 1000 / prm->base.channel_count / prm->base.clock_rate * 1000; @@ -509,7 +526,9 @@ PJ_DEF(pj_status_t) pjmedia_snd_port_set_ec( pjmedia_snd_port *snd_port, PJ_EINVALIDOP); /* Determine whether we use device or software EC */ - if (snd_port->aud_caps & PJMEDIA_AUD_DEV_CAP_EC) { + if ((snd_port->prm_ec_options & PJMEDIA_ECHO_USE_SW_ECHO) == 0 && + snd_port->aud_caps & PJMEDIA_AUD_DEV_CAP_EC) + { /* We use device EC */ pj_bool_t ec_enabled; diff --git a/pjsip-apps/src/pjsystest/systest.c b/pjsip-apps/src/pjsystest/systest.c index 892deeff..0ee08b67 100644 --- a/pjsip-apps/src/pjsystest/systest.c +++ b/pjsip-apps/src/pjsystest/systest.c @@ -967,8 +967,9 @@ static void systest_aec_test(void) goto on_return; } - status = pjsua_recorder_create(pj_cstr(&tmp, AEC_REC_PATH), 0, 0, -1, - 0, &writer_id); + status = pjsua_recorder_create( + pj_cstr(&tmp, add_path(doc_path, AEC_REC_PATH)), 0, 0, -1, + 0, &writer_id); if (status != PJ_SUCCESS) { PJ_PERROR(1,(THIS_FILE, status, "Error writing WAV file %s", AEC_REC_PATH)); @@ -999,7 +1000,9 @@ static void systest_aec_test(void) /* * Play the result. */ - status = pjsua_player_create(pj_cstr(&tmp, AEC_REC_PATH), 0, &player_id); + status = pjsua_player_create( + pj_cstr(&tmp, add_path(doc_path, AEC_REC_PATH)), + 0, &player_id); if (status != PJ_SUCCESS) { PJ_PERROR(1,(THIS_FILE, status, "Error opening WAV file %s", AEC_REC_PATH)); goto on_return; diff --git a/pjsip/build/pjsip_core.vcproj b/pjsip/build/pjsip_core.vcproj index dff4e810..7239c888 100644 --- a/pjsip/build/pjsip_core.vcproj +++ b/pjsip/build/pjsip_core.vcproj @@ -3487,358 +3487,6 @@ RelativePath="..\src\pjsip\sip_transport_tls.c" > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pjsip/src/pjsip-simple/evsub.c b/pjsip/src/pjsip-simple/evsub.c index d61fe71d..372c5151 100644 --- a/pjsip/src/pjsip-simple/evsub.c +++ b/pjsip/src/pjsip-simple/evsub.c @@ -1818,7 +1818,6 @@ static void on_tsx_state_uac( pjsip_evsub *sub, pjsip_transaction *tsx, pjsip_tx_data *tdata; pj_status_t status; - int next_refresh; /* Only want to handle initial NOTIFY receive event. */ if (tsx->state != PJSIP_TSX_STATE_TRYING) @@ -1898,19 +1897,14 @@ static void on_tsx_state_uac( pjsip_evsub *sub, pjsip_transaction *tsx, (pj_stricmp(&sub_state->sub_state, &STR_ACTIVE)==0 || pj_stricmp(&sub_state->sub_state, &STR_PENDING)==0)) { - next_refresh = sub_state->expires_param; + int next_refresh = sub_state->expires_param; + unsigned timeout; - } else { - next_refresh = sub->expires->ivalue; - } + update_expires(sub, next_refresh); - /* Update time */ - update_expires(sub, next_refresh); - - /* Start UAC refresh timer, only when we're not unsubscribing */ - if (sub->expires->ivalue != 0) { - unsigned timeout = (next_refresh > TIME_UAC_REFRESH) ? - next_refresh - TIME_UAC_REFRESH : next_refresh; + /* Start UAC refresh timer, only when we're not unsubscribing */ + timeout = (next_refresh > TIME_UAC_REFRESH) ? + next_refresh - TIME_UAC_REFRESH : next_refresh; PJ_LOG(5,(sub->obj_name, "Will refresh in %d seconds", timeout)); set_timer(sub, TIMER_TYPE_UAC_REFRESH, timeout); diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c index 17c38473..41e3291f 100644 --- a/pjsip/src/pjsip-ua/sip_inv.c +++ b/pjsip/src/pjsip-ua/sip_inv.c @@ -2242,7 +2242,7 @@ PJ_DEF(pj_status_t) pjsip_inv_end_session( pjsip_inv_session *inv, return PJSIP_ESESSIONTERMINATED; default: - pj_assert("!Invalid operation!"); + pj_assert(!"Invalid operation!"); pj_log_pop_indent(); return PJ_EINVALIDOP; } diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c index 6dc49fdf..e3786369 100644 --- a/pjsip/src/pjsua-lib/pjsua_call.c +++ b/pjsip/src/pjsua-lib/pjsua_call.c @@ -1269,10 +1269,8 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata) &pjsua_var.acc[acc_id].cfg.timer_setting); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Session Timer init failed", status); - status = pjsip_inv_end_session(inv, PJSIP_SC_INTERNAL_SERVER_ERROR, - NULL, &response); - if (status == PJ_SUCCESS && response) - status = pjsip_inv_send_msg(inv, response); + pjsip_dlg_respond(dlg, rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, NULL, NULL, NULL); + pjsip_inv_terminate(inv, PJSIP_SC_INTERNAL_SERVER_ERROR, PJ_FALSE); pjsua_media_channel_deinit(call->index); -- cgit v1.2.3