Ignore:
Timestamp:
Apr 24, 2012 5:40:32 AM (12 years ago)
Author:
nanang
Message:

Fix #1423:

  • Added provisional media in call for generating initial and subsequent SDP offer/answer. If a reoffer is rejected by peer, the main call media will remain unchanged and the provisional media will be cleaned up (the cleanup is currently delayed until call gets destroyed or another reoffer/answer occurs).
  • Reenabled media transport dump in pjsua_core.c.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c

    r4011 r4071  
    11461146        pjmedia_srtp_setting_default(&srtp_opt); 
    11471147        srtp_opt.close_member_tp = PJ_TRUE; 
     1148 
    11481149        /* If media session has been ever established, let's use remote's  
    11491150         * preference in SRTP usage policy, especially when it is stricter. 
     
    11801181on_return: 
    11811182    if (status != PJ_SUCCESS && call_med->tp) { 
     1183        pjsua_set_media_tp_state(call_med, PJSUA_MED_TP_NULL); 
    11821184        pjmedia_transport_close(call_med->tp); 
    11831185        call_med->tp = NULL; 
     
    12181220    call_med->type = type; 
    12191221 
    1220     /* Create the media transport for initial call. */ 
     1222    /* Create the media transport for initial call. Here are the possible 
     1223     * media transport state and the action needed: 
     1224     * - PJSUA_MED_TP_NULL or call_med->tp==NULL, create one. 
     1225     * - PJSUA_MED_TP_RUNNING, do nothing. 
     1226     * - PJSUA_MED_TP_DISABLED, re-init (media_create(), etc). Currently, 
     1227     *   this won't happen as media_channel_update() will always clean up 
     1228     *   the unused transport of a disabled media. 
     1229     */ 
    12211230    if (call_med->tp == NULL) { 
    12221231#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0) 
     
    12581267    } else if (call_med->tp_st == PJSUA_MED_TP_DISABLED) { 
    12591268        /* Media is being reenabled. */ 
    1260         pjsua_set_media_tp_state(call_med, PJSUA_MED_TP_INIT); 
     1269        //pjsua_set_media_tp_state(call_med, PJSUA_MED_TP_IDLE); 
     1270 
     1271        pj_assert(!"Currently no media transport reuse"); 
    12611272    } 
    12621273 
     
    12811292         * has completed. 
    12821293         */ 
    1283         call->media[info->med_idx].med_init_cb = NULL; 
     1294        call->media_prov[info->med_idx].med_init_cb = NULL; 
    12841295 
    12851296        /* In case of failure, save the information to be returned 
     
    12921303         * callbacks. 
    12931304         */ 
    1294         for (mi=0; mi < call->med_cnt; ++mi) { 
    1295             pjsua_call_media *call_med = &call->media[mi]; 
     1305        for (mi=0; mi < call->med_prov_cnt; ++mi) { 
     1306            pjsua_call_media *call_med = &call->media_prov[mi]; 
    12961307 
    12971308            if (call_med->med_init_cb) { 
     
    13141325 
    13151326    if (status != PJ_SUCCESS) { 
    1316         pjsua_media_channel_deinit(call_id); 
     1327        pjsua_media_prov_clean_up(call_id); 
    13171328        goto on_return; 
    13181329    } 
    13191330 
    13201331    /* Tell the media transport of a new offer/answer session */ 
    1321     for (mi=0; mi < call->med_cnt; ++mi) { 
    1322         pjsua_call_media *call_med = &call->media[mi]; 
     1332    for (mi=0; mi < call->med_prov_cnt; ++mi) { 
     1333        pjsua_call_media *call_med = &call->media_prov[mi]; 
    13231334 
    13241335        /* Note: tp may be NULL if this media line is disabled */ 
     
    13551366                call->med_ch_info.state = call_med->tp_st; 
    13561367                call->med_ch_info.sip_err_code = PJSIP_SC_NOT_ACCEPTABLE; 
    1357                 pjsua_media_channel_deinit(call_id); 
     1368                pjsua_media_prov_clean_up(call_id); 
    13581369                goto on_return; 
    13591370            } 
     
    13711382    return status; 
    13721383} 
     1384 
     1385 
     1386/* Clean up media transports in provisional media that is not used 
     1387 * by call media. 
     1388 */ 
     1389void pjsua_media_prov_clean_up(pjsua_call_id call_id) 
     1390{ 
     1391    pjsua_call *call = &pjsua_var.calls[call_id]; 
     1392    unsigned i; 
     1393 
     1394    for (i = 0; i < call->med_prov_cnt; ++i) { 
     1395        pjsua_call_media *call_med = &call->media_prov[i]; 
     1396        unsigned j; 
     1397        pj_bool_t used = PJ_FALSE; 
     1398 
     1399        if (call_med->tp == NULL) 
     1400            continue; 
     1401 
     1402        for (j = 0; j < call->med_cnt; ++j) { 
     1403            if (call->media[j].tp == call_med->tp) { 
     1404                used = PJ_TRUE; 
     1405                break; 
     1406            } 
     1407        } 
     1408 
     1409        if (!used) { 
     1410            if (call_med->tp_st > PJSUA_MED_TP_IDLE) { 
     1411                pjsua_set_media_tp_state(call_med, PJSUA_MED_TP_IDLE); 
     1412                pjmedia_transport_media_stop(call_med->tp); 
     1413            } 
     1414            pjsua_set_media_tp_state(call_med, PJSUA_MED_TP_NULL); 
     1415            pjmedia_transport_close(call_med->tp); 
     1416            call_med->tp = call_med->tp_orig = NULL; 
     1417        } 
     1418    } 
     1419} 
     1420 
    13731421 
    13741422pj_status_t pjsua_media_channel_init(pjsua_call_id call_id, 
     
    14231471    pj_log_push_indent(); 
    14241472 
     1473    /* Init provisional media state */ 
     1474    if (call->med_cnt == 0) { 
     1475        /* New media session, just copy whole from call media state. */ 
     1476        pj_memcpy(call->media_prov, call->media, sizeof(call->media)); 
     1477    } else { 
     1478        /* Clean up any unused transports. Note that when local SDP reoffer 
     1479         * is rejected by remote, there may be any initialized transports that 
     1480         * are not used by call media and currently there is no notification 
     1481         * from PJSIP level regarding the reoffer rejection. 
     1482         */ 
     1483        pjsua_media_prov_clean_up(call_id); 
     1484 
     1485        /* Updating media session, copy from call media state. */ 
     1486        pj_memcpy(call->media_prov, call->media, 
     1487                  sizeof(call->media[0]) * call->med_cnt); 
     1488    } 
     1489    call->med_prov_cnt = call->med_cnt; 
     1490 
    14251491#if DISABLED_FOR_TICKET_1185 
    14261492    /* Return error if media transport has not been created yet 
     
    14421508            /* Expecting audio in the offer */ 
    14431509            if (sip_err_code) *sip_err_code = PJSIP_SC_NOT_ACCEPTABLE_HERE; 
    1444             pjsua_media_channel_deinit(call_id); 
    14451510            status = PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_ACCEPTABLE_HERE); 
    14461511            goto on_error; 
     
    14591524         * count setting (of the call setting) before the SDP negotiation. 
    14601525         */ 
    1461         if (call->med_cnt < rem_sdp->media_count) 
    1462             call->med_cnt = PJ_MIN(rem_sdp->media_count, PJSUA_MAX_CALL_MEDIA); 
     1526        if (call->med_prov_cnt < rem_sdp->media_count) 
     1527            call->med_prov_cnt = PJ_MIN(rem_sdp->media_count, 
     1528                                        PJSUA_MAX_CALL_MEDIA); 
    14631529 
    14641530        call->rem_offerer = PJ_TRUE; 
     
    14961562            { 
    14971563                for (mi = 0; mi < call->opt.aud_cnt - mtotaudcnt; ++mi) 
    1498                     maudidx[maudcnt++] = (pj_uint8_t)call->med_cnt++; 
     1564                    maudidx[maudcnt++] = (pj_uint8_t)call->med_prov_cnt++; 
    14991565                 
    15001566                mtotaudcnt = call->opt.aud_cnt; 
     
    15071573            { 
    15081574                for (mi = 0; mi < call->opt.vid_cnt - mtotvidcnt; ++mi) 
    1509                     mvididx[mvidcnt++] = (pj_uint8_t)call->med_cnt++; 
     1575                    mvididx[mvidcnt++] = (pj_uint8_t)call->med_prov_cnt++; 
    15101576 
    15111577                mtotvidcnt = call->opt.vid_cnt; 
     
    15231589                mvididx[mi] = (pj_uint8_t)(maudcnt + mi); 
    15241590            } 
    1525             call->med_cnt = maudcnt + mvidcnt; 
     1591            call->med_prov_cnt = maudcnt + mvidcnt; 
    15261592 
    15271593            /* Need to publish supported media? */ 
     
    15291595                if (mtotaudcnt == 0) { 
    15301596                    mtotaudcnt = 1; 
    1531                     maudidx[0] = (pj_uint8_t)call->med_cnt++; 
     1597                    maudidx[0] = (pj_uint8_t)call->med_prov_cnt++; 
    15321598                } 
    15331599#if PJMEDIA_HAS_VIDEO 
    15341600                if (mtotvidcnt == 0) { 
    15351601                    mtotvidcnt = 1; 
    1536                     mvididx[0] = (pj_uint8_t)call->med_cnt++; 
     1602                    mvididx[0] = (pj_uint8_t)call->med_prov_cnt++; 
    15371603                } 
    15381604#endif 
     
    15431609    } 
    15441610 
    1545     if (call->med_cnt == 0) { 
     1611    if (call->med_prov_cnt == 0) { 
    15461612        /* Expecting at least one media */ 
    15471613        if (sip_err_code) *sip_err_code = PJSIP_SC_NOT_ACCEPTABLE_HERE; 
    1548         pjsua_media_channel_deinit(call_id); 
    15491614        status = PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_ACCEPTABLE_HERE); 
    15501615        goto on_error; 
     
    15651630 
    15661631    /* Initialize each media line */ 
    1567     for (mi=0; mi < call->med_cnt; ++mi) { 
    1568         pjsua_call_media *call_med = &call->media[mi]; 
     1632    for (mi=0; mi < call->med_prov_cnt; ++mi) { 
     1633        pjsua_call_media *call_med = &call->media_prov[mi]; 
    15691634        pj_bool_t enabled = PJ_FALSE; 
    15701635        pjmedia_type media_type = PJMEDIA_TYPE_UNKNOWN; 
     
    16101675                } 
    16111676 
    1612                 pjsua_media_channel_deinit(call_id); 
     1677                pjsua_media_prov_clean_up(call_id); 
    16131678                goto on_error; 
    16141679            } 
     
    16191684            if (call_med->tp) { 
    16201685                // Don't close transport here, as SDP negotiation has not been 
    1621                 // done and stream may be still active. 
     1686                // done and stream may be still active. Once SDP negotiation 
     1687                // is done (channel_update() invoked), this transport will be 
     1688                // closed there. 
    16221689                //pjmedia_transport_close(call_med->tp); 
    16231690                //call_med->tp = NULL; 
     
    17361803    /* Get one address to use in the origin field */ 
    17371804    pj_bzero(&origin, sizeof(origin)); 
    1738     for (mi=0; mi<call->med_cnt; ++mi) { 
     1805    for (mi=0; mi<call->med_prov_cnt; ++mi) { 
    17391806        pjmedia_transport_info tpinfo; 
    17401807 
    1741         if (call->media[mi].tp == NULL) 
     1808        if (call->media_prov[mi].tp == NULL) 
    17421809            continue; 
    17431810 
    17441811        pjmedia_transport_info_init(&tpinfo); 
    1745         pjmedia_transport_get_info(call->media[mi].tp, &tpinfo); 
     1812        pjmedia_transport_get_info(call->media_prov[mi].tp, &tpinfo); 
    17461813        pj_sockaddr_cp(&origin, &tpinfo.sock_info.rtp_addr_name); 
    17471814        break; 
     
    17551822 
    17561823    /* Process each media line */ 
    1757     for (mi=0; mi<call->med_cnt; ++mi) { 
    1758         pjsua_call_media *call_med = &call->media[mi]; 
     1824    for (mi=0; mi<call->med_prov_cnt; ++mi) { 
     1825        pjsua_call_media *call_med = &call->media_prov[mi]; 
    17591826        pjmedia_sdp_media *m = NULL; 
    17601827        pjmedia_transport_info tpinfo; 
     
    19992066        call_med->prev_state = call_med->state; 
    20002067        call_med->state = PJSUA_CALL_MEDIA_NONE; 
     2068 
     2069        /* Try to sync recent changes to provisional media */ 
     2070        if (mi<call->med_prov_cnt && call->media_prov[mi].tp==call_med->tp) 
     2071        { 
     2072            pjsua_call_media *prov_med = &call->media_prov[mi]; 
     2073 
     2074            /* Media state */ 
     2075            prov_med->prev_state = call_med->prev_state; 
     2076            prov_med->state      = call_med->state; 
     2077 
     2078            /* RTP seq/ts */ 
     2079            prov_med->rtp_tx_seq_ts_set = call_med->rtp_tx_seq_ts_set; 
     2080            prov_med->rtp_tx_seq        = call_med->rtp_tx_seq; 
     2081            prov_med->rtp_tx_ts         = call_med->rtp_tx_ts; 
     2082 
     2083            /* Stream */ 
     2084            if (call_med->type == PJMEDIA_TYPE_AUDIO) { 
     2085                prov_med->strm.a.conf_slot = call_med->strm.a.conf_slot; 
     2086                prov_med->strm.a.stream    = call_med->strm.a.stream; 
     2087            } 
     2088#if PJMEDIA_HAS_VIDEO 
     2089            else if (call_med->type == PJMEDIA_TYPE_VIDEO) { 
     2090                prov_med->strm.v.cap_win_id = call_med->strm.v.cap_win_id; 
     2091                prov_med->strm.v.rdr_win_id = call_med->strm.v.rdr_win_id; 
     2092                prov_med->strm.v.stream     = call_med->strm.v.stream; 
     2093            } 
     2094#endif 
     2095        } 
    20012096    } 
    20022097 
     
    20292124    stop_media_session(call_id); 
    20302125 
     2126    /* Clean up media transports */ 
     2127    pjsua_media_prov_clean_up(call_id); 
     2128    call->med_prov_cnt = 0; 
    20312129    for (mi=0; mi<call->med_cnt; ++mi) { 
    20322130        pjsua_call_media *call_med = &call->media[mi]; 
    20332131 
    20342132        if (call_med->tp_st > PJSUA_MED_TP_IDLE) { 
     2133            pjsua_set_media_tp_state(call_med, PJSUA_MED_TP_IDLE); 
    20352134            pjmedia_transport_media_stop(call_med->tp); 
    2036             pjsua_set_media_tp_state(call_med, PJSUA_MED_TP_IDLE); 
    2037         } 
    2038  
    2039         //if (call_med->tp_orig && call_med->tp && 
    2040         //      call_med->tp != call_med->tp_orig) 
    2041         //{ 
    2042         //    pjmedia_transport_close(call_med->tp); 
    2043         //    call_med->tp = call_med->tp_orig; 
    2044         //} 
     2135        } 
     2136 
    20452137        if (call_med->tp) { 
     2138            pjsua_set_media_tp_state(call_med, PJSUA_MED_TP_NULL); 
    20462139            pjmedia_transport_close(call_med->tp); 
    20472140            call_med->tp = call_med->tp_orig = NULL; 
     
    20892182     * it may not be equal when remote removed any SDP media line. 
    20902183     */ 
    2091     pj_assert(call->med_cnt >= local_sdp->media_count); 
     2184    pj_assert(call->med_prov_cnt >= local_sdp->media_count); 
    20922185 
    20932186    /* Reset audio_idx first */ 
     
    21362229 
    21372230    /* Process each media stream */ 
    2138     for (mi=0; mi < call->med_cnt; ++mi) { 
    2139         pjsua_call_media *call_med = &call->media[mi]; 
     2231    for (mi=0; mi < call->med_prov_cnt; ++mi) { 
     2232        pjsua_call_media *call_med = &call->media_prov[mi]; 
    21402233 
    21412234        if (mi >= local_sdp->media_count || 
     
    22882381            /* Check if no media is active */ 
    22892382            if (si->dir == PJMEDIA_DIR_NONE) { 
    2290                 /* Call media state */ 
     2383                /* Update call media state and direction */ 
    22912384                call_med->state = PJSUA_CALL_MEDIA_NONE; 
    2292  
    2293                 /* Call media direction */ 
    22942385                call_med->dir = PJMEDIA_DIR_NONE; 
    22952386 
     
    23942485         */ 
    23952486        if (local_sdp->media[mi]->desc.port==0 && call_med->tp) { 
     2487            pjsua_set_media_tp_state(call_med, PJSUA_MED_TP_NULL); 
    23962488            pjmedia_transport_close(call_med->tp); 
    23972489            call_med->tp = call_med->tp_orig = NULL; 
    2398             pjsua_set_media_tp_state(call_med, PJSUA_MED_TP_IDLE); 
    23992490        } 
    24002491 
     
    24062497        } 
    24072498    } 
     2499 
     2500    /* Update call media from provisional media */ 
     2501    call->med_cnt = call->med_prov_cnt; 
     2502    pj_memcpy(call->media, call->media_prov, 
     2503              sizeof(call->media_prov[0]) * call->med_prov_cnt); 
    24082504 
    24092505    /* Perform SDP re-negotiation if needed. */ 
Note: See TracChangeset for help on using the changeset viewer.