Changeset 3714


Ignore:
Timestamp:
Aug 18, 2011 6:30:55 PM (8 years ago)
Author:
nanang
Message:

Re #1347: Fixed case 1, 2, and 3 above:

  • Generating a deactivated pre-answer media by cloning remote media. There was a case that the media transport in the offer is bad/unrecognized, PJSUA still generated the preanswer with RTP/AVP.
  • When generating answer, it should apply max media count (max_audio/video_cnt in account setting) after SDP negotiation instead of in the pjsua_media_channel_init()). This will require PJSUA to perform SDP re-negotiation when the SDP answer get changed.
  • Fixed media priority/acceptibility sorting, e.g: media with RTP/SAVP transport still got acceptable score in SRTP disabled mode, this messed up the algorithm of applying max media count setting.
  • Fixed SDP negotiator to skip format match in generating answer when the pre-answer provided is deactivated (port 0).
Location:
pjproject/trunk
Files:
2 edited

Legend:

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

    r3708 r3714  
    11501150    } 
    11511151 
     1152    /* If the preanswer define zero port, this media is being rejected, 
     1153     * just clone the preanswer. 
     1154     */ 
     1155    if (preanswer->desc.port == 0) { 
     1156        answer = pjmedia_sdp_media_clone(pool, preanswer); 
     1157        *p_answer = answer; 
     1158        return PJ_SUCCESS; 
     1159    } 
     1160 
    11521161    /* Set master/slave negotiator based on prefer_remote_codec_order. */ 
    11531162    if (prefer_remote_codec_order) { 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c

    r3678 r3714  
    11451145                break; 
    11461146            case PJMEDIA_SRTP_DISABLED: 
    1147                 --score[i]; 
     1147                //--score[i]; 
     1148                score[i] -= 5; 
    11481149                break; 
    11491150            } 
     
    11511152            switch (use_srtp) { 
    11521153            case PJMEDIA_SRTP_MANDATORY: 
    1153                 --score[i]; 
     1154                //--score[i]; 
     1155                score[i] -= 5; 
    11541156                break; 
    11551157            case PJMEDIA_SRTP_OPTIONAL: 
     
    13761378        sort_media(rem_sdp, &STR_AUDIO, acc->cfg.use_srtp, 
    13771379                   maudidx, &maudcnt); 
    1378         if (maudcnt > acc->cfg.max_audio_cnt) 
    1379             maudcnt = acc->cfg.max_audio_cnt; 
     1380        // Don't apply media count limitation until SDP negotiation is done. 
     1381        //if (maudcnt > acc->cfg.max_audio_cnt) 
     1382        //    maudcnt = acc->cfg.max_audio_cnt; 
    13801383 
    13811384        if (maudcnt==0) { 
     
    13861389        } 
    13871390 
     1391#if PJMEDIA_HAS_VIDEO 
    13881392        sort_media(rem_sdp, &STR_VIDEO, acc->cfg.use_srtp, 
    13891393                   mvididx, &mvidcnt); 
    1390         if (mvidcnt > acc->cfg.max_video_cnt) 
    1391             mvidcnt = acc->cfg.max_video_cnt; 
     1394        // Don't apply media count limitation until SDP negotiation is done. 
     1395        //if (mvidcnt > acc->cfg.max_video_cnt) 
     1396            //mvidcnt = acc->cfg.max_video_cnt; 
     1397#else 
     1398        mvidcnt = 0; 
     1399#endif 
    13921400 
    13931401        /* Update media count only when remote add any media, this media count 
     
    14031411            media_types[mi] = PJMEDIA_TYPE_AUDIO; 
    14041412        } 
     1413#if PJMEDIA_HAS_VIDEO 
    14051414        mvidcnt = acc->cfg.max_video_cnt; 
    14061415        for (mi=0; mi<mvidcnt; ++mi) { 
    14071416            media_types[maudcnt + mi] = PJMEDIA_TYPE_VIDEO; 
    14081417        } 
    1409          
     1418#else 
     1419        mvidcnt = 0; 
     1420#endif   
    14101421        call->med_cnt = maudcnt + mvidcnt; 
    14111422    } 
     
    16111622             * port. 
    16121623             */ 
    1613             m = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_media); 
    1614             m->desc.transport = pj_str("RTP/AVP"); 
    1615             m->desc.fmt_count = 1; 
    1616             m->conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn); 
    1617             m->conn->net_type = pj_str("IN"); 
    1618             m->conn->addr_type = pj_str("IP4"); 
    1619             m->conn->addr = pj_str("127.0.0.1"); 
    1620  
    1621             switch (call_med->type) { 
    1622             case PJMEDIA_TYPE_AUDIO: 
    1623                 m->desc.media = pj_str("audio"); 
    1624                 m->desc.fmt[0] = pj_str("0"); 
    1625                 break; 
    1626             case PJMEDIA_TYPE_VIDEO: 
    1627                 m->desc.media = pj_str("video"); 
    1628                 m->desc.fmt[0] = pj_str("31"); 
    1629                 break; 
    1630             default: 
    1631                 if (rem_sdp && mi < rem_sdp->media_count) { 
    1632                     pj_strdup(pool, &m->desc.media, 
    1633                               &rem_sdp->media[mi]->desc.media); 
    1634                     pj_strdup(pool, &m->desc.fmt[0], 
    1635                               &rem_sdp->media[mi]->desc.fmt[0]); 
    1636                 } else { 
    1637                     pj_assert(!"Invalid call_med media type"); 
    1638                     return PJ_EBUG; 
     1624            if (rem_sdp) { 
     1625                /* Just clone the remote media and deactivate it */ 
     1626                m = pjmedia_sdp_media_clone_deactivate(pool, 
     1627                                                       rem_sdp->media[mi]); 
     1628            } else { 
     1629                m = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_media); 
     1630                m->desc.transport = pj_str("RTP/AVP"); 
     1631                m->desc.fmt_count = 1; 
     1632                m->conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn); 
     1633                m->conn->net_type = pj_str("IN"); 
     1634                m->conn->addr_type = pj_str("IP4"); 
     1635                m->conn->addr = pj_str("127.0.0.1"); 
     1636 
     1637                switch (call_med->type) { 
     1638                case PJMEDIA_TYPE_AUDIO: 
     1639                    m->desc.media = pj_str("audio"); 
     1640                    m->desc.fmt[0] = pj_str("0"); 
     1641                    break; 
     1642                case PJMEDIA_TYPE_VIDEO: 
     1643                    m->desc.media = pj_str("video"); 
     1644                    m->desc.fmt[0] = pj_str("31"); 
     1645                    break; 
     1646                default: 
     1647                    if (rem_sdp) { 
     1648                        pj_strdup(pool, &m->desc.media, 
     1649                                  &rem_sdp->media[mi]->desc.media); 
     1650                        pj_strdup(pool, &m->desc.fmt[0], 
     1651                                  &rem_sdp->media[mi]->desc.fmt[0]); 
     1652                    } else { 
     1653                        pj_assert(!"Invalid call_med media type"); 
     1654                        return PJ_EBUG; 
     1655                    } 
    16391656                } 
    16401657            } 
     
    20872104{ 
    20882105    pjsua_call *call = &pjsua_var.calls[call_id]; 
     2106    pjsua_acc *acc = &pjsua_var.acc[call->acc_id]; 
    20892107    pj_pool_t *tmp_pool = call->inv->pool_prov; 
    20902108    unsigned mi; 
     
    20922110    pj_status_t status = PJ_SUCCESS; 
    20932111 
     2112    const pj_str_t STR_AUDIO = { "audio", 5 }; 
     2113    const pj_str_t STR_VIDEO = { "video", 5 }; 
     2114    pj_uint8_t maudidx[PJSUA_MAX_CALL_MEDIA]; 
     2115    unsigned maudcnt = PJ_ARRAY_SIZE(maudidx); 
     2116    pj_uint8_t mvididx[PJSUA_MAX_CALL_MEDIA]; 
     2117    unsigned mvidcnt = PJ_ARRAY_SIZE(mvididx); 
     2118    pj_bool_t need_renego_sdp = PJ_FALSE; 
     2119 
    20942120    if (pjsua_get_state() != PJSUA_STATE_RUNNING) 
    20952121        return PJ_EBUSY; 
     
    20982124    stop_media_session(call->index); 
    20992125 
     2126    /* Call media count must be at least equal to SDP media. Note that 
     2127     * it may not be equal when remote removed any SDP media line. 
     2128     */ 
     2129    pj_assert(call->med_cnt >= local_sdp->media_count); 
     2130 
    21002131    /* Reset audio_idx first */ 
    21012132    call->audio_idx = -1; 
     2133 
     2134    /* Apply maximum audio/video count of the account */ 
     2135    sort_media(local_sdp, &STR_AUDIO, acc->cfg.use_srtp, 
     2136               maudidx, &maudcnt); 
     2137#if PJMEDIA_HAS_VIDEO 
     2138    sort_media(local_sdp, &STR_VIDEO, acc->cfg.use_srtp, 
     2139               mvididx, &mvidcnt); 
     2140#else 
     2141    PJ_UNUSED_ARG(STR_VIDEO); 
     2142    mvidcnt = 0; 
     2143#endif 
     2144    if (maudcnt > acc->cfg.max_audio_cnt || mvidcnt > acc->cfg.max_video_cnt) 
     2145    { 
     2146        pjmedia_sdp_session *local_sdp2; 
     2147 
     2148        maudcnt = PJ_MIN(maudcnt, acc->cfg.max_audio_cnt); 
     2149        mvidcnt = PJ_MIN(mvidcnt, acc->cfg.max_video_cnt); 
     2150        local_sdp2 = pjmedia_sdp_session_clone(tmp_pool, local_sdp); 
     2151 
     2152        for (mi=0; mi < local_sdp2->media_count; ++mi) { 
     2153            pjmedia_sdp_media *m = local_sdp2->media[mi]; 
     2154 
     2155            if (m->desc.port == 0 || 
     2156                pj_memchr(maudidx, mi, maudcnt*sizeof(maudidx[0])) || 
     2157                pj_memchr(mvididx, mi, mvidcnt*sizeof(mvididx[0]))) 
     2158            { 
     2159                continue; 
     2160            } 
     2161             
     2162            /* Deactivate this media */ 
     2163            pjmedia_sdp_media_deactivate(tmp_pool, m); 
     2164        } 
     2165 
     2166        local_sdp = local_sdp2; 
     2167        need_renego_sdp = PJ_TRUE; 
     2168    } 
    21022169 
    21032170    /* Process each media stream */ 
     
    21412208        } 
    21422209 
     2210        /* Close the transport of deactivated media, need this here as media 
     2211         * can be deactivated by the SDP negotiation and the max media count 
     2212         * (account) setting. 
     2213         */ 
     2214        if (local_sdp->media[mi]->desc.port==0 && call_med->tp) { 
     2215            pjmedia_transport_close(call_med->tp); 
     2216            call_med->tp = call_med->tp_orig = NULL; 
     2217            call_med->tp_st = PJSUA_MED_TP_IDLE; 
     2218        } 
     2219 
    21432220        if (status != PJ_SUCCESS) { 
    21442221            PJ_PERROR(1,(THIS_FILE, status, "Error updating media call%02d:%d", 
     
    21472224            got_media = PJ_TRUE; 
    21482225        } 
     2226    } 
     2227 
     2228    /* Perform SDP re-negotiation if needed. */ 
     2229    if (got_media && need_renego_sdp) { 
     2230        pjmedia_sdp_neg *neg = call->inv->neg; 
     2231 
     2232        /* This should only happen when we are the answerer. */ 
     2233        PJ_ASSERT_RETURN(neg && !pjmedia_sdp_neg_was_answer_remote(neg), 
     2234                         PJMEDIA_SDPNEG_EINSTATE); 
     2235         
     2236        status = pjmedia_sdp_neg_set_remote_offer(tmp_pool, neg, remote_sdp); 
     2237        if (status != PJ_SUCCESS) 
     2238            return status; 
     2239 
     2240        status = pjmedia_sdp_neg_set_local_answer(tmp_pool, neg, local_sdp); 
     2241        if (status != PJ_SUCCESS) 
     2242            return status; 
     2243 
     2244        status = pjmedia_sdp_neg_negotiate(tmp_pool, neg, 0); 
     2245        if (status != PJ_SUCCESS) 
     2246            return status; 
    21492247    } 
    21502248 
Note: See TracChangeset for help on using the changeset viewer.