summaryrefslogtreecommitdiff
path: root/pjmedia/src
diff options
context:
space:
mode:
authorLiong Sauw Ming <ming@teluu.com>2013-07-09 07:17:39 +0000
committerLiong Sauw Ming <ming@teluu.com>2013-07-09 07:17:39 +0000
commitfc938ab05ef6ea7e2c81c5d1e72a75eb89b03b13 (patch)
tree72913aaf4d900c1723d89b2eb70f177a15d1e8f6 /pjmedia/src
parent753074502fc69345d693068f13f1f1b58de70222 (diff)
Closed #1687: Allow media type change during SDP negotiation
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4554 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia/src')
-rw-r--r--pjmedia/src/pjmedia/sdp_neg.c97
1 files changed, 62 insertions, 35 deletions
diff --git a/pjmedia/src/pjmedia/sdp_neg.c b/pjmedia/src/pjmedia/sdp_neg.c
index a23b6ef0..160a082e 100644
--- a/pjmedia/src/pjmedia/sdp_neg.c
+++ b/pjmedia/src/pjmedia/sdp_neg.c
@@ -276,6 +276,15 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer( pj_pool_t *pool,
pjmedia_sdp_neg *neg,
const pjmedia_sdp_session *local)
{
+ return pjmedia_sdp_neg_modify_local_offer2(pool, neg, 0, local);
+}
+
+PJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer2(
+ pj_pool_t *pool,
+ pjmedia_sdp_neg *neg,
+ unsigned flags,
+ const pjmedia_sdp_session *local)
+{
pjmedia_sdp_session *new_offer;
pjmedia_sdp_session *old_offer;
char media_used[PJMEDIA_MAX_SDP_MEDIA];
@@ -314,45 +323,63 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer( pj_pool_t *pool,
pj_strdup(pool, &new_offer->origin.addr_type,&old_offer->origin.addr_type);
pj_strdup(pool, &new_offer->origin.addr, &old_offer->origin.addr);
- /* Generating the new offer, in the case media lines doesn't match the
- * active SDP (e.g. current/active SDP's have m=audio and m=video lines,
- * and the new offer only has m=audio line), the negotiator will fix
- * the new offer by reordering and adding the missing media line with
- * port number set to zero.
- */
- for (oi = 0; oi < old_offer->media_count; ++oi) {
- pjmedia_sdp_media *om;
- pjmedia_sdp_media *nm;
- unsigned ni; /* new offer media index */
- pj_bool_t found = PJ_FALSE;
-
- om = old_offer->media[oi];
- for (ni = oi; ni < new_offer->media_count; ++ni) {
- nm = new_offer->media[ni];
- if (pj_strcmp(&nm->desc.media, &om->desc.media) == 0) {
- if (ni != oi) {
- /* The same media found but the position unmatched to the
- * old offer, so let's put this media in the right place,
- * and keep the order of the rest.
- */
- pj_array_insert(new_offer->media, /* array */
- sizeof(new_offer->media[0]), /* elmt size*/
- ni, /* count */
- oi, /* pos */
- &nm); /* new elmt */
- }
- found = PJ_TRUE;
- break;
+ if ((flags & PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE) == 0) {
+ /* Generating the new offer, in the case media lines doesn't match the
+ * active SDP (e.g. current/active SDP's have m=audio and m=video lines,
+ * and the new offer only has m=audio line), the negotiator will fix
+ * the new offer by reordering and adding the missing media line with
+ * port number set to zero.
+ */
+ for (oi = 0; oi < old_offer->media_count; ++oi) {
+ pjmedia_sdp_media *om;
+ pjmedia_sdp_media *nm;
+ unsigned ni; /* new offer media index */
+ pj_bool_t found = PJ_FALSE;
+
+ om = old_offer->media[oi];
+ for (ni = oi; ni < new_offer->media_count; ++ni) {
+ nm = new_offer->media[ni];
+ if (pj_strcmp(&nm->desc.media, &om->desc.media) == 0) {
+ if (ni != oi) {
+ /* The same media found but the position unmatched to
+ * the old offer, so let's put this media in the right
+ * place, and keep the order of the rest.
+ */
+ pj_array_insert(
+ new_offer->media, /* array */
+ sizeof(new_offer->media[0]), /* elmt size*/
+ ni, /* count */
+ oi, /* pos */
+ &nm); /* new elmt */
+ }
+ found = PJ_TRUE;
+ break;
+ }
}
- }
- if (!found) {
- pjmedia_sdp_media *m;
+ if (!found) {
+ pjmedia_sdp_media *m;
+
+ m = sdp_media_clone_deactivate(pool, om, om, local);
+
+ pj_array_insert(new_offer->media, sizeof(new_offer->media[0]),
+ new_offer->media_count++, oi, &m);
+ }
+ }
+ } else {
+ /* If media type change is allowed, the negotiator only needs to fix
+ * the new offer by adding the missing media line(s) with port number
+ * set to zero.
+ */
+ for (oi = new_offer->media_count; oi < old_offer->media_count; ++oi) {
+ pjmedia_sdp_media *m;
- m = sdp_media_clone_deactivate(pool, om, om, local);
+ m = sdp_media_clone_deactivate(pool, old_offer->media[oi],
+ old_offer->media[oi], local);
pj_array_insert(new_offer->media, sizeof(new_offer->media[0]),
- new_offer->media_count++, oi, &m);
- }
+ new_offer->media_count++, oi, &m);
+
+ }
}
/* New_offer fixed */