Changeset 3664 for pjproject/trunk/pjmedia/src/pjmedia/sdp_neg.c
- Timestamp:
- Jul 19, 2011 3:42:28 AM (13 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk
- Property svn:mergeinfo changed
-
pjproject/trunk/pjmedia/src/pjmedia/sdp_neg.c
r3553 r3664 53 53 }; 54 54 55 #define GET_FMTP_IVAL (ival, fmtp, param, default_val) \55 #define GET_FMTP_IVAL_BASE(ival, base, fmtp, param, default_val) \ 56 56 do { \ 57 57 pj_str_t s; \ … … 64 64 pj_strset(&s, p + param.slen, fmtp.fmt_param.slen - \ 65 65 (p - fmtp.fmt_param.ptr) - param.slen); \ 66 ival = pj_strtoul (&s); \66 ival = pj_strtoul2(&s, NULL, base); \ 67 67 } while (0) 68 69 #define GET_FMTP_IVAL(ival, fmtp, param, default_val) \ 70 GET_FMTP_IVAL_BASE(ival, 10, fmtp, param, default_val) 71 72 73 /* Definition of customized SDP format negotiation callback */ 74 struct fmt_match_cb_t 75 { 76 pj_str_t fmt_name; 77 pjmedia_sdp_neg_fmt_match_cb cb; 78 }; 79 80 /* Number of registered customized SDP format negotiation callbacks */ 81 static unsigned fmt_match_cb_cnt; 82 83 /* The registered customized SDP format negotiation callbacks */ 84 static struct fmt_match_cb_t 85 fmt_match_cb[PJMEDIA_SDP_NEG_MAX_CUSTOM_FMT_NEG_CB]; 86 87 /* Redefining a very long identifier name, just for convenience */ 88 #define ALLOW_MODIFY_ANSWER PJMEDIA_SDP_NEG_FMT_MATCH_ALLOW_MODIFY_ANSWER 89 90 static pj_status_t custom_fmt_match( pj_pool_t *pool, 91 const pj_str_t *fmt_name, 92 pjmedia_sdp_media *offer, 93 unsigned o_fmt_idx, 94 pjmedia_sdp_media *answer, 95 unsigned a_fmt_idx, 96 unsigned option); 97 68 98 69 99 /* … … 232 262 } 233 263 264 static pjmedia_sdp_media *sdp_media_clone_deactivate( 265 pj_pool_t *pool, 266 const pjmedia_sdp_media *rem_med, 267 const pjmedia_sdp_media *local_med, 268 const pjmedia_sdp_session *local_sess) 269 { 270 pjmedia_sdp_media *res; 271 272 res = pjmedia_sdp_media_clone_deactivate(pool, rem_med); 273 if (!res) 274 return NULL; 275 276 if (!res->conn && (!local_sess || !local_sess->conn)) { 277 if (local_med && local_med->conn) 278 res->conn = pjmedia_sdp_conn_clone(pool, local_med->conn); 279 else { 280 res->conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn); 281 res->conn->net_type = pj_str("IN"); 282 res->conn->addr_type = pj_str("IP4"); 283 res->conn->addr = pj_str("127.0.0.1"); 284 } 285 } 286 287 return res; 288 } 234 289 235 290 /* … … 312 367 pjmedia_sdp_media *m; 313 368 314 m = pjmedia_sdp_media_clone_deactivate(pool, om);369 m = sdp_media_clone_deactivate(pool, om, om, local); 315 370 316 371 pj_array_insert(new_offer->media, sizeof(new_offer->media[0]), … … 877 932 { 878 933 /* Further check for G7221, negotiate bitrate. */ 879 if (pj_stricmp2(&or_.enc_name, "G7221") == 0) { 934 if (pj_stricmp2(&or_.enc_name, "G7221") == 0) 935 { 880 936 if (match_g7221(offer, i, answer, j)) 881 937 break; 882 938 } else 939 883 940 /* Further check for AMR, negotiate fmtp. */ 884 941 if (pj_stricmp2(&or_.enc_name, "AMR") == 0 || … … 888 945 NULL)) 889 946 break; 890 } else { 947 } else 948 949 /* Call custom format matching callbacks */ 950 if (custom_fmt_match(pool, &or_.enc_name, 951 offer, i, answer, j, 0) == 952 PJ_SUCCESS) 953 { 891 954 /* Match! */ 892 955 break; … … 1017 1080 1018 1081 /* Generate matching-but-disabled-media for the answer */ 1019 am = pjmedia_sdp_media_clone_deactivate(pool, offer->media[omi]); 1082 am = sdp_media_clone_deactivate(pool, offer->media[omi], 1083 offer->media[omi], offer); 1020 1084 answer->media[answer->media_count++] = am; 1021 1085 ++ami; … … 1079 1143 /* If offer has zero port, just clone the offer */ 1080 1144 if (offer->desc.port == 0) { 1081 answer = pjmedia_sdp_media_clone_deactivate(pool, offer);1145 answer = sdp_media_clone_deactivate(pool, offer, preanswer, NULL); 1082 1146 *p_answer = answer; 1083 1147 return PJ_SUCCESS; … … 1182 1246 /* Match! */ 1183 1247 if (is_codec) { 1248 pjmedia_sdp_media *o, *a; 1249 unsigned o_fmt_idx, a_fmt_idx; 1250 1251 o = (pjmedia_sdp_media*)offer; 1252 a = (pjmedia_sdp_media*)preanswer; 1253 o_fmt_idx = prefer_remote_codec_order? i:j; 1254 a_fmt_idx = prefer_remote_codec_order? j:i; 1255 1256 /* Call custom format matching callbacks */ 1257 if (custom_fmt_match(pool, &or_.enc_name, 1258 o, o_fmt_idx, 1259 a, a_fmt_idx, 1260 ALLOW_MODIFY_ANSWER) != 1261 PJ_SUCCESS) 1262 { 1263 continue; 1264 } else 1265 1184 1266 /* Further check for G7221, negotiate bitrate */ 1185 1267 if (pj_stricmp2(&or_.enc_name, "G7221") == 0 && … … 1187 1269 { 1188 1270 continue; 1189 } else 1271 } else 1272 1190 1273 /* Further check for AMR, negotiate fmtp */ 1191 1274 if (pj_stricmp2(&or_.enc_name, "AMR")==0 || … … 1201 1284 continue; 1202 1285 } 1286 1203 1287 found_matching_codec = 1; 1204 1288 } else { … … 1372 1456 * number is zero. 1373 1457 */ 1374 am = pjmedia_sdp_media_clone_deactivate(pool, om);1458 am = sdp_media_clone_deactivate(pool, om, om, answer); 1375 1459 } else { 1376 1460 /* The answer is in am */ … … 1474 1558 } 1475 1559 1560 1561 static pj_status_t custom_fmt_match(pj_pool_t *pool, 1562 const pj_str_t *fmt_name, 1563 pjmedia_sdp_media *offer, 1564 unsigned o_fmt_idx, 1565 pjmedia_sdp_media *answer, 1566 unsigned a_fmt_idx, 1567 unsigned option) 1568 { 1569 unsigned i; 1570 1571 for (i = 0; i < fmt_match_cb_cnt; ++i) { 1572 if (pj_stricmp(fmt_name, &fmt_match_cb[i].fmt_name) == 0) { 1573 pj_assert(fmt_match_cb[i].cb); 1574 return (*fmt_match_cb[i].cb)(pool, offer, o_fmt_idx, 1575 answer, a_fmt_idx, 1576 option); 1577 } 1578 } 1579 1580 /* Not customized format matching found, should be matched */ 1581 return PJ_SUCCESS; 1582 } 1583 1584 /* Register customized SDP format negotiation callback function. */ 1585 PJ_DECL(pj_status_t) pjmedia_sdp_neg_register_fmt_match_cb( 1586 const pj_str_t *fmt_name, 1587 pjmedia_sdp_neg_fmt_match_cb cb) 1588 { 1589 struct fmt_match_cb_t *f = NULL; 1590 unsigned i; 1591 1592 PJ_ASSERT_RETURN(fmt_name, PJ_EINVAL); 1593 1594 /* Check if the callback for the format name has been registered */ 1595 for (i = 0; i < fmt_match_cb_cnt; ++i) { 1596 if (pj_stricmp(fmt_name, &fmt_match_cb[i].fmt_name) == 0) 1597 break; 1598 } 1599 1600 /* Unregistration */ 1601 1602 if (cb == NULL) { 1603 if (i == fmt_match_cb_cnt) 1604 return PJ_ENOTFOUND; 1605 1606 pj_array_erase(fmt_match_cb, sizeof(fmt_match_cb[0]), 1607 fmt_match_cb_cnt, i); 1608 fmt_match_cb_cnt--; 1609 1610 return PJ_SUCCESS; 1611 } 1612 1613 /* Registration */ 1614 1615 if (i < fmt_match_cb_cnt) { 1616 /* The same format name has been registered before */ 1617 if (cb != fmt_match_cb[i].cb) 1618 return PJ_EEXISTS; 1619 else 1620 return PJ_SUCCESS; 1621 } 1622 1623 if (fmt_match_cb_cnt >= PJ_ARRAY_SIZE(fmt_match_cb)) 1624 return PJ_ETOOMANY; 1625 1626 f = &fmt_match_cb[fmt_match_cb_cnt++]; 1627 f->fmt_name = *fmt_name; 1628 f->cb = cb; 1629 1630 return PJ_SUCCESS; 1631 } 1632 1633 1634 /* Match format in the SDP media offer and answer. */ 1635 PJ_DEF(pj_bool_t) pjmedia_sdp_neg_fmt_match( pj_pool_t *pool, 1636 pjmedia_sdp_media *offer, 1637 unsigned o_fmt_idx, 1638 pjmedia_sdp_media *answer, 1639 unsigned a_fmt_idx, 1640 unsigned option) 1641 { 1642 const pjmedia_sdp_attr *attr; 1643 pjmedia_sdp_rtpmap o_rtpmap, a_rtpmap; 1644 1645 /* Get the format rtpmap from the offer. */ 1646 attr = pjmedia_sdp_media_find_attr2(offer, "rtpmap", 1647 &offer->desc.fmt[o_fmt_idx]); 1648 if (!attr) { 1649 pj_assert(!"Bug! Offer haven't been validated"); 1650 return PJ_EBUG; 1651 } 1652 pjmedia_sdp_attr_get_rtpmap(attr, &o_rtpmap); 1653 1654 /* Get the format rtpmap from the answer. */ 1655 attr = pjmedia_sdp_media_find_attr2(answer, "rtpmap", 1656 &answer->desc.fmt[a_fmt_idx]); 1657 if (!attr) { 1658 pj_assert(!"Bug! Answer haven't been validated"); 1659 return PJ_EBUG; 1660 } 1661 pjmedia_sdp_attr_get_rtpmap(attr, &a_rtpmap); 1662 1663 if (pj_stricmp(&o_rtpmap.enc_name, &a_rtpmap.enc_name) != 0 || 1664 o_rtpmap.clock_rate != a_rtpmap.clock_rate) 1665 { 1666 return PJMEDIA_SDP_EFORMATNOTEQUAL; 1667 } 1668 1669 /* Further check for G7221, negotiate bitrate. */ 1670 if (pj_stricmp2(&o_rtpmap.enc_name, "G7221") == 0) { 1671 if (match_g7221(offer, o_fmt_idx, answer, a_fmt_idx)) 1672 return PJ_SUCCESS; 1673 else 1674 return PJMEDIA_SDP_EFORMATNOTEQUAL; 1675 } else 1676 /* Further check for AMR, negotiate fmtp. */ 1677 if (pj_stricmp2(&o_rtpmap.enc_name, "AMR") == 0 || 1678 pj_stricmp2(&o_rtpmap.enc_name, "AMR-WB") == 0) 1679 { 1680 if (match_amr(offer, o_fmt_idx, answer, a_fmt_idx, PJ_FALSE, NULL)) 1681 return PJ_SUCCESS; 1682 else 1683 return PJMEDIA_SDP_EFORMATNOTEQUAL; 1684 } 1685 PJ_TODO(replace_hardcoded_fmt_match_in_sdp_neg_with_custom_fmt_match_cb); 1686 1687 return custom_fmt_match(pool, &o_rtpmap.enc_name, 1688 offer, o_fmt_idx, answer, a_fmt_idx, option); 1689 } 1690
Note: See TracChangeset
for help on using the changeset viewer.