- Timestamp:
- Apr 6, 2011 1:55:01 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/sdp_neg.c
r3493 r3500 71 71 72 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 98 73 99 /* 74 100 * Get string representation of negotiator state. … … 683 709 684 710 685 /* Matching H.264 between offer and answer. */686 static pj_bool_t match_h264( const pjmedia_sdp_media *offer,687 unsigned o_fmt_idx,688 const pjmedia_sdp_media *answer,689 unsigned a_fmt_idx)690 {691 const pjmedia_sdp_attr *attr_ans;692 const pjmedia_sdp_attr *attr_ofr;693 pjmedia_sdp_fmtp fmtp;694 pj_uint32_t profile1, profile2;695 unsigned pack_mode1, pack_mode2;696 const pj_str_t STR_PROFILE = {"profile-level-id=", 17};697 const pj_str_t STR_PACK_MODE = {"packetization-mode=", 19};698 699 /* Parse offer */700 attr_ofr = pjmedia_sdp_media_find_attr2(offer, "fmtp",701 &offer->desc.fmt[o_fmt_idx]);702 if (!attr_ofr)703 return PJ_FALSE;704 705 if (pjmedia_sdp_attr_get_fmtp(attr_ofr, &fmtp) != PJ_SUCCESS)706 return PJ_FALSE;707 708 GET_FMTP_IVAL_BASE(profile1, 16, fmtp, STR_PROFILE, 0x42000A);709 GET_FMTP_IVAL(pack_mode1, fmtp, STR_PACK_MODE, 0);710 711 /* Parse answer */712 attr_ans = pjmedia_sdp_media_find_attr2(answer, "fmtp",713 &answer->desc.fmt[a_fmt_idx]);714 if (!attr_ans)715 return PJ_FALSE;716 717 if (pjmedia_sdp_attr_get_fmtp(attr_ans, &fmtp) != PJ_SUCCESS)718 return PJ_FALSE;719 720 GET_FMTP_IVAL_BASE(profile2, 16, fmtp, STR_PROFILE, 0x42000A);721 GET_FMTP_IVAL(pack_mode2, fmtp, STR_PACK_MODE, 0);722 723 /* Compare bitrate in answer and offer. */724 return ((profile1 == profile2) && (pack_mode1 == pack_mode2));725 }726 727 728 711 /* Toggle AMR octet-align setting in the fmtp. 729 712 */ … … 929 912 break; 930 913 } else 914 931 915 /* Further check for AMR, negotiate fmtp. */ 932 916 if (pj_stricmp2(&or_.enc_name, "AMR") == 0 || … … 937 921 break; 938 922 } else 939 /* Further check for H264, negotiate fmtp. */ 940 if (pj_stricmp2(&or_.enc_name, "H264") == 0) 923 924 /* Call custom format matching callbacks */ 925 if (custom_fmt_match(pool, &or_.enc_name, 926 offer, i, answer, j, 0) == 927 PJ_SUCCESS) 941 928 { 942 if (match_h264(offer, i, answer, j))943 break;944 } else {945 929 /* Match! */ 946 930 break; … … 1236 1220 /* Match! */ 1237 1221 if (is_codec) { 1222 pjmedia_sdp_media *o, *a; 1223 unsigned o_fmt_idx, a_fmt_idx; 1224 1225 o = (pjmedia_sdp_media*)offer; 1226 a = (pjmedia_sdp_media*)preanswer; 1227 o_fmt_idx = prefer_remote_codec_order? i:j; 1228 a_fmt_idx = prefer_remote_codec_order? j:i; 1229 1230 /* Call custom format matching callbacks */ 1231 if (custom_fmt_match(pool, &or_.enc_name, 1232 o, o_fmt_idx, 1233 a, a_fmt_idx, 1234 ALLOW_MODIFY_ANSWER) != 1235 PJ_SUCCESS) 1236 { 1237 continue; 1238 } else 1239 1238 1240 /* Further check for G7221, negotiate bitrate */ 1239 1241 if (pj_stricmp2(&or_.enc_name, "G7221") == 0 && … … 1241 1243 { 1242 1244 continue; 1243 } else 1245 } else 1246 1244 1247 /* Further check for AMR, negotiate fmtp */ 1245 1248 if (pj_stricmp2(&or_.enc_name, "AMR")==0 || … … 1254 1257 PJ_TRUE, &pt_amr_need_adapt)) 1255 1258 continue; 1256 } else1257 if (pj_stricmp2(&or_.enc_name, "H264") == 0 &&1258 !match_h264(master, i, slave, j))1259 {1260 continue;1261 1259 } 1260 1262 1261 found_matching_codec = 1; 1263 1262 } else { … … 1533 1532 } 1534 1533 1534 1535 static pj_status_t custom_fmt_match(pj_pool_t *pool, 1536 const pj_str_t *fmt_name, 1537 pjmedia_sdp_media *offer, 1538 unsigned o_fmt_idx, 1539 pjmedia_sdp_media *answer, 1540 unsigned a_fmt_idx, 1541 unsigned option) 1542 { 1543 unsigned i; 1544 1545 for (i = 0; i < fmt_match_cb_cnt; ++i) { 1546 if (pj_stricmp(fmt_name, &fmt_match_cb[i].fmt_name) == 0) { 1547 pj_assert(fmt_match_cb[i].cb); 1548 return (*fmt_match_cb[i].cb)(pool, offer, o_fmt_idx, 1549 answer, a_fmt_idx, 1550 option); 1551 } 1552 } 1553 1554 /* Not customized format matching found, should be matched */ 1555 return PJ_SUCCESS; 1556 } 1557 1558 /* Register customized SDP format negotiation callback function. */ 1559 PJ_DECL(pj_status_t) pjmedia_sdp_neg_register_fmt_match_cb( 1560 const pj_str_t *fmt_name, 1561 pjmedia_sdp_neg_fmt_match_cb cb) 1562 { 1563 struct fmt_match_cb_t *f = NULL; 1564 unsigned i; 1565 1566 PJ_ASSERT_RETURN(fmt_name, PJ_EINVAL); 1567 1568 /* Check if the callback for the format name has been registered */ 1569 for (i = 0; i < fmt_match_cb_cnt; ++i) { 1570 if (pj_stricmp(fmt_name, &fmt_match_cb[i].fmt_name) == 0) 1571 break; 1572 } 1573 1574 /* Unregistration */ 1575 1576 if (cb == NULL) { 1577 if (i == fmt_match_cb_cnt) 1578 return PJ_ENOTFOUND; 1579 1580 pj_array_erase(fmt_match_cb, sizeof(fmt_match_cb[0]), 1581 fmt_match_cb_cnt, i); 1582 fmt_match_cb_cnt--; 1583 1584 return PJ_SUCCESS; 1585 } 1586 1587 /* Registration */ 1588 1589 if (i < fmt_match_cb_cnt) { 1590 /* The same format name has been registered before */ 1591 if (cb != fmt_match_cb[i].cb) 1592 return PJ_EEXISTS; 1593 else 1594 return PJ_SUCCESS; 1595 } 1596 1597 if (fmt_match_cb_cnt >= PJ_ARRAY_SIZE(fmt_match_cb)) 1598 return PJ_ETOOMANY; 1599 1600 f = &fmt_match_cb[fmt_match_cb_cnt++]; 1601 f->fmt_name = *fmt_name; 1602 f->cb = cb; 1603 1604 return PJ_SUCCESS; 1605 } 1606 1607 1608 /* Match format in the SDP media offer and answer. */ 1609 PJ_DEF(pj_bool_t) pjmedia_sdp_neg_fmt_match( pj_pool_t *pool, 1610 pjmedia_sdp_media *offer, 1611 unsigned o_fmt_idx, 1612 pjmedia_sdp_media *answer, 1613 unsigned a_fmt_idx, 1614 unsigned option) 1615 { 1616 const pjmedia_sdp_attr *attr; 1617 pjmedia_sdp_rtpmap o_rtpmap, a_rtpmap; 1618 1619 /* Get the format rtpmap from the offer. */ 1620 attr = pjmedia_sdp_media_find_attr2(offer, "rtpmap", 1621 &offer->desc.fmt[o_fmt_idx]); 1622 if (!attr) { 1623 pj_assert(!"Bug! Offer haven't been validated"); 1624 return PJ_EBUG; 1625 } 1626 pjmedia_sdp_attr_get_rtpmap(attr, &o_rtpmap); 1627 1628 /* Get the format rtpmap from the answer. */ 1629 attr = pjmedia_sdp_media_find_attr2(answer, "rtpmap", 1630 &answer->desc.fmt[a_fmt_idx]); 1631 if (!attr) { 1632 pj_assert(!"Bug! Answer haven't been validated"); 1633 return PJ_EBUG; 1634 } 1635 pjmedia_sdp_attr_get_rtpmap(attr, &a_rtpmap); 1636 1637 if (pj_stricmp(&o_rtpmap.enc_name, &a_rtpmap.enc_name) != 0 || 1638 o_rtpmap.clock_rate != a_rtpmap.clock_rate) 1639 { 1640 return PJMEDIA_SDP_EFORMATNOTEQUAL; 1641 } 1642 1643 /* Further check for G7221, negotiate bitrate. */ 1644 if (pj_stricmp2(&o_rtpmap.enc_name, "G7221") == 0) { 1645 if (match_g7221(offer, o_fmt_idx, answer, a_fmt_idx)) 1646 return PJ_SUCCESS; 1647 else 1648 return PJMEDIA_SDP_EFORMATNOTEQUAL; 1649 } else 1650 /* Further check for AMR, negotiate fmtp. */ 1651 if (pj_stricmp2(&o_rtpmap.enc_name, "AMR") == 0 || 1652 pj_stricmp2(&o_rtpmap.enc_name, "AMR-WB") == 0) 1653 { 1654 if (match_amr(offer, o_fmt_idx, answer, a_fmt_idx, PJ_FALSE, NULL)) 1655 return PJ_SUCCESS; 1656 else 1657 return PJMEDIA_SDP_EFORMATNOTEQUAL; 1658 } 1659 PJ_TODO(replace_hardcoded_fmt_match_in_sdp_neg_with_custom_fmt_match_cb); 1660 1661 return custom_fmt_match(pool, &o_rtpmap.enc_name, 1662 offer, o_fmt_idx, answer, a_fmt_idx, option); 1663 } 1664
Note: See TracChangeset
for help on using the changeset viewer.