diff options
-rw-r--r-- | CHANGES | 7 | ||||
-rw-r--r-- | channels/chan_pjsip.c | 25 | ||||
-rw-r--r-- | configs/samples/pjsip.conf.sample | 2 | ||||
-rw-r--r-- | contrib/ast-db-manage/config/versions/4468b4a91372_add_pjsip_asymmetric_rtp_codec.py | 31 | ||||
-rw-r--r-- | include/asterisk/res_pjsip.h | 2 | ||||
-rw-r--r-- | res/res_pjsip.c | 8 | ||||
-rw-r--r-- | res/res_pjsip/pjsip_configuration.c | 1 | ||||
-rw-r--r-- | res/res_pjsip_sdp_rtp.c | 5 |
8 files changed, 74 insertions, 7 deletions
@@ -21,6 +21,13 @@ res_pjsip res_pjsip_multihomed module has also been moved into core res_pjsip to ensure that messages are updated with the correct address information in all cases. +chan_pjsip +------------------ + * The default behavior for RTP codecs has been changed. The sending codec will + now match the receiving codec. This can be turned off and behavior reverted + to asymmetric using the "asymmetric_rtp_codec" endpoint option. If this + option is set then the sending and received codec are allowed to differ. + ------------------------------------------------------------------------------ --- Functionality changes from Asterisk 13.11.0 to Asterisk 13.12.0 ---------- ------------------------------------------------------------------------------ diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c index 23545112e..90553cb63 100644 --- a/channels/chan_pjsip.c +++ b/channels/chan_pjsip.c @@ -219,9 +219,7 @@ static enum ast_rtp_glue_result chan_pjsip_get_vrtp_peer(struct ast_channel *cha /*! \brief Function called by RTP engine to get peer capabilities */ static void chan_pjsip_get_codec(struct ast_channel *chan, struct ast_format_cap *result) { - struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan); - - ast_format_cap_append_from_cap(result, channel->session->endpoint->media.codecs, AST_MEDIA_TYPE_UNKNOWN); + ast_format_cap_append_from_cap(result, ast_channel_nativeformats(chan), AST_MEDIA_TYPE_UNKNOWN); } /*! \brief Destructor function for \ref transport_info_data */ @@ -704,15 +702,28 @@ static struct ast_frame *chan_pjsip_read(struct ast_channel *ast) session = channel->session; - if (ast_format_cap_iscompatible_format(session->endpoint->media.codecs, f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) { - ast_debug(1, "Oooh, got a frame with format of %s on channel '%s' when endpoint '%s' is not configured for it\n", - ast_format_get_name(f->subclass.format), ast_channel_name(ast), - ast_sorcery_object_get_id(session->endpoint)); + if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(ast), f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) { + ast_debug(1, "Oooh, got a frame with format of %s on channel '%s' when it has not been negotiated\n", + ast_format_get_name(f->subclass.format), ast_channel_name(ast)); ast_frfree(f); return &ast_null_frame; } + if (!session->endpoint->asymmetric_rtp_codec && + ast_format_cmp(ast_channel_rawwriteformat(ast), f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) { + /* For maximum compatibility we ensure that the write format matches that of the received media */ + ast_debug(1, "Oooh, got a frame with format of %s on channel '%s' when we're sending '%s', switching to match\n", + ast_format_get_name(f->subclass.format), ast_channel_name(ast), + ast_format_get_name(ast_channel_rawwriteformat(ast))); + ast_channel_set_rawwriteformat(ast, f->subclass.format); + ast_set_write_format(ast, ast_channel_writeformat(ast)); + + if (ast_channel_is_bridged(ast)) { + ast_channel_set_unbridged_nolock(ast, 1); + } + } + if (session->dsp) { int dsp_features; diff --git a/configs/samples/pjsip.conf.sample b/configs/samples/pjsip.conf.sample index c9b5a8c07..2ef893384 100644 --- a/configs/samples/pjsip.conf.sample +++ b/configs/samples/pjsip.conf.sample @@ -753,6 +753,8 @@ ; "0" or not enabled) ;contact_user= ; On outgoing requests, force the user portion of the Contact ; header to this value (default: "") +;asymmetric_rtp_codec= ; Allow the sending and receiving codec to differ and + ; not be automatically matched (default: "no") ;==========================AUTH SECTION OPTIONS========================= ;[auth] diff --git a/contrib/ast-db-manage/config/versions/4468b4a91372_add_pjsip_asymmetric_rtp_codec.py b/contrib/ast-db-manage/config/versions/4468b4a91372_add_pjsip_asymmetric_rtp_codec.py new file mode 100644 index 000000000..c121495e2 --- /dev/null +++ b/contrib/ast-db-manage/config/versions/4468b4a91372_add_pjsip_asymmetric_rtp_codec.py @@ -0,0 +1,31 @@ +"""add pjsip asymmetric rtp codec + +Revision ID: 4468b4a91372 +Revises: a6ef36f1309 +Create Date: 2016-10-25 10:57:20.808815 + +""" + +# revision identifiers, used by Alembic. +revision = '4468b4a91372' +down_revision = 'a6ef36f1309' + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects.postgresql import ENUM + +YESNO_NAME = 'yesno_values' +YESNO_VALUES = ['yes', 'no'] + +def upgrade(): + ############################# Enums ############################## + + # yesno_values have already been created, so use postgres enum object + # type to get around "already created" issue - works okay with mysql + yesno_values = ENUM(*YESNO_VALUES, name=YESNO_NAME, create_type=False) + + op.add_column('ps_endpoints', sa.Column('asymmetric_rtp_codec', yesno_values)) + + +def downgrade(): + op.drop_column('ps_endpoints', 'asymmetric_rtp_codec') diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index 28ecf7f1d..4ad660727 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -753,6 +753,8 @@ struct ast_sip_endpoint { unsigned int faxdetect_timeout; /*! Override the user on the outgoing Contact header with this value. */ char *contact_user; + /*! Do we allow an asymmetric RTP codec? */ + unsigned int asymmetric_rtp_codec; }; /*! diff --git a/res/res_pjsip.c b/res/res_pjsip.c index 4927ea36a..153352f9f 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -919,6 +919,14 @@ On outbound requests, force the user portion of the Contact header to this value. </para></description> </configOption> + <configOption name="asymmetric_rtp_codec" default="no"> + <synopsis>Allow the sending and receiving RTP codec to differ</synopsis> + <description><para> + When set to "yes" the codec in use for sending will be allowed to differ from + that of the received one. PJSIP will not automatically switch the sending one + to the receiving one. + </para></description> + </configOption> </configObject> <configObject name="auth"> <synopsis>Authentication type</synopsis> diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c index 478e5c7d7..84dfa2264 100644 --- a/res/res_pjsip/pjsip_configuration.c +++ b/res/res_pjsip/pjsip_configuration.c @@ -1939,6 +1939,7 @@ int ast_res_pjsip_initialize_configuration(const struct ast_module_info *ast_mod ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "contact_acl", "", endpoint_acl_handler, contact_acl_to_str, NULL, 0, 0); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "subscribe_context", "", OPT_CHAR_ARRAY_T, 0, CHARFLDSET(struct ast_sip_endpoint, subscription.context)); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "contact_user", "", contact_user_handler, contact_user_to_str, NULL, 0, 0); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "asymmetric_rtp_codec", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, asymmetric_rtp_codec)); if (ast_sip_initialize_sorcery_transport()) { ast_log(LOG_ERROR, "Failed to register SIP transport support with sorcery\n"); diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c index aaedde423..9e9815591 100644 --- a/res/res_pjsip_sdp_rtp.c +++ b/res/res_pjsip_sdp_rtp.c @@ -370,6 +370,11 @@ static int set_caps(struct ast_sip_session *session, struct ast_sip_session_medi session->dsp = NULL; } } + + if (ast_channel_is_bridged(session->channel)) { + ast_channel_set_unbridged_nolock(session->channel, 1); + } + ast_channel_unlock(session->channel); } |