Ignore:
Timestamp:
May 15, 2019 12:09:57 AM (5 years ago)
Author:
ming
Message:

Fixed #2107: Add option to use loopback media transport in pjsua

File:
1 edited

Legend:

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

    r3553 r5989  
    3636                        void*, 
    3737                        pj_ssize_t); 
     38    void  (*rtp_cb2)(   pjmedia_tp_cb_param*); 
    3839    void  (*rtcp_cb)(   void*,          /**< To report incoming RTCP.       */ 
    3940                        void*, 
     
    4849    unsigned            user_cnt;       /**< Number of attachments          */ 
    4950    struct user         users[4];       /**< Array of users.                */ 
     51    pj_bool_t           disable_rx;     /**< Disable RX.                    */ 
     52 
     53    pjmedia_loop_tp_setting setting;    /**< Setting.                       */ 
    5054 
    5155    unsigned            tx_drop_pct;    /**< Percent of tx pkts to drop.    */ 
     
    7276                                                       void*, 
    7377                                                       pj_ssize_t)); 
     78static pj_status_t transport_attach2  (pjmedia_transport *tp, 
     79                                       pjmedia_transport_attach_param 
     80                                           *att_param); 
    7481static void        transport_detach   (pjmedia_transport *tp, 
    7582                                       void *strm); 
     
    120127    &transport_media_stop, 
    121128    &transport_simulate_lost, 
    122     &transport_destroy 
     129    &transport_destroy, 
     130    &transport_attach2 
    123131}; 
     132 
     133 
     134/** 
     135 * Initialize loopback media transport setting with its default values. 
     136 */ 
     137PJ_DEF(void) pjmedia_loop_tp_setting_default(pjmedia_loop_tp_setting *opt) 
     138{ 
     139    pj_bzero(opt, sizeof(pjmedia_loop_tp_setting)); 
     140     
     141    opt->af = pj_AF_INET(); 
     142} 
    124143 
    125144 
     
    130149                                                  pjmedia_transport **p_tp) 
    131150{ 
     151    pjmedia_loop_tp_setting opt; 
     152     
     153    pj_bzero(&opt, sizeof(opt)); 
     154    opt.af = pj_AF_INET(); 
     155 
     156    return pjmedia_transport_loop_create2(endpt, &opt, p_tp); 
     157} 
     158 
     159 
     160PJ_DEF(pj_status_t) 
     161pjmedia_transport_loop_create2(pjmedia_endpt *endpt, 
     162                               const pjmedia_loop_tp_setting *opt, 
     163                               pjmedia_transport **p_tp) 
     164{ 
    132165    struct transport_loop *tp; 
    133166    pj_pool_t *pool; 
     
    147180    tp->base.type = PJMEDIA_TRANSPORT_TYPE_UDP; 
    148181 
     182    if (opt) { 
     183        tp->setting = *opt; 
     184    } else { 
     185        pjmedia_loop_tp_setting_default(&tp->setting); 
     186    } 
     187    if (tp->setting.addr.slen) { 
     188        pj_strdup(pool, &tp->setting.addr, &opt->addr); 
     189    } else { 
     190        pj_strset2(&tp->setting.addr, (opt->af == pj_AF_INET())? 
     191                                       "127.0.0.1": "::1"); 
     192    } 
     193    if (tp->setting.port == 0) 
     194        tp->setting.port = 4000; 
     195 
    149196    /* Done */ 
    150197    *p_tp = &tp->base; 
     
    190237                                      pjmedia_transport_info *info) 
    191238{ 
    192     PJ_ASSERT_RETURN(tp && info, PJ_EINVAL); 
     239    struct transport_loop *loop = (struct transport_loop*) tp; 
    193240 
    194241    info->sock_info.rtp_sock = 1; 
    195     pj_sockaddr_in_init(&info->sock_info.rtp_addr_name.ipv4, 0, 0); 
     242    pj_sockaddr_init(loop->setting.af, &info->sock_info.rtp_addr_name,  
     243                     &loop->setting.addr, loop->setting.port); 
    196244    info->sock_info.rtcp_sock = 2; 
    197     pj_sockaddr_in_init(&info->sock_info.rtcp_addr_name.ipv4, 0, 0); 
     245    pj_sockaddr_init(loop->setting.af, &info->sock_info.rtcp_addr_name, 
     246                     &loop->setting.addr, loop->setting.port + 1); 
    198247 
    199248    return PJ_SUCCESS; 
     
    202251 
    203252/* Called by application to initialize the transport */ 
     253static pj_status_t tp_attach(   pjmedia_transport *tp, 
     254                                       void *user_data, 
     255                                       const pj_sockaddr_t *rem_addr, 
     256                                       const pj_sockaddr_t *rem_rtcp, 
     257                                       unsigned addr_len, 
     258                                       void (*rtp_cb)(void*, 
     259                                                      void*, 
     260                                                      pj_ssize_t), 
     261                                       void (*rtp_cb2)(pjmedia_tp_cb_param*), 
     262                                       void (*rtcp_cb)(void*, 
     263                                                       void*, 
     264                                                       pj_ssize_t)) 
     265{ 
     266    struct transport_loop *loop = (struct transport_loop*) tp; 
     267    unsigned i; 
     268    const pj_sockaddr *rtcp_addr; 
     269 
     270    /* Validate arguments */ 
     271    PJ_ASSERT_RETURN(tp && rem_addr && addr_len, PJ_EINVAL); 
     272 
     273    /* Must not be "attached" to same user */ 
     274    for (i=0; i<loop->user_cnt; ++i) { 
     275        PJ_ASSERT_RETURN(loop->users[i].user_data != user_data, 
     276                         PJ_EINVALIDOP); 
     277    } 
     278    PJ_ASSERT_RETURN(loop->user_cnt != PJ_ARRAY_SIZE(loop->users),  
     279                     PJ_ETOOMANY); 
     280 
     281    PJ_UNUSED_ARG(rem_rtcp); 
     282    PJ_UNUSED_ARG(rtcp_addr); 
     283 
     284    /* "Attach" the application: */ 
     285 
     286    /* Save the new user */ 
     287    loop->users[loop->user_cnt].rtp_cb = rtp_cb; 
     288    loop->users[loop->user_cnt].rtp_cb2 = rtp_cb2; 
     289    loop->users[loop->user_cnt].rtcp_cb = rtcp_cb; 
     290    loop->users[loop->user_cnt].user_data = user_data; 
     291    loop->users[loop->user_cnt].rx_disabled = loop->disable_rx; 
     292    ++loop->user_cnt; 
     293 
     294    return PJ_SUCCESS; 
     295} 
     296 
    204297static pj_status_t transport_attach(   pjmedia_transport *tp, 
    205298                                       void *user_data, 
     
    214307                                                       pj_ssize_t)) 
    215308{ 
    216     struct transport_loop *loop = (struct transport_loop*) tp; 
    217     unsigned i; 
    218     const pj_sockaddr *rtcp_addr; 
    219  
    220     /* Validate arguments */ 
    221     PJ_ASSERT_RETURN(tp && rem_addr && addr_len, PJ_EINVAL); 
    222  
    223     /* Must not be "attached" to same user */ 
    224     for (i=0; i<loop->user_cnt; ++i) { 
    225         PJ_ASSERT_RETURN(loop->users[i].user_data != user_data, 
    226                          PJ_EINVALIDOP); 
    227     } 
    228     PJ_ASSERT_RETURN(loop->user_cnt != PJ_ARRAY_SIZE(loop->users),  
    229                      PJ_ETOOMANY); 
    230  
    231     PJ_UNUSED_ARG(rem_rtcp); 
    232     PJ_UNUSED_ARG(rtcp_addr); 
    233  
    234     /* "Attach" the application: */ 
    235  
    236     /* Save the new user */ 
    237     loop->users[loop->user_cnt].rtp_cb = rtp_cb; 
    238     loop->users[loop->user_cnt].rtcp_cb = rtcp_cb; 
    239     loop->users[loop->user_cnt].user_data = user_data; 
    240     ++loop->user_cnt; 
    241  
    242     return PJ_SUCCESS; 
     309    return tp_attach(tp, user_data, rem_addr, rem_rtcp, addr_len, 
     310                     rtp_cb, NULL, rtcp_cb); 
     311} 
     312 
     313static pj_status_t transport_attach2(pjmedia_transport *tp, 
     314                                     pjmedia_transport_attach_param *att_param) 
     315{ 
     316    return tp_attach(tp, att_param->user_data,  
     317                            (pj_sockaddr_t*)&att_param->rem_addr,  
     318                            (pj_sockaddr_t*)&att_param->rem_rtcp,  
     319                            att_param->addr_len, att_param->rtp_cb, 
     320                            att_param->rtp_cb2,  
     321                            att_param->rtcp_cb); 
    243322} 
    244323 
     
    297376    /* Distribute to users */ 
    298377    for (i=0; i<loop->user_cnt; ++i) { 
    299         if (!loop->users[i].rx_disabled && loop->users[i].rtp_cb) 
     378        if (loop->users[i].rx_disabled) continue; 
     379        if (loop->users[i].rtp_cb2) { 
     380            pjmedia_tp_cb_param param; 
     381 
     382            pj_bzero(&param, sizeof(param)); 
     383            param.user_data = loop->users[i].user_data; 
     384            param.pkt = (void *)pkt; 
     385            param.size = size; 
     386            (*loop->users[i].rtp_cb2)(&param); 
     387        } else if (loop->users[i].rtp_cb) { 
    300388            (*loop->users[i].rtp_cb)(loop->users[i].user_data, (void*)pkt,  
    301389                                     size); 
     390        } 
    302391    } 
    303392 
Note: See TracChangeset for help on using the changeset viewer.