Ignore:
Timestamp:
May 9, 2018 6:58:48 AM (17 months ago)
Author:
ming
Message:

Fixed #2087: Support for RTP and RTCP multiplexing

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia/transport_ice.c

    r5752 r5788  
    8282    pj_sockaddr          rtcp_src_addr; /**< Actual source RTCP address.    */ 
    8383    unsigned             rtcp_src_cnt;  /**< How many pkt from this addr.   */ 
     84    pj_bool_t            enable_rtcp_mux;/**< Enable RTP& RTCP multiplexing?*/ 
     85    pj_bool_t            use_rtcp_mux;  /**< Use RTP & RTCP multiplexing?   */ 
    8486 
    8587    unsigned             tx_drop_pct;   /**< Percent of tx pkts to drop.    */ 
     
    194196static const pj_str_t STR_IP6           = { "IP6", 3 }; 
    195197static const pj_str_t STR_RTCP          = { "rtcp", 4 }; 
     198static const pj_str_t STR_RTCP_MUX      = { "rtcp-mux", 8 }; 
    196199static const pj_str_t STR_BANDW_RR      = { "RR", 2 }; 
    197200static const pj_str_t STR_BANDW_RS      = { "RS", 2 }; 
     
    505508                                         unsigned media_index, 
    506509                                         unsigned comp_cnt, 
    507                                          pj_bool_t restart_session) 
     510                                         pj_bool_t restart_session, 
     511                                         pj_bool_t rtcp_mux) 
    508512{ 
    509513    enum {  
     
    759763        } 
    760764    } 
    761      
     765 
     766    /* Add a=rtcp-mux attribute */ 
     767    if (rtcp_mux) { 
     768        pjmedia_sdp_attr *attr; 
     769 
     770        attr = PJ_POOL_ZALLOC_T(sdp_pool, pjmedia_sdp_attr); 
     771        attr->name = STR_RTCP_MUX; 
     772        m->attr[m->attr_count++] = attr; 
     773    } 
    762774 
    763775    return PJ_SUCCESS; 
     
    895907    /* Encode ICE in SDP */ 
    896908    status = encode_session_in_sdp(tp_ice, sdp_pool, loc_sdp, media_index,  
    897                                    tp_ice->comp_cnt, PJ_FALSE); 
     909                                   tp_ice->comp_cnt, PJ_FALSE, 
     910                                   tp_ice->enable_rtcp_mux); 
    898911    if (status != PJ_SUCCESS) { 
    899912        set_no_ice(tp_ice, "Error encoding SDP answer", status); 
     
    923936 
    924937    rem_m = rem_sdp->media[media_index]; 
     938 
     939    /* Check if remote wants RTCP mux */ 
     940    if (tp_ice->enable_rtcp_mux) { 
     941        pjmedia_sdp_attr *attr; 
     942 
     943        attr = pjmedia_sdp_attr_find(rem_m->attr_count, rem_m->attr,  
     944                                     &STR_RTCP_MUX, NULL); 
     945        tp_ice->use_rtcp_mux = (attr? PJ_TRUE: PJ_FALSE); 
     946    } 
    925947 
    926948    /* Get the "ice-ufrag" and "ice-pwd" attributes */ 
     
    10641086 
    10651087    /* Check matched component count and ice_mismatch */ 
    1066     if (comp1_found && (tp_ice->comp_cnt==1 || !has_rtcp)) { 
     1088    if (comp1_found && 
     1089        (tp_ice->comp_cnt==1 || !has_rtcp || tp_ice->use_rtcp_mux)) 
     1090    { 
    10671091        sdp_state->match_comp_cnt = 1; 
    10681092        sdp_state->ice_mismatch = PJ_FALSE; 
     
    11231147} 
    11241148 
     1149/* Encode information in SDP if ICE is not used */ 
     1150static pj_status_t encode_no_ice_in_sdp( struct transport_ice *tp_ice, 
     1151                                         pj_pool_t *pool, 
     1152                                         pjmedia_sdp_session *sdp_local, 
     1153                                         const pjmedia_sdp_session *rem_sdp, 
     1154                                         unsigned media_index) 
     1155{ 
     1156    if (tp_ice->enable_rtcp_mux) { 
     1157        pjmedia_sdp_media *m = sdp_local->media[media_index]; 
     1158        pjmedia_sdp_attr *attr; 
     1159        pj_bool_t add_rtcp_mux = PJ_TRUE; 
     1160 
     1161        if (rem_sdp) 
     1162            add_rtcp_mux = tp_ice->use_rtcp_mux; 
     1163        else { 
     1164            /* For subsequent offer, set it to false first since 
     1165             * we are still waiting for remote answer. 
     1166             */ 
     1167            tp_ice->use_rtcp_mux = PJ_FALSE; 
     1168        } 
     1169 
     1170        /* Remove RTCP attribute because for subsequent offers/answers, 
     1171         * the address (obtained from transport_get_info() ) may be 
     1172         * incorrect if we are not yet confirmed to use RTCP mux 
     1173         * (because we are still waiting for remote answer) or 
     1174         * if remote rejects it. 
     1175         */ 
     1176        pjmedia_sdp_attr_remove_all(&m->attr_count, m->attr, "rtcp"); 
     1177         
     1178        if (!tp_ice->use_rtcp_mux && tp_ice->comp_cnt > 1) { 
     1179            pj_ice_sess_cand cand; 
     1180            pj_status_t status; 
     1181             
     1182            status = pj_ice_strans_get_def_cand(tp_ice->ice_st, 2, &cand); 
     1183            if (status == PJ_SUCCESS) { 
     1184                /* Add RTCP attribute if the remote doesn't offer or 
     1185                 * rejects it. 
     1186                 */ 
     1187                attr = pjmedia_sdp_attr_create_rtcp(pool, &cand.addr);   
     1188                if (attr) 
     1189                    pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr); 
     1190            } 
     1191        } 
     1192 
     1193        /* Add a=rtcp-mux attribute. */ 
     1194        if (add_rtcp_mux) { 
     1195            attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr); 
     1196            attr->name = STR_RTCP_MUX; 
     1197            m->attr[m->attr_count++] = attr; 
     1198        } 
     1199    } 
     1200    return PJ_SUCCESS; 
     1201} 
     1202 
    11251203 
    11261204/* Verify incoming offer and create initial answer */ 
     
    11511229    if (tp_ice->rem_offer_state.match_comp_cnt==0) { 
    11521230        set_no_ice(tp_ice, "No ICE found in SDP offer", PJ_SUCCESS); 
     1231        encode_no_ice_in_sdp(tp_ice, sdp_pool, loc_sdp, rem_sdp, 
     1232                             media_index); 
    11531233        return PJ_SUCCESS; 
    11541234    } 
     
    11641244    status = encode_session_in_sdp(tp_ice, sdp_pool, loc_sdp, media_index,  
    11651245                                   tp_ice->rem_offer_state.match_comp_cnt, 
    1166                                    PJ_FALSE); 
     1246                                   PJ_FALSE, tp_ice->use_rtcp_mux); 
    11671247    if (status != PJ_SUCCESS) { 
    11681248        set_no_ice(tp_ice, "Error encoding SDP answer", status); 
     
    11841264    if (pj_ice_strans_has_sess(tp_ice->ice_st) == PJ_FALSE) { 
    11851265        /* We don't have ICE */ 
     1266        encode_no_ice_in_sdp(tp_ice, sdp_pool, loc_sdp, NULL, media_index); 
    11861267        return PJ_SUCCESS; 
    11871268    } 
     
    11891270    comp_cnt = pj_ice_strans_get_running_comp_cnt(tp_ice->ice_st); 
    11901271    return encode_session_in_sdp(tp_ice, sdp_pool, loc_sdp, media_index, 
    1191                                  comp_cnt, PJ_FALSE); 
     1272                                 comp_cnt, PJ_FALSE, tp_ice->enable_rtcp_mux); 
    11921273} 
    11931274 
     
    12181299        if (tp_ice->rem_offer_state.match_comp_cnt == 0) { 
    12191300            /* Remote no longer offers ICE */ 
     1301            encode_no_ice_in_sdp(tp_ice, sdp_pool, loc_sdp, rem_sdp, 
     1302                                 media_index); 
    12201303            return PJ_SUCCESS; 
    12211304        } 
     
    12281311        status = encode_session_in_sdp(tp_ice, sdp_pool, loc_sdp, media_index, 
    12291312                                       tp_ice->rem_offer_state.match_comp_cnt, 
    1230                                        tp_ice->rem_offer_state.ice_restart); 
     1313                                       tp_ice->rem_offer_state.ice_restart, 
     1314                                       tp_ice->use_rtcp_mux); 
    12311315        if (status != PJ_SUCCESS) 
    12321316            return status; 
     
    12411325        if (tp_ice->rem_offer_state.match_comp_cnt == 0) { 
    12421326            /* Remote does not support ICE */ 
     1327            encode_no_ice_in_sdp(tp_ice, sdp_pool, loc_sdp, rem_sdp, 
     1328                                 media_index); 
    12431329            return PJ_SUCCESS; 
    12441330        } 
     
    12621348        status = encode_session_in_sdp(tp_ice, sdp_pool, loc_sdp, media_index, 
    12631349                                       tp_ice->rem_offer_state.match_comp_cnt, 
    1264                                        tp_ice->rem_offer_state.ice_restart); 
     1350                                       tp_ice->rem_offer_state.ice_restart, 
     1351                                       tp_ice->use_rtcp_mux); 
    12651352        if (status != PJ_SUCCESS) 
    12661353            return status; 
     
    12911378 
    12921379    tp_ice->media_option = options; 
     1380    tp_ice->enable_rtcp_mux = ((options & PJMEDIA_TPMED_RTCP_MUX) != 0); 
    12931381    tp_ice->oa_role = ROLE_NONE; 
    12941382    tp_ice->initial_sdp = PJ_TRUE; 
     
    14021490        } 
    14031491 
    1404         cand_cnt++; 
     1492        if (!tp_ice->use_rtcp_mux || cand[cand_cnt].comp_id < 2) 
     1493            cand_cnt++; 
    14051494    } 
    14061495 
     
    16551744 
    16561745    /* Get RTCP default address */ 
    1657     if (tp_ice->comp_cnt > 1) { 
     1746    if (tp_ice->use_rtcp_mux) { 
     1747        pj_sockaddr_cp(&info->sock_info.rtcp_addr_name, &cand.addr); 
     1748    } else if (tp_ice->comp_cnt > 1) { 
    16581749        status = pj_ice_strans_get_def_cand(tp_ice->ice_st, 2, &cand); 
    16591750        if (status != PJ_SUCCESS) 
     
    17501841    tp_ice->rtcp_cb = att_param->rtcp_cb; 
    17511842 
     1843    /* Check again if we are multiplexing RTP & RTCP. */ 
     1844    tp_ice->use_rtcp_mux = (pj_sockaddr_has_addr(&att_param->rem_addr) && 
     1845                            pj_sockaddr_cmp(&att_param->rem_addr, 
     1846                                            &att_param->rem_rtcp) == 0); 
     1847 
    17521848    pj_memcpy(&tp_ice->remote_rtp, &att_param->rem_addr, att_param->addr_len); 
    17531849    pj_memcpy(&tp_ice->remote_rtcp, &att_param->rem_rtcp, att_param->addr_len); 
     
    18151911{ 
    18161912    struct transport_ice *tp_ice = (struct transport_ice*)tp; 
    1817     if (tp_ice->comp_cnt > 1) { 
     1913 
     1914    if (tp_ice->comp_cnt > 1 || tp_ice->use_rtcp_mux) { 
     1915        unsigned comp_id = (tp_ice->use_rtcp_mux? 1: 2); 
    18181916        if (addr == NULL) { 
    18191917            addr = &tp_ice->remote_rtcp; 
    18201918            addr_len = pj_sockaddr_get_len(addr); 
    1821         } 
    1822         return pj_ice_strans_sendto(tp_ice->ice_st, 2, pkt, size,  
     1919        }          
     1920        return pj_ice_strans_sendto(tp_ice->ice_st, comp_id, pkt, size, 
    18231921                                    addr, addr_len); 
    18241922    } else { 
     
    18891987                                        sizeof(addr_text), 3))); 
    18901988 
    1891             /* Also update remote RTCP address if actual RTCP source 
    1892              * address is not heard yet. 
    1893              */ 
    1894             if (!pj_sockaddr_has_addr(&tp_ice->rtcp_src_addr)) { 
     1989            if (tp_ice->use_rtcp_mux) { 
     1990                pj_sockaddr_cp(&tp_ice->remote_rtcp, &tp_ice->remote_rtp); 
     1991            } else if (!pj_sockaddr_has_addr(&tp_ice->rtcp_src_addr)) { 
     1992                /* Also update remote RTCP address if actual RTCP source 
     1993                 * address is not heard yet. 
     1994                 */ 
    18951995                pj_uint16_t port; 
    18961996 
Note: See TracChangeset for help on using the changeset viewer.