diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c index 33abe03209..c4281c32da 100644 --- a/channels/chan_pjsip.c +++ b/channels/chan_pjsip.c @@ -771,7 +771,8 @@ static struct ast_frame *chan_pjsip_read(struct ast_channel *ast) * raw read format BEFORE the native format check */ if (!session->endpoint->asymmetric_rtp_codec && - ast_format_cmp(ast_channel_rawwriteformat(ast), f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) { + ast_format_cmp(ast_channel_rawwriteformat(ast), f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL && + ast_format_cap_iscompatible_format(session->joint_caps, f->subclass.format) == AST_FORMAT_CMP_EQUAL) { struct ast_format_cap *caps; /* For maximum compatibility we ensure that the formats match that of the received media */ diff --git a/include/asterisk/res_pjsip_session.h b/include/asterisk/res_pjsip_session.h index 9ae1883d04..38df3fd165 100644 --- a/include/asterisk/res_pjsip_session.h +++ b/include/asterisk/res_pjsip_session.h @@ -167,6 +167,8 @@ struct ast_sip_session { enum ast_sip_dtmf_mode dtmf; /*! Initial incoming INVITE Request-URI. NULL otherwise. */ pjsip_uri *request_uri; + /*! Joint capabilities */ + struct ast_format_cap *joint_caps; }; typedef int (*ast_sip_session_request_creation_cb)(struct ast_sip_session *session, pjsip_tx_data *tdata); diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c index 98e981965f..36b60444d3 100644 --- a/res/res_pjsip_sdp_rtp.c +++ b/res/res_pjsip_sdp_rtp.c @@ -408,6 +408,9 @@ static int set_caps(struct ast_sip_session *session, struct ast_sip_session_medi if (session->channel) { ast_channel_lock(session->channel); + ast_format_cap_remove_by_type(session->joint_caps, media_type); + ast_format_cap_append_from_cap(session->joint_caps, joint, media_type); + ast_format_cap_remove_by_type(caps, AST_MEDIA_TYPE_UNKNOWN); ast_format_cap_append_from_cap(caps, ast_channel_nativeformats(session->channel), AST_MEDIA_TYPE_UNKNOWN); diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c index bbdb8d148a..b61b0fd917 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -1351,6 +1351,7 @@ static void session_destructor(void *obj) ao2_cleanup(session->aor); ao2_cleanup(session->contact); ao2_cleanup(session->req_caps); + ao2_cleanup(session->joint_caps); ao2_cleanup(session->direct_media_cap); ast_dsp_free(session->dsp); @@ -1433,6 +1434,10 @@ struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint, if (!session->req_caps) { return NULL; } + session->joint_caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT); + if (!session->joint_caps) { + return NULL; + } session->datastores = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0, DATASTORE_BUCKETS, datastore_hash, NULL, datastore_cmp); if (!session->datastores) {