From a088975f81907044c195a49d31790fee43b973a6 Mon Sep 17 00:00:00 2001 From: Liong Sauw Ming Date: Thu, 1 Aug 2013 04:18:15 +0000 Subject: Closed #1692: Allow multiple codecs in SDP answer By default, the setting is disabled, to change it during run-time, use the function pjmedia_sdp_neg_set_allow_multiple_codecs(). git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4577 74dad513-b988-da41-8d7b-12977e46ad98 --- pjmedia/include/pjmedia/config.h | 13 +++++++++++++ pjmedia/include/pjmedia/sdp_neg.h | 17 +++++++++++++++++ pjmedia/src/pjmedia/sdp_neg.c | 29 ++++++++++++++++++++++++----- 3 files changed, 54 insertions(+), 5 deletions(-) (limited to 'pjmedia') diff --git a/pjmedia/include/pjmedia/config.h b/pjmedia/include/pjmedia/config.h index d718b659..9eec63e8 100644 --- a/pjmedia/include/pjmedia/config.h +++ b/pjmedia/include/pjmedia/config.h @@ -668,6 +668,19 @@ # define PJMEDIA_SDP_NEG_PREFER_REMOTE_CODEC_ORDER 1 #endif +/** + * This specifies the behavior of the SDP negotiator when responding to an + * offer, whether it should answer with multiple formats or not. + * + * Note that this behavior can be changed during run-time by calling + * pjmedia_sdp_neg_set_allow_multiple_codecs(). + * + * Default is 0 (to maintain backward compatibility) + */ +#ifndef PJMEDIA_SDP_NEG_ANSWER_MULTIPLE_CODECS +# define PJMEDIA_SDP_NEG_ANSWER_MULTIPLE_CODECS 0 +#endif + /** * This specifies the maximum number of the customized SDP format diff --git a/pjmedia/include/pjmedia/sdp_neg.h b/pjmedia/include/pjmedia/sdp_neg.h index 3f6eb319..a17c74ce 100644 --- a/pjmedia/include/pjmedia/sdp_neg.h +++ b/pjmedia/include/pjmedia/sdp_neg.h @@ -416,6 +416,23 @@ PJ_DECL(pj_status_t) pjmedia_sdp_neg_set_prefer_remote_codec_order(pjmedia_sdp_neg *neg, pj_bool_t prefer_remote); +/** + * This specifies the behavior of the SDP negotiator when responding to an + * offer, whether it should answer with multiple formats or not. + * + * By default, the value in PJMEDIA_SDP_NEG_ANSWER_MULTIPLE_CODECS will + * be used. + * + * @param neg The SDP negotiator instance. + * @param answer_multiple + * If non-zero, the negotiator will respond with + * multiple formats. If zero only a single format + * will be returned. + */ +PJ_DECL(pj_status_t) +pjmedia_sdp_neg_set_answer_multiple_codecs(pjmedia_sdp_neg *neg, + pj_bool_t answer_multiple); + /** * Get SDP negotiator state. diff --git a/pjmedia/src/pjmedia/sdp_neg.c b/pjmedia/src/pjmedia/sdp_neg.c index 160a082e..ebed3a36 100644 --- a/pjmedia/src/pjmedia/sdp_neg.c +++ b/pjmedia/src/pjmedia/sdp_neg.c @@ -33,6 +33,7 @@ struct pjmedia_sdp_neg { pjmedia_sdp_neg_state state; /**< Negotiator state. */ pj_bool_t prefer_remote_codec_order; + pj_bool_t answer_with_multiple_codecs; pj_bool_t has_remote_answer; pj_bool_t answer_was_remote; @@ -114,6 +115,7 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_create_w_local_offer( pj_pool_t *pool, neg->state = PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER; neg->prefer_remote_codec_order = PJMEDIA_SDP_NEG_PREFER_REMOTE_CODEC_ORDER; + neg->answer_with_multiple_codecs = PJMEDIA_SDP_NEG_ANSWER_MULTIPLE_CODECS; neg->initial_sdp = pjmedia_sdp_session_clone(pool, local); neg->neg_local_sdp = pjmedia_sdp_session_clone(pool, local); @@ -182,6 +184,19 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_set_prefer_remote_codec_order( } +/* + * Set multiple codec answering. + */ +PJ_DEF(pj_status_t) pjmedia_sdp_neg_set_answer_multiple_codecs( + pjmedia_sdp_neg *neg, + pj_bool_t answer_multiple) +{ + PJ_ASSERT_RETURN(neg, PJ_EINVAL); + neg->answer_with_multiple_codecs = answer_multiple; + return PJ_SUCCESS; +} + + /* * Get SDP negotiator state. */ @@ -1010,6 +1025,7 @@ static void apply_answer_symmetric_pt(pj_pool_t *pool, /* Try to match offer with answer. */ static pj_status_t match_offer(pj_pool_t *pool, pj_bool_t prefer_remote_codec_order, + pj_bool_t answer_with_multiple_codecs, const pjmedia_sdp_media *offer, const pjmedia_sdp_media *preanswer, const pjmedia_sdp_session *preanswer_sdp, @@ -1075,11 +1091,11 @@ static pj_status_t match_offer(pj_pool_t *pool, master_has_codec = 1; - /* We just need to select one codec. + /* We just need to select one codec if not allowing multiple. * Continue if we have selected matching codec for previous * payload. */ - if (found_matching_codec) + if (!answer_with_multiple_codecs && found_matching_codec) continue; /* Find matching codec in local descriptor. */ @@ -1119,7 +1135,7 @@ static pj_status_t match_offer(pj_pool_t *pool, is_codec = 0; } else { master_has_codec = 1; - if (found_matching_codec) + if (!answer_with_multiple_codecs && found_matching_codec) continue; is_codec = 1; } @@ -1277,6 +1293,7 @@ static pj_status_t match_offer(pj_pool_t *pool, /* Create complete answer for remote's offer. */ static pj_status_t create_answer( pj_pool_t *pool, pj_bool_t prefer_remote_codec_order, + pj_bool_t answer_with_multiple_codecs, const pjmedia_sdp_session *initial, const pjmedia_sdp_session *offer, pjmedia_sdp_session **p_answer) @@ -1326,7 +1343,8 @@ static pj_status_t create_answer( pj_pool_t *pool, pj_status_t status2; /* See if it has matching codec. */ - status2 = match_offer(pool, prefer_remote_codec_order, + status2 = match_offer(pool, prefer_remote_codec_order, + answer_with_multiple_codecs, om, im, initial, &am); if (status2 == PJ_SUCCESS) { /* Mark media as used. */ @@ -1424,7 +1442,8 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_negotiate( pj_pool_t *pool, } else { pjmedia_sdp_session *answer = NULL; - status = create_answer(pool, neg->prefer_remote_codec_order, + status = create_answer(pool, neg->prefer_remote_codec_order, + neg->answer_with_multiple_codecs, neg->neg_local_sdp, neg->neg_remote_sdp, &answer); if (status == PJ_SUCCESS) { -- cgit v1.2.3