Changeset 5788


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

Fixed #2087: Support for RTP and RTCP multiplexing

Location:
pjproject/trunk
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/include/pjmedia/stream.h

    r5748 r5788  
    9999                                         sin_family is zero, the RTP address 
    100100                                         will be calculated from RTP.       */ 
     101    pj_bool_t           rtcp_mux;   /**< Use RTP and RTCP multiplexing.     */ 
    101102#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0) 
    102103    pj_bool_t           rtcp_xr_enabled; 
  • pjproject/trunk/pjmedia/include/pjmedia/transport.h

    r5752 r5788  
    258258     * transport SRTP. 
    259259     */ 
    260     PJMEDIA_TPMED_NO_TRANSPORT_CHECKING = 1 
     260    PJMEDIA_TPMED_NO_TRANSPORT_CHECKING = 1, 
     261 
     262    /** 
     263     * When this flag is specified, the transport will allow multiplexing 
     264     * RTP and RTCP, i.e. if the remote agrees, RTCP will be sent using 
     265     * the same socket for RTP. 
     266     */ 
     267    PJMEDIA_TPMED_RTCP_MUX = 2 
    261268 
    262269} pjmedia_tranport_media_option; 
  • pjproject/trunk/pjmedia/include/pjmedia/vid_stream.h

    r5748 r5788  
    156156                                         sin_family is zero, the RTP address 
    157157                                         will be calculated from RTP.       */ 
     158    pj_bool_t           rtcp_mux;   /**< Use RTP and RTCP multiplexing.     */ 
    158159    unsigned            tx_pt;      /**< Outgoing codec paylaod type.       */ 
    159160    unsigned            rx_pt;      /**< Incoming codec paylaod type.       */ 
  • pjproject/trunk/pjmedia/src/pjmedia/stream.c

    r5786 r5788  
    272272} 
    273273 
     274static void on_rx_rtcp( void *data, 
     275                        void *pkt, 
     276                        pj_ssize_t bytes_read); 
    274277 
    275278static pj_status_t send_rtcp(pjmedia_stream *stream, 
     
    17161719        stream->rtcp.stat.rx.discard++; 
    17171720        return; 
     1721    } 
     1722     
     1723    /* Check if multiplexing is allowed and the payload indicates RTCP. */ 
     1724    if (stream->si.rtcp_mux && hdr->pt >= 64 && hdr->pt <= 95) { 
     1725        on_rx_rtcp(stream, pkt, bytes_read); 
     1726        return; 
    17181727    } 
    17191728 
     
    25042513    pj_sockaddr_cp(&att_param.rem_addr, &info->rem_addr); 
    25052514    pj_sockaddr_cp(&stream->rem_rtp_addr, &info->rem_addr); 
    2506     if (pj_sockaddr_has_addr(&info->rem_rtcp.addr)) 
     2515    if (stream->si.rtcp_mux) { 
     2516        pj_sockaddr_cp(&att_param.rem_rtcp, &info->rem_addr);            
     2517    } else if (pj_sockaddr_has_addr(&info->rem_rtcp.addr)) { 
    25072518        pj_sockaddr_cp(&att_param.rem_rtcp, &info->rem_rtcp); 
     2519    } 
    25082520    att_param.addr_len = pj_sockaddr_get_len(&info->rem_addr); 
    25092521    att_param.rtp_cb2 = &on_rx_rtp; 
  • pjproject/trunk/pjmedia/src/pjmedia/stream_info.c

    r5748 r5788  
    526526    } 
    527527 
     528    /* Check if "rtcp-mux" is present in the SDP. */ 
     529    attr = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr, 
     530                                  "rtcp-mux", NULL); 
     531    if (attr) 
     532        si->rtcp_mux = PJ_TRUE; 
     533 
    528534    /* If "rtcp" attribute is present in the SDP, set the RTCP address 
    529535     * from that attribute. Otherwise, calculate from RTP address. 
  • 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 
  • pjproject/trunk/pjmedia/src/pjmedia/transport_srtp.c

    r5781 r5788  
    234234    pjmedia_srtp_setting setting; 
    235235    unsigned             media_option; 
     236    pj_bool_t            use_rtcp_mux;      /**< Use RTP& RTCP multiplexing?*/ 
    236237 
    237238    /* SRTP policy */ 
     
    11381139    } 
    11391140 
     1141    /* Check if we are multiplexing RTP & RTCP. */ 
     1142    srtp->use_rtcp_mux = (pj_sockaddr_has_addr(&param->rem_addr) && 
     1143                          pj_sockaddr_cmp(&param->rem_addr, 
     1144                                          &param->rem_rtcp) == 0); 
    11401145    srtp->member_tp_attached = PJ_TRUE; 
    11411146    return PJ_SUCCESS; 
     
    13471352        return; 
    13481353    } 
     1354 
     1355    /* Check if multiplexing is allowed and the payload indicates RTCP. */ 
     1356    if (srtp->use_rtcp_mux) { 
     1357        pjmedia_rtp_hdr *hdr = (pjmedia_rtp_hdr *)pkt; 
     1358   
     1359        if (hdr->pt >= 64 && hdr->pt <= 95) {    
     1360            pj_lock_release(srtp->mutex); 
     1361            srtp_rtcp_cb(srtp, pkt, size); 
     1362            return; 
     1363        } 
     1364    } 
     1365     
    13491366    err = srtp_unprotect(srtp->srtp_rx_ctx, (pj_uint8_t*)pkt, &len); 
     1367     
    13501368    if (srtp->probation_cnt > 0 && 
    13511369        (err == srtp_err_status_replay_old || 
  • pjproject/trunk/pjmedia/src/pjmedia/transport_srtp_dtls.c

    r5783 r5788  
    986986            pj_sockaddr_cp(&ap.rem_addr, &ds->rem_addr); 
    987987            ap.addr_len = pj_sockaddr_get_len(&ap.rem_addr); 
    988             if (pj_sockaddr_has_addr(&ds->rem_rtcp)) { 
     988            if (pj_sockaddr_cmp(&info.sock_info.rtp_addr_name, 
     989                                &info.sock_info.rtcp_addr_name) == 0) 
     990            { 
     991                /* Using RTP & RTCP multiplexing */ 
     992                pj_sockaddr_cp(&ds->rem_rtcp, &ds->rem_addr); 
     993                pj_sockaddr_cp(&ap.rem_rtcp, &ds->rem_rtcp); 
     994            } else if (pj_sockaddr_has_addr(&ds->rem_rtcp)) { 
    989995                pj_sockaddr_cp(&ap.rem_rtcp, &ds->rem_rtcp); 
    990996            } else { 
     
    11871193    { 
    11881194        pjmedia_transport_attach_param ap; 
     1195        pjmedia_transport_info info; 
     1196 
    11891197        pj_bzero(&ap, sizeof(ap)); 
    11901198        ap.user_data = ds->srtp; 
     1199        pjmedia_transport_get_info(ds->srtp->member_tp, &info); 
    11911200 
    11921201        if (sdp_remote) 
    11931202            get_rem_addrs(ds, sdp_remote, media_index); 
    11941203 
    1195         if (pj_sockaddr_has_addr(&ds->rem_addr)) 
     1204        if (pj_sockaddr_has_addr(&ds->rem_addr)) { 
    11961205            pj_sockaddr_cp(&ap.rem_addr, &ds->rem_addr); 
    1197         else 
     1206        } else if (pj_sockaddr_has_addr(&info.sock_info.rtp_addr_name)) { 
     1207            pj_sockaddr_cp(&ap.rem_addr, &info.sock_info.rtp_addr_name); 
     1208        } else { 
    11981209            pj_sockaddr_init(pj_AF_INET(), &ap.rem_addr, 0, 0); 
    1199  
    1200         if (pj_sockaddr_has_addr(&ds->rem_rtcp)) 
     1210        } 
     1211 
     1212        if (pj_sockaddr_cmp(&info.sock_info.rtp_addr_name, 
     1213                            &info.sock_info.rtcp_addr_name) == 0) 
     1214        { 
     1215            /* Using RTP & RTCP multiplexing */ 
     1216            pj_sockaddr_cp(&ap.rem_rtcp, &ap.rem_addr); 
     1217        } else if (pj_sockaddr_has_addr(&ds->rem_rtcp)) { 
    12011218            pj_sockaddr_cp(&ap.rem_rtcp, &ds->rem_rtcp); 
    1202         else 
     1219        } else if (pj_sockaddr_has_addr(&info.sock_info.rtcp_addr_name)) { 
     1220            pj_sockaddr_cp(&ap.rem_rtcp, &info.sock_info.rtcp_addr_name); 
     1221        } else { 
    12031222            pj_sockaddr_init(pj_AF_INET(), &ap.rem_rtcp, 0, 0); 
     1223        } 
    12041224 
    12051225        ap.addr_len = pj_sockaddr_get_len(&ap.rem_addr); 
  • pjproject/trunk/pjmedia/src/pjmedia/transport_udp.c

    r5783 r5788  
    8383    char                rtp_pkt[RTP_LEN];/**< Incoming RTP packet buffer    */ 
    8484 
     85    pj_bool_t           enable_rtcp_mux;/**< Enable RTP & RTCP multiplexing?*/ 
     86    pj_bool_t           use_rtcp_mux;   /**< Use RTP & RTCP multiplexing?   */ 
    8587    pj_sock_t           rtcp_sock;      /**< RTCP socket                    */ 
    8688    pj_sockaddr         rtcp_addr_name; /**< Published RTCP address.        */ 
     
    179181}; 
    180182 
     183static const pj_str_t STR_RTCP_MUX      = { "rtcp-mux", 8 }; 
    181184 
    182185/** 
     
    398401    if (status != PJ_EPENDING) 
    399402        goto on_error; 
    400 #endif     
     403#endif   
    401404 
    402405    tp->ioqueue = ioqueue; 
     
    535538                                        sizeof(addr_text), 3))); 
    536539 
    537             /* Also update remote RTCP address if actual RTCP source 
    538              * address is not heard yet. 
    539              */ 
    540             if (!pj_sockaddr_has_addr(&udp->rtcp_src_addr)) { 
     540            if (udp->use_rtcp_mux) { 
     541                pj_sockaddr_cp(&udp->rem_rtcp_addr, &udp->rem_rtp_addr); 
     542                pj_sockaddr_cp(&udp->rtcp_src_addr, &udp->rem_rtcp_addr); 
     543            } else if (!pj_sockaddr_has_addr(&udp->rtcp_src_addr)) { 
     544                /* Also update remote RTCP address if actual RTCP source 
     545                 * address is not heard yet. 
     546                 */ 
    541547                pj_uint16_t port; 
    542548 
     
    666672    info->sock_info.rtp_addr_name = udp->rtp_addr_name; 
    667673    info->sock_info.rtcp_sock = udp->rtcp_sock; 
    668     info->sock_info.rtcp_addr_name = udp->rtcp_addr_name; 
     674    info->sock_info.rtcp_addr_name = (udp->use_rtcp_mux? 
     675                                      udp->rtp_addr_name: 
     676                                      udp->rtcp_addr_name); 
    669677 
    670678    /* Get remote address originating RTP & RTCP. */ 
     
    709717    /* Must not be "attached" to existing application */ 
    710718    //PJ_ASSERT_RETURN(!udp->attached, PJ_EINVALIDOP); 
     719 
     720    /* Check again if we are multiplexing RTP & RTCP. */ 
     721    udp->use_rtcp_mux = (pj_sockaddr_has_addr(rem_addr) && 
     722                         pj_sockaddr_cmp(rem_addr, rem_rtcp) == 0); 
    711723 
    712724    /* Lock the ioqueue keys to make sure that callbacks are 
     
    978990 
    979991    sent = size; 
    980     status = pj_ioqueue_sendto( udp->rtcp_key, &udp->rtcp_write_op, 
     992    status = pj_ioqueue_sendto( (udp->use_rtcp_mux? udp->rtp_key: 
     993                                 udp->rtcp_key), &udp->rtcp_write_op, 
    981994                                pkt, &sent, 0, addr, addr_len); 
    982995 
     
    9981011    PJ_ASSERT_RETURN(tp && pool, PJ_EINVAL); 
    9991012    udp->media_options = options; 
     1013    udp->enable_rtcp_mux = ((options & PJMEDIA_TPMED_RTCP_MUX) != 0); 
    10001014 
    10011015    PJ_UNUSED_ARG(sdp_remote); 
     
    10261040            pjmedia_sdp_media_deactivate(pool, m_loc); 
    10271041            return PJMEDIA_SDP_EINPROTO; 
     1042        } 
     1043    } 
     1044     
     1045    if (udp->enable_rtcp_mux) { 
     1046        pjmedia_sdp_media *m = sdp_local->media[media_index]; 
     1047        pjmedia_sdp_attr *attr; 
     1048        pj_bool_t add_rtcp_mux = PJ_TRUE; 
     1049 
     1050        udp->use_rtcp_mux = PJ_FALSE; 
     1051 
     1052        /* Check if remote wants RTCP mux */ 
     1053        if (rem_sdp) { 
     1054            pjmedia_sdp_media *rem_m = rem_sdp->media[media_index]; 
     1055             
     1056            attr = pjmedia_sdp_attr_find(rem_m->attr_count, rem_m->attr,  
     1057                                         &STR_RTCP_MUX, NULL); 
     1058            udp->use_rtcp_mux = (attr? PJ_TRUE: PJ_FALSE); 
     1059            add_rtcp_mux = udp->use_rtcp_mux; 
     1060        } 
     1061 
     1062        /* Remove RTCP attribute because for subsequent offers/answers, 
     1063         * the address (obtained from transport_get_info() ) may be 
     1064         * incorrect if we are not yet confirmed to use RTCP mux 
     1065         * (because we are still waiting for remote answer) or 
     1066         * if remote rejects it. 
     1067         */ 
     1068        pjmedia_sdp_attr_remove_all(&m->attr_count, m->attr, "rtcp"); 
     1069         
     1070        if (!udp->use_rtcp_mux) { 
     1071           /* Add RTCP attribute if the remote doesn't offer or 
     1072            * rejects it. 
     1073            */ 
     1074            attr = pjmedia_sdp_attr_create_rtcp(pool, 
     1075                                                &udp->rtcp_addr_name);   
     1076            if (attr) 
     1077                pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr); 
     1078        } 
     1079 
     1080        /* Add a=rtcp-mux attribute. */ 
     1081        if (add_rtcp_mux) { 
     1082            attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr); 
     1083            attr->name = STR_RTCP_MUX; 
     1084            m->attr[m->attr_count++] = attr; 
    10281085        } 
    10291086    } 
  • pjproject/trunk/pjmedia/src/pjmedia/vid_stream.c

    r5752 r5788  
    219219                             pj_bool_t with_bye); 
    220220 
     221static void on_rx_rtcp( void *data, 
     222                        void *pkt,  
     223                        pj_ssize_t bytes_read); 
    221224 
    222225#if TRACE_JB 
     
    650653        stream->rtcp.stat.rx.discard++; 
    651654        return; 
     655    } 
     656 
     657    /* Check if multiplexing is allowed and the payload indicates RTCP. */ 
     658    if (stream->info.rtcp_mux && hdr->pt >= 64 && hdr->pt <= 95) { 
     659        on_rx_rtcp(stream, pkt, bytes_read); 
     660        return; 
    652661    } 
    653662 
     
    17371746    pj_sockaddr_cp(&att_param.rem_addr, &info->rem_addr); 
    17381747    pj_sockaddr_cp(&stream->rem_rtp_addr, &info->rem_addr); 
    1739     if (pj_sockaddr_has_addr(&info->rem_rtcp.addr)) 
    1740         pj_sockaddr_cp(&att_param.rem_rtcp, &info->rem_rtcp);     
     1748    if (info->rtcp_mux) { 
     1749        pj_sockaddr_cp(&att_param.rem_rtcp, &info->rem_addr);            
     1750    } else if (pj_sockaddr_has_addr(&info->rem_rtcp.addr)) { 
     1751        pj_sockaddr_cp(&att_param.rem_rtcp, &info->rem_rtcp); 
     1752    }     
    17411753    att_param.addr_len = pj_sockaddr_get_len(&info->rem_addr); 
    17421754    att_param.rtp_cb2 = &on_rx_rtp; 
  • pjproject/trunk/pjmedia/src/pjmedia/vid_stream_info.c

    r5748 r5788  
    349349    } 
    350350 
     351    /* Check if "rtcp-mux" is present in the SDP. */ 
     352    attr = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr, 
     353                                  "rtcp-mux", NULL); 
     354    if (attr) 
     355        si->rtcp_mux = PJ_TRUE; 
     356 
    351357    /* If "rtcp" attribute is present in the SDP, set the RTCP address 
    352358     * from that attribute. Otherwise, calculate from RTP address. 
  • pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app_config.c

    r5755 r5788  
    192192    puts  ("  --turn-user         TURN username"); 
    193193    puts  ("  --turn-passwd       TURN password"); 
     194    puts  ("  --rtcp-mux          Enable RTP & RTCP multiplexing (default: no)"); 
    194195#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) 
    195196    puts  ("  --srtp-keying       SRTP keying method for outgoing SDP offer."); 
     
    360361           OPT_USE_ICE, OPT_ICE_REGULAR, OPT_USE_SRTP, OPT_SRTP_SECURE, 
    361362           OPT_USE_TURN, OPT_ICE_MAX_HOSTS, OPT_ICE_NO_RTCP, OPT_TURN_SRV, 
    362            OPT_TURN_TCP, OPT_TURN_USER, OPT_TURN_PASSWD, OPT_SRTP_KEYING, 
     363           OPT_TURN_TCP, OPT_TURN_USER, OPT_TURN_PASSWD, OPT_RTCP_MUX, 
     364           OPT_SRTP_KEYING, 
    363365           OPT_PLAY_FILE, OPT_PLAY_TONE, OPT_RTP_PORT, OPT_ADD_CODEC, 
    364366           OPT_ILBC_MODE, OPT_REC_FILE, OPT_AUTO_REC, 
     
    453455        { "turn-user",  1, 0, OPT_TURN_USER}, 
    454456        { "turn-passwd",1, 0, OPT_TURN_PASSWD}, 
     457        { "rtcp-mux",   0, 0, OPT_RTCP_MUX}, 
    455458 
    456459#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) 
     
    10221025            break; 
    10231026 
     1027        case OPT_RTCP_MUX: 
     1028            cur_acc->enable_rtcp_mux = PJ_TRUE; 
     1029            break; 
     1030 
    10241031#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) 
    10251032        case OPT_USE_SRTP: 
     
    17611768        pj_strcat2(result, line); 
    17621769    } 
     1770 
     1771    if (acc_cfg->enable_rtcp_mux) 
     1772        pj_strcat2(result, "--rtcp-mux\n"); 
    17631773} 
    17641774 
  • pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h

    r5755 r5788  
    39083908    pjsua_ip_change_acc_cfg ip_change_cfg; 
    39093909 
     3910    /** 
     3911     * Enable RTP and RTCP multiplexing. 
     3912     */ 
     3913    pj_bool_t           enable_rtcp_mux; 
     3914 
    39103915} pjsua_acc_config; 
    39113916 
  • pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h

    r5748 r5788  
    8484    pjsua_med_tp_st      tp_st;     /**< Media transport state              */ 
    8585    pj_bool_t            use_custom_med_tp;/**< Use custom media transport? */ 
     86    pj_bool_t            enable_rtcp_mux;/**< Enable RTP& RTCP multiplexing?*/ 
    8687    pj_sockaddr          rtp_addr;  /**< Current RTP source address 
    8788                                            (used to update ICE default 
  • pjproject/trunk/pjsip/include/pjsua2/account.hpp

    r5775 r5788  
    850850    pjsua_ipv6_use      ipv6Use; 
    851851 
     852    /** 
     853     * Enable RTP and RTCP multiplexing. 
     854     */ 
     855    pj_bool_t           rtcpMuxEnabled; 
     856 
    852857public: 
    853858    /** 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_acc.c

    r5784 r5788  
    13391339    acc->cfg.nat64_opt = cfg->nat64_opt; 
    13401340    acc->cfg.ipv6_media_use = cfg->ipv6_media_use; 
     1341    acc->cfg.enable_rtcp_mux = cfg->enable_rtcp_mux; 
    13411342 
    13421343    /* STUN and Media customization */ 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c

    r5748 r5788  
    43894389        pjmedia_transport_media_stop(call_med->tp); 
    43904390        pjmedia_transport_media_create(call_med->tp, call->inv->pool_prov, 
    4391                                        0, NULL, mi); 
     4391                                       (call_med->enable_rtcp_mux? 
     4392                                        PJMEDIA_TPMED_RTCP_MUX: 0), 
     4393                                       NULL, mi); 
    43924394 
    43934395        PJ_LOG(4, (THIS_FILE, "Restarting ICE for media %d", mi)); 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c

    r5774 r5788  
    579579    pj_sockaddr_cp(&skinfo->rtcp_addr_name, &mapped_addr[1]); 
    580580 
    581     PJ_LOG(4,(THIS_FILE, "RTP socket reachable at %s", 
     581    PJ_LOG(4,(THIS_FILE, "RTP%s socket reachable at %s", 
     582              (call_med->enable_rtcp_mux? " & RTCP": ""), 
    582583              pj_sockaddr_print(&skinfo->rtp_addr_name, addr_buf, 
    583584                                sizeof(addr_buf), 3))); 
     
    18321833 
    18331834            if (call_med->tp) { 
     1835                unsigned options = (call_med->enable_rtcp_mux? 
     1836                                    PJMEDIA_TPMED_RTCP_MUX: 0); 
    18341837                status = pjmedia_transport_media_create( 
    18351838                             call_med->tp, tmp_pool, 
    1836                              0, call->async_call.rem_sdp, mi); 
     1839                             options, call->async_call.rem_sdp, mi); 
    18371840            } 
    18381841            if (status != PJ_SUCCESS) { 
     
    21542157 
    21552158        if (enabled) { 
     2159            call_med->enable_rtcp_mux = acc->cfg.enable_rtcp_mux; 
     2160 
    21562161            status = pjsua_call_media_init(call_med, media_type, 
    21572162                                           &acc->cfg.rtp_cfg, 
     
    27902795         * internally by ICE and does not need to cause media restart. 
    27912796         */ 
     2797        if (old_si->rtcp_mux != new_si->rtcp_mux) 
     2798            return PJ_TRUE; 
    27922799        if (!is_ice_running(call_med->tp) && 
    27932800            pj_sockaddr_cmp(&old_si->rem_addr, &new_si->rem_addr)) 
     
    28522859         * internally by ICE and does not need to cause media restart. 
    28532860         */ 
     2861        if (old_si->rtcp_mux != new_si->rtcp_mux) 
     2862            return PJ_TRUE; 
    28542863        if (!is_ice_running(call_med->tp) && 
    28552864            pj_sockaddr_cmp(&old_si->rem_addr, &new_si->rem_addr)) 
     
    30273036                             call_id, mi)); 
    30283037                goto on_check_med_status; 
     3038            } 
     3039 
     3040            /* Check if remote wants RTP and RTCP multiplexing, 
     3041             * but we don't enable it. 
     3042             */ 
     3043            if (si->rtcp_mux && !call_med->enable_rtcp_mux) { 
     3044                si->rtcp_mux = PJ_FALSE; 
    30293045            } 
    30303046 
     
    30713087 
    30723088                if (call->inv->following_fork) { 
     3089                    unsigned options = (call_med->enable_rtcp_mux? 
     3090                                        PJMEDIA_TPMED_RTCP_MUX: 0); 
    30733091                    /* Normally media transport will automatically restart 
    30743092                     * itself (if needed, based on info from the SDP) in 
     
    30883106                    status = pjmedia_transport_media_create(call_med->tp, 
    30893107                                                            tmp_pool, 
    3090                                                             0, NULL, mi); 
     3108                                                            options, NULL, mi); 
    30913109                    if (status != PJ_SUCCESS) { 
    30923110                        PJ_PERROR(1,(THIS_FILE, status, 
     
    32053223            } 
    32063224 
     3225            /* Check if remote wants RTP and RTCP multiplexing, 
     3226             * but we don't enable it. 
     3227             */ 
     3228            if (si->rtcp_mux && !call_med->enable_rtcp_mux) { 
     3229                si->rtcp_mux = PJ_FALSE; 
     3230            } 
     3231 
    32073232            /* Check if this media is changed */ 
    32083233            stream_info.type = PJMEDIA_TYPE_VIDEO; 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_vid.c

    r5748 r5788  
    17201720    pjmedia_sdp_media *sdp_m; 
    17211721    pjmedia_transport_info tpinfo; 
     1722    unsigned options; 
    17221723    pj_status_t status; 
    17231724 
     
    17581759 
    17591760    /* Init transport media */ 
    1760     status = pjmedia_transport_media_create(call_med->tp, pool, 0, 
     1761    options = (call_med->enable_rtcp_mux? PJMEDIA_TPMED_RTCP_MUX: 0); 
     1762    status = pjmedia_transport_media_create(call_med->tp, pool, options, 
    17611763                                            NULL, call_med->idx); 
    17621764    if (status != PJ_SUCCESS) 
     
    19091911        /* Init transport media */ 
    19101912        if (call_med->tp && call_med->tp_st == PJSUA_MED_TP_IDLE) { 
    1911             status = pjmedia_transport_media_create(call_med->tp, pool, 0, 
    1912                                                     NULL, call_med->idx); 
     1913            unsigned options = (call_med->enable_rtcp_mux? 
     1914                                PJMEDIA_TPMED_RTCP_MUX: 0); 
     1915            status = pjmedia_transport_media_create(call_med->tp, pool, 
     1916                                                    options, NULL, 
     1917                                                    call_med->idx); 
    19131918            if (status != PJ_SUCCESS) 
    19141919                goto on_error; 
  • pjproject/trunk/pjsip/src/pjsua2/account.cpp

    r5755 r5788  
    359359    NODE_READ_NUM_T   ( this_node, pjsua_ipv6_use, ipv6Use); 
    360360    NODE_READ_OBJ     ( this_node, transportConfig); 
     361    NODE_READ_BOOL    ( this_node, rtcpMuxEnabled); 
    361362} 
    362363 
     
    372373    NODE_WRITE_NUM_T   ( this_node, pjsua_ipv6_use, ipv6Use); 
    373374    NODE_WRITE_OBJ     ( this_node, transportConfig); 
     375    NODE_WRITE_BOOL    ( this_node, rtcpMuxEnabled); 
    374376} 
    375377 
     
    560562    ret.srtp_opt                = mediaConfig.srtpOpt.toPj(); 
    561563    ret.ipv6_media_use          = mediaConfig.ipv6Use; 
     564    ret.enable_rtcp_mux         = mediaConfig.rtcpMuxEnabled; 
    562565 
    563566    // AccountVideoConfig 
     
    735738    mediaConfig.srtpOpt.fromPj(prm.srtp_opt); 
    736739    mediaConfig.ipv6Use         = prm.ipv6_media_use; 
     740    mediaConfig.rtcpMuxEnabled  = prm.enable_rtcp_mux; 
    737741 
    738742    // AccountVideoConfig 
Note: See TracChangeset for help on using the changeset viewer.