Fixed ticket #183: Add flag in SDP negotiator to specify codec order preference (thanks Esbjorn Dominique)

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@1072 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
Benny Prijono 2007-03-15 22:05:39 +00:00
parent 9de76b7020
commit a38e78df75
3 changed files with 88 additions and 15 deletions

View File

@ -279,6 +279,30 @@
#endif
/**
* This specifies the behavior of the SDP negotiator when responding to an
* offer, whether it should rather use the codec preference as set by
* remote, or should it rather use the codec preference as specified by
* local endpoint.
*
* For example, suppose incoming call has codec order "8 0 3", while
* local codec order is "3 0 8". If remote codec order is preferable,
* the selected codec will be 8, while if local codec order is preferable,
* the selected codec will be 3.
*
* If set to non-zero, the negotiator will use the codec order as specified
* by remote in the offer.
*
* Note that this behavior can be changed during run-time by calling
* pjmedia_sdp_neg_set_prefer_remote_codec_order().
*
* Default is 1 (to maintain backward compatibility)
*/
#ifndef PJMEDIA_SDP_NEG_PREFER_REMOTE_CODEC_ORDER
# define PJMEDIA_SDP_NEG_PREFER_REMOTE_CODEC_ORDER 1
#endif
/**
* Support for sending and decoding RTCP port in SDP (RFC 3605).
* Default is yes.

View File

@ -353,6 +353,30 @@ pjmedia_sdp_neg_create_w_remote_offer(pj_pool_t *pool,
const pjmedia_sdp_session *remote,
pjmedia_sdp_neg **p_neg);
/**
* This specifies the behavior of the SDP negotiator when responding to an
* offer, whether it should rather use the codec preference as set by
* remote, or should it rather use the codec preference as specified by
* local endpoint.
*
* For example, suppose incoming call has codec order "8 0 3", while
* local codec order is "3 0 8". If remote codec order is preferable,
* the selected codec will be 8, while if local codec order is preferable,
* the selected codec will be 3.
*
* By default, the value in PJMEDIA_SDP_NEG_PREFER_REMOTE_CODEC_ORDER will
* be used.
*
* @param neg The SDP negotiator instance.
* @param prefer_remote If non-zero, the negotiator will use the codec
* order as specified in remote offer. If zero, it
* will prefer to use the local codec order.
*/
PJ_DECL(pj_status_t)
pjmedia_sdp_neg_set_prefer_remote_codec_order(pjmedia_sdp_neg *neg,
pj_bool_t prefer_remote);
/**
* Get SDP negotiator state.
*

View File

@ -31,6 +31,7 @@
struct pjmedia_sdp_neg
{
pjmedia_sdp_neg_state state; /**< Negotiator state. */
pj_bool_t prefer_remote_codec_order;
pj_bool_t has_remote_answer;
pj_bool_t answer_was_remote;
@ -86,6 +87,7 @@ pjmedia_sdp_neg_create_w_local_offer( pj_pool_t *pool,
PJ_ASSERT_RETURN(neg != NULL, PJ_ENOMEM);
neg->state = PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER;
neg->prefer_remote_codec_order = PJMEDIA_SDP_NEG_PREFER_REMOTE_CODEC_ORDER;
neg->initial_sdp = pjmedia_sdp_session_clone(pool, local);
neg->neg_local_sdp = pjmedia_sdp_session_clone(pool, local);
@ -119,6 +121,7 @@ pjmedia_sdp_neg_create_w_remote_offer(pj_pool_t *pool,
neg = pj_pool_zalloc(pool, sizeof(pjmedia_sdp_neg));
PJ_ASSERT_RETURN(neg != NULL, PJ_ENOMEM);
neg->prefer_remote_codec_order = PJMEDIA_SDP_NEG_PREFER_REMOTE_CODEC_ORDER;
neg->neg_remote_sdp = pjmedia_sdp_session_clone(pool, remote);
if (initial) {
@ -140,6 +143,20 @@ pjmedia_sdp_neg_create_w_remote_offer(pj_pool_t *pool,
return PJ_SUCCESS;
}
/*
* Set codec order preference.
*/
PJ_DEF(pj_status_t)
pjmedia_sdp_neg_set_prefer_remote_codec_order(pjmedia_sdp_neg *neg,
pj_bool_t prefer_remote)
{
PJ_ASSERT_RETURN(neg, PJ_EINVAL);
neg->prefer_remote_codec_order = prefer_remote;
return PJ_SUCCESS;
}
/*
* Get SDP negotiator state.
*/
@ -667,7 +684,8 @@ static pj_status_t process_answer(pj_pool_t *pool,
/* Try to match offer with answer. */
static pj_status_t match_offer(pj_pool_t *pool,
const pjmedia_sdp_media *offer,
const pjmedia_sdp_media *local,
const pjmedia_sdp_media *preanswer,
const pjmedia_sdp_media *orig_local,
pjmedia_sdp_media **p_answer)
{
unsigned i;
@ -710,12 +728,12 @@ static pj_status_t match_offer(pj_pool_t *pool,
continue;
/* Find matching codec in local descriptor. */
for (j=0; j<local->desc.fmt_count; ++j) {
for (j=0; j<preanswer->desc.fmt_count; ++j) {
unsigned p;
p = pj_strtoul(&local->desc.fmt[j]);
if (p == pt && pj_isdigit(*local->desc.fmt[j].ptr)) {
p = pj_strtoul(&preanswer->desc.fmt[j]);
if (p == pt && pj_isdigit(*preanswer->desc.fmt[j].ptr)) {
found_matching_codec = 1;
pt_answer[pt_answer_count++] = local->desc.fmt[j];
pt_answer[pt_answer_count++] = preanswer->desc.fmt[j];
break;
}
}
@ -753,9 +771,9 @@ static pj_status_t match_offer(pj_pool_t *pool,
/* Find paylaod in our initial SDP with matching
* encoding name and clock rate.
*/
for (j=0; j<local->desc.fmt_count; ++j) {
a = pjmedia_sdp_media_find_attr2(local, "rtpmap",
&local->desc.fmt[j]);
for (j=0; j<preanswer->desc.fmt_count; ++j) {
a = pjmedia_sdp_media_find_attr2(preanswer, "rtpmap",
&preanswer->desc.fmt[j]);
if (a) {
pjmedia_sdp_rtpmap lr;
pjmedia_sdp_attr_get_rtpmap(a, &lr);
@ -773,7 +791,7 @@ static pj_status_t match_offer(pj_pool_t *pool,
found_matching_codec = 1;
else
found_matching_telephone_event = 1;
pt_answer[pt_answer_count++] = local->desc.fmt[j];
pt_answer[pt_answer_count++] = preanswer->desc.fmt[j];
break;
}
}
@ -791,11 +809,11 @@ static pj_status_t match_offer(pj_pool_t *pool,
if (found_matching_other)
continue;
for (j=0; j<local->desc.fmt_count; ++j) {
if (!pj_strcmp(&offer->desc.fmt[i], &local->desc.fmt[j])) {
for (j=0; j<preanswer->desc.fmt_count; ++j) {
if (!pj_strcmp(&offer->desc.fmt[i], &preanswer->desc.fmt[j])) {
/* Match */
found_matching_other = 1;
pt_answer[pt_answer_count++] = local->desc.fmt[j];
pt_answer[pt_answer_count++] = preanswer->desc.fmt[j];
break;
}
}
@ -823,7 +841,7 @@ static pj_status_t match_offer(pj_pool_t *pool,
* Build the answer by cloning from local media, but rearrange the payload
* to suit the offer.
*/
answer = pjmedia_sdp_media_clone(pool, local);
answer = pjmedia_sdp_media_clone(pool, orig_local);
for (i=0; i<pt_answer_count; ++i) {
unsigned j;
for (j=i; j<answer->desc.fmt_count; ++j) {
@ -867,6 +885,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,
const pjmedia_sdp_session *initial,
const pjmedia_sdp_session *offer,
pjmedia_sdp_session **p_answer)
@ -914,7 +933,12 @@ static pj_status_t create_answer( pj_pool_t *pool,
media_used[j] == 0)
{
/* See if it has matching codec. */
status = match_offer(pool, om, im, &am);
if (prefer_remote_codec_order) {
status = match_offer(pool, om, im, im, &am);
} else {
status = match_offer(pool, im, om, im, &am);
}
if (status == PJ_SUCCESS) {
/* Mark media as used. */
media_used[j] = 1;
@ -991,7 +1015,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->neg_local_sdp, neg->neg_remote_sdp,
status = create_answer(pool, neg->prefer_remote_codec_order,
neg->neg_local_sdp, neg->neg_remote_sdp,
&answer);
if (status == PJ_SUCCESS) {
pj_uint32_t active_ver;