Ignore:
Timestamp:
Jul 19, 2011 3:42:28 AM (13 years ago)
Author:
nanang
Message:

Re #1326: Initial code integration from branch 2.0-dev to trunk as "2.0-pre-alpha-svn".

Location:
pjproject/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk

  • pjproject/trunk/pjmedia/src/pjmedia/sdp_neg.c

    r3553 r3664  
    5353}; 
    5454 
    55 #define GET_FMTP_IVAL(ival, fmtp, param, default_val) \ 
     55#define GET_FMTP_IVAL_BASE(ival, base, fmtp, param, default_val) \ 
    5656    do { \ 
    5757        pj_str_t s; \ 
     
    6464        pj_strset(&s, p + param.slen, fmtp.fmt_param.slen - \ 
    6565                  (p - fmtp.fmt_param.ptr) - param.slen); \ 
    66         ival = pj_strtoul(&s); \ 
     66        ival = pj_strtoul2(&s, NULL, base); \ 
    6767    } 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 */ 
     74struct 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 */ 
     81static unsigned fmt_match_cb_cnt; 
     82 
     83/* The registered customized SDP format negotiation callbacks */ 
     84static 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 
     90static 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 
    6898 
    6999/* 
     
    232262} 
    233263 
     264static 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} 
    234289 
    235290/* 
     
    312367            pjmedia_sdp_media *m; 
    313368 
    314             m = pjmedia_sdp_media_clone_deactivate(pool, om); 
     369            m = sdp_media_clone_deactivate(pool, om, om, local); 
    315370 
    316371            pj_array_insert(new_offer->media, sizeof(new_offer->media[0]), 
     
    877932                        { 
    878933                            /* 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                            { 
    880936                                if (match_g7221(offer, i, answer, j)) 
    881937                                    break; 
    882938                            } else 
     939 
    883940                            /* Further check for AMR, negotiate fmtp. */ 
    884941                            if (pj_stricmp2(&or_.enc_name, "AMR") == 0 || 
     
    888945                                              NULL)) 
    889946                                    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                            { 
    891954                                /* Match! */ 
    892955                                break; 
     
    10171080 
    10181081            /* 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); 
    10201084            answer->media[answer->media_count++] = am; 
    10211085            ++ami; 
     
    10791143    /* If offer has zero port, just clone the offer */ 
    10801144    if (offer->desc.port == 0) { 
    1081         answer = pjmedia_sdp_media_clone_deactivate(pool, offer); 
     1145        answer = sdp_media_clone_deactivate(pool, offer, preanswer, NULL); 
    10821146        *p_answer = answer; 
    10831147        return PJ_SUCCESS; 
     
    11821246                            /* Match! */ 
    11831247                            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 
    11841266                                /* Further check for G7221, negotiate bitrate */ 
    11851267                                if (pj_stricmp2(&or_.enc_name, "G7221") == 0 && 
     
    11871269                                { 
    11881270                                    continue; 
    1189                                 } else  
     1271                                } else 
     1272 
    11901273                                /* Further check for AMR, negotiate fmtp */ 
    11911274                                if (pj_stricmp2(&or_.enc_name, "AMR")==0 || 
     
    12011284                                        continue; 
    12021285                                } 
     1286 
    12031287                                found_matching_codec = 1; 
    12041288                            } else { 
     
    13721456             * number is zero. 
    13731457             */ 
    1374             am = pjmedia_sdp_media_clone_deactivate(pool, om); 
     1458            am = sdp_media_clone_deactivate(pool, om, om, answer); 
    13751459        } else { 
    13761460            /* The answer is in am */ 
     
    14741558} 
    14751559 
     1560 
     1561static 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. */ 
     1585PJ_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. */ 
     1635PJ_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.