Changeset 4254


Ignore:
Timestamp:
Sep 14, 2012 4:06:29 AM (7 years ago)
Author:
nanang
Message:

Close #1568:

  • Added media change detection based on SDP negotiation result and local codec param settings, the detection result will decide whether the media should be re-initialized after the SDP negotiation.
  • Fixed stream to keep the duplicate of codec param for the stream info (was only copying the pointer).
  • Introduced macro PJSUA_THIRD_PARTY_STREAM_HAS_GET_INFO & PJSUA_THIRD_PARTY_STREAM_HAS_GET_STAT.
Location:
pjproject/trunk
Files:
8 edited

Legend:

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

    r3664 r4254  
    309309 
    310310 
     311/** 
     312 * Duplicate codec parameter. 
     313 * 
     314 * @param pool      The pool. 
     315 * @param src       The codec parameter to be duplicated. 
     316 * 
     317 * @return          Duplicated codec parameter. 
     318 */ 
     319PJ_DECL(pjmedia_codec_param*) pjmedia_codec_param_clone( 
     320                                        pj_pool_t *pool,  
     321                                        const pjmedia_codec_param *src); 
     322 
    311323 
    312324/* 
  • pjproject/trunk/pjmedia/src/pjmedia/codec.c

    r3664 r4254  
    4242 
    4343/* 
     44 * Duplicate codec parameter. 
     45 */ 
     46PJ_DEF(pjmedia_codec_param*) pjmedia_codec_param_clone( 
     47                                        pj_pool_t *pool,  
     48                                        const pjmedia_codec_param *src) 
     49{ 
     50    pjmedia_codec_param *p; 
     51    unsigned i; 
     52 
     53    PJ_ASSERT_RETURN(pool && src, NULL); 
     54 
     55    p = PJ_POOL_ZALLOC_T(pool, pjmedia_codec_param); 
     56 
     57    /* Update codec param */ 
     58    pj_memcpy(p, src, sizeof(pjmedia_codec_param)); 
     59    for (i = 0; i < src->setting.dec_fmtp.cnt; ++i) { 
     60        pj_strdup(pool, &p->setting.dec_fmtp.param[i].name,  
     61                  &src->setting.dec_fmtp.param[i].name); 
     62        pj_strdup(pool, &p->setting.dec_fmtp.param[i].val,  
     63                  &src->setting.dec_fmtp.param[i].val); 
     64    } 
     65    for (i = 0; i < src->setting.enc_fmtp.cnt; ++i) { 
     66        pj_strdup(pool, &p->setting.enc_fmtp.param[i].name,  
     67                  &src->setting.enc_fmtp.param[i].name); 
     68        pj_strdup(pool, &p->setting.enc_fmtp.param[i].val,  
     69                  &src->setting.enc_fmtp.param[i].val); 
     70    } 
     71 
     72    return p; 
     73} 
     74 
     75 
     76/* 
    4477 * Initialize codec manager. 
    4578 */ 
     
    601634    p = codec_desc->param; 
    602635    p->pool = pool; 
    603     p->param = PJ_POOL_ZALLOC_T(pool, pjmedia_codec_param); 
    604636 
    605637    /* Update codec param */ 
    606     pj_memcpy(p->param, param, sizeof(pjmedia_codec_param)); 
    607     for (i = 0; i < param->setting.dec_fmtp.cnt; ++i) { 
    608         pj_strdup(pool, &p->param->setting.dec_fmtp.param[i].name,  
    609                   &param->setting.dec_fmtp.param[i].name); 
    610         pj_strdup(pool, &p->param->setting.dec_fmtp.param[i].val,  
    611                   &param->setting.dec_fmtp.param[i].val); 
    612     } 
    613     for (i = 0; i < param->setting.enc_fmtp.cnt; ++i) { 
    614         pj_strdup(pool, &p->param->setting.enc_fmtp.param[i].name,  
    615                   &param->setting.enc_fmtp.param[i].name); 
    616         pj_strdup(pool, &p->param->setting.enc_fmtp.param[i].val,  
    617                   &param->setting.enc_fmtp.param[i].val); 
    618     } 
     638    p->param = pjmedia_codec_param_clone(pool, param); 
     639    if (!p->param) 
     640        return PJ_EINVAL; 
    619641 
    620642    pj_mutex_unlock(mgr->mutex); 
  • pjproject/trunk/pjmedia/src/pjmedia/stream.c

    r4223 r4254  
    19901990    stream->own_pool = own_pool; 
    19911991    pj_memcpy(&stream->si, info, sizeof(*info)); 
     1992    stream->si.param = pjmedia_codec_param_clone(pool, info->param); 
    19921993 
    19931994    /* Init stream/port name */ 
  • pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h

    r4225 r4254  
    52375237 
    52385238/** 
     5239 * Specify whether the third party stream has the capability of retrieving 
     5240 * the stream info, i.e: pjmedia_stream_get_info() and 
     5241 * pjmedia_vid_stream_get_info(). Currently this capability is required 
     5242 * by smart media update and call dump. 
     5243 */ 
     5244#ifndef PJSUA_THIRD_PARTY_STREAM_HAS_GET_INFO 
     5245#   define PJSUA_THIRD_PARTY_STREAM_HAS_GET_INFO    0 
     5246#endif 
     5247 
     5248 
     5249/** 
     5250 * Specify whether the third party stream has the capability of retrieving 
     5251 * the stream statistics, i.e: pjmedia_stream_get_stat() and 
     5252 * pjmedia_vid_stream_get_stat(). Currently this capability is required 
     5253 * by call dump. 
     5254 */ 
     5255#ifndef PJSUA_THIRD_PARTY_STREAM_HAS_GET_STAT 
     5256#   define PJSUA_THIRD_PARTY_STREAM_HAS_GET_STAT    0 
     5257#endif 
     5258 
     5259 
     5260/** 
    52395261 * Max ports in the conference bridge. This setting is the default value 
    52405262 * for pjsua_media_config.max_media_ports. 
     
    55495571     */ 
    55505572    pj_bool_t vid_preview_enable_native; 
     5573 
     5574    /** 
     5575     * Disable smart media update (ticket #1568). The smart media update 
     5576     * will check for any changes in the media properties after a successful 
     5577     * SDP negotiation and the media will only be reinitialized when any 
     5578     * change is found. When it is disabled, media streams will always be 
     5579     * reinitialized after a successful SDP negotiation. 
     5580     * 
     5581     * Note for third party media, the smart media update requires stream info 
     5582     * retrieval capability, see #PJSUA_THIRD_PARTY_STREAM_HAS_GET_INFO. 
     5583     * 
     5584     * Default: PJ_FALSE 
     5585     */ 
     5586    pj_bool_t no_smart_media_update; 
    55515587}; 
    55525588 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_aud.c

    r4243 r4254  
    561561} 
    562562 
    563  
     563/* Internal function: update audio channel after SDP negotiation. 
     564 * Warning: do not use temporary/flip-flop pool, e.g: inv->pool_prov, 
     565 *          for creating stream, etc, as after SDP negotiation and when 
     566 *          the SDP media is not changed, the stream should remain running 
     567 *          while the temporary/flip-flop pool may be released. 
     568 */ 
    564569pj_status_t pjsua_aud_channel_update(pjsua_call_media *call_med, 
    565570                                     pj_pool_t *tmp_pool, 
     
    680685            } 
    681686            status = pjmedia_conf_add_port( pjsua_var.mconf, 
    682                                             call->inv->pool_prov, 
     687                                            call->inv->pool, 
    683688                                            media_port, 
    684689                                            &port_name, 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_dump.c

    r4085 r4254  
    213213 
    214214/* Dump media session */ 
     215#if PJSUA_MEDIA_HAS_PJMEDIA || \ 
     216    (PJSUA_THIRD_PARTY_STREAM_HAS_GET_INFO && \ 
     217     PJSUA_THIRD_PARTY_STREAM_HAS_GET_STAT) 
     218 
    215219static void dump_media_session(const char *indent, 
    216220                               char *buf, unsigned maxlen, 
     
    859863} 
    860864 
     865#else   /* PJSUA_MEDIA_HAS_PJMEDIA || 
     866           (PJSUA_THIRD_PARTY_STREAM_HAS_GET_INFO && 
     867            PJSUA_THIRD_PARTY_STREAM_HAS_GET_STAT) */ 
     868 
     869static void dump_media_session(const char *indent, 
     870                               char *buf, unsigned maxlen, 
     871                               pjsua_call *call) 
     872{ 
     873    PJ_UNUSED_ARG(indent); 
     874    PJ_UNUSED_ARG(buf); 
     875    PJ_UNUSED_ARG(maxlen); 
     876    PJ_UNUSED_ARG(call); 
     877} 
     878 
     879#endif  /* PJSUA_MEDIA_HAS_PJMEDIA || 
     880           (PJSUA_THIRD_PARTY_STREAM_HAS_GET_INFO && 
     881            PJSUA_THIRD_PARTY_STREAM_HAS_GET_STAT) */ 
     882 
    861883 
    862884/* Print call info */ 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c

    r4245 r4254  
    20852085 
    20862086 
     2087static void stop_media_stream(pjsua_call *call, unsigned med_idx) 
     2088{ 
     2089    pjsua_call_media *call_med = &call->media[med_idx]; 
     2090 
     2091    /* Check if stream does not exist */ 
     2092    if (med_idx >= call->med_cnt) 
     2093        return; 
     2094 
     2095    pj_log_push_indent(); 
     2096 
     2097    if (call_med->type == PJMEDIA_TYPE_AUDIO) { 
     2098        pjsua_aud_stop_stream(call_med); 
     2099    } 
     2100 
     2101#if PJMEDIA_HAS_VIDEO 
     2102    else if (call_med->type == PJMEDIA_TYPE_VIDEO) { 
     2103        pjsua_vid_stop_stream(call_med); 
     2104    } 
     2105#endif 
     2106 
     2107    PJ_LOG(4,(THIS_FILE, "Media stream call%02d:%d is destroyed", 
     2108                         call->index, med_idx)); 
     2109    call_med->prev_state = call_med->state; 
     2110    call_med->state = PJSUA_CALL_MEDIA_NONE; 
     2111 
     2112    /* Try to sync recent changes to provisional media */ 
     2113    if (med_idx < call->med_prov_cnt &&  
     2114        call->media_prov[med_idx].tp == call_med->tp) 
     2115    { 
     2116        pjsua_call_media *prov_med = &call->media_prov[med_idx]; 
     2117 
     2118        /* Media state */ 
     2119        prov_med->prev_state = call_med->prev_state; 
     2120        prov_med->state      = call_med->state; 
     2121 
     2122        /* RTP seq/ts */ 
     2123        prov_med->rtp_tx_seq_ts_set = call_med->rtp_tx_seq_ts_set; 
     2124        prov_med->rtp_tx_seq        = call_med->rtp_tx_seq; 
     2125        prov_med->rtp_tx_ts         = call_med->rtp_tx_ts; 
     2126 
     2127        /* Stream */ 
     2128        if (call_med->type == PJMEDIA_TYPE_AUDIO) { 
     2129            prov_med->strm.a.conf_slot = call_med->strm.a.conf_slot; 
     2130            prov_med->strm.a.stream    = call_med->strm.a.stream; 
     2131        } 
     2132#if PJMEDIA_HAS_VIDEO 
     2133        else if (call_med->type == PJMEDIA_TYPE_VIDEO) { 
     2134            prov_med->strm.v.cap_win_id = call_med->strm.v.cap_win_id; 
     2135            prov_med->strm.v.rdr_win_id = call_med->strm.v.rdr_win_id; 
     2136            prov_med->strm.v.stream     = call_med->strm.v.stream; 
     2137        } 
     2138#endif 
     2139    } 
     2140 
     2141    pj_log_pop_indent(); 
     2142} 
     2143 
    20872144static void stop_media_session(pjsua_call_id call_id) 
    20882145{ 
     
    20902147    unsigned mi; 
    20912148 
    2092     pj_log_push_indent(); 
    2093  
    20942149    for (mi=0; mi<call->med_cnt; ++mi) { 
    2095         pjsua_call_media *call_med = &call->media[mi]; 
    2096  
    2097         if (call_med->type == PJMEDIA_TYPE_AUDIO) { 
    2098             pjsua_aud_stop_stream(call_med); 
    2099         } 
    2100  
    2101 #if PJMEDIA_HAS_VIDEO 
    2102         else if (call_med->type == PJMEDIA_TYPE_VIDEO) { 
    2103             pjsua_vid_stop_stream(call_med); 
    2104         } 
    2105 #endif 
    2106  
    2107         PJ_LOG(4,(THIS_FILE, "Media session call%02d:%d is destroyed", 
    2108                              call_id, mi)); 
    2109         call_med->prev_state = call_med->state; 
    2110         call_med->state = PJSUA_CALL_MEDIA_NONE; 
    2111  
    2112         /* Try to sync recent changes to provisional media */ 
    2113         if (mi<call->med_prov_cnt && call->media_prov[mi].tp==call_med->tp) 
    2114         { 
    2115             pjsua_call_media *prov_med = &call->media_prov[mi]; 
    2116  
    2117             /* Media state */ 
    2118             prov_med->prev_state = call_med->prev_state; 
    2119             prov_med->state      = call_med->state; 
    2120  
    2121             /* RTP seq/ts */ 
    2122             prov_med->rtp_tx_seq_ts_set = call_med->rtp_tx_seq_ts_set; 
    2123             prov_med->rtp_tx_seq        = call_med->rtp_tx_seq; 
    2124             prov_med->rtp_tx_ts         = call_med->rtp_tx_ts; 
    2125  
    2126             /* Stream */ 
    2127             if (call_med->type == PJMEDIA_TYPE_AUDIO) { 
    2128                 prov_med->strm.a.conf_slot = call_med->strm.a.conf_slot; 
    2129                 prov_med->strm.a.stream    = call_med->strm.a.stream; 
    2130             } 
    2131 #if PJMEDIA_HAS_VIDEO 
    2132             else if (call_med->type == PJMEDIA_TYPE_VIDEO) { 
    2133                 prov_med->strm.v.cap_win_id = call_med->strm.v.cap_win_id; 
    2134                 prov_med->strm.v.rdr_win_id = call_med->strm.v.rdr_win_id; 
    2135                 prov_med->strm.v.stream     = call_med->strm.v.stream; 
    2136             } 
    2137 #endif 
    2138         } 
    2139     } 
    2140  
    2141     pj_log_pop_indent(); 
     2150        stop_media_stream(call, mi); 
     2151    } 
    21422152} 
    21432153 
     
    21872197    return PJ_SUCCESS; 
    21882198} 
     2199 
     2200 
     2201/* Match codec fmtp. This will compare the values and the order. */ 
     2202static pj_bool_t match_codec_fmtp(const pjmedia_codec_fmtp *fmtp1, 
     2203                                  const pjmedia_codec_fmtp *fmtp2) 
     2204{ 
     2205    unsigned i; 
     2206 
     2207    if (fmtp1->cnt != fmtp2->cnt) 
     2208        return PJ_FALSE; 
     2209 
     2210    for (i = 0; i < fmtp1->cnt; ++i) { 
     2211        if (pj_stricmp(&fmtp1->param[i].name, &fmtp2->param[i].name)) 
     2212            return PJ_FALSE; 
     2213        if (pj_stricmp(&fmtp1->param[i].val, &fmtp2->param[i].val)) 
     2214            return PJ_FALSE; 
     2215    } 
     2216 
     2217    return PJ_TRUE; 
     2218} 
     2219 
     2220#if PJSUA_MEDIA_HAS_PJMEDIA || PJSUA_THIRD_PARTY_STREAM_HAS_GET_INFO 
     2221 
     2222static pj_bool_t is_media_changed(const pjsua_call *call, 
     2223                                  unsigned med_idx, 
     2224                                  const pjsua_stream_info *new_si_) 
     2225{ 
     2226    const pjsua_call_media *call_med = &call->media[med_idx]; 
     2227 
     2228    /* Check for newly added media */ 
     2229    if (med_idx >= call->med_cnt) 
     2230        return PJ_TRUE; 
     2231 
     2232    /* Compare media type */ 
     2233    if (call_med->type != new_si_->type) 
     2234        return PJ_TRUE; 
     2235 
     2236    /* Audio update checks */ 
     2237    if (call_med->type == PJMEDIA_TYPE_AUDIO) { 
     2238        pjmedia_stream_info the_old_si; 
     2239        const pjmedia_stream_info *old_si = NULL; 
     2240        const pjmedia_stream_info *new_si = &new_si_->info.aud; 
     2241        const pjmedia_codec_info *old_ci = NULL; 
     2242        const pjmedia_codec_info *new_ci = &new_si->fmt; 
     2243        const pjmedia_codec_param *old_cp = NULL; 
     2244        const pjmedia_codec_param *new_cp = new_si->param; 
     2245 
     2246        /* Compare media direction */ 
     2247        if (call_med->dir != new_si->dir) 
     2248            return PJ_TRUE; 
     2249 
     2250        /* Get current active stream info */ 
     2251        if (call_med->strm.a.stream) { 
     2252            pjmedia_stream_get_info(call_med->strm.a.stream, &the_old_si); 
     2253            old_si = &the_old_si; 
     2254            old_ci = &old_si->fmt; 
     2255            old_cp = old_si->param; 
     2256        } else { 
     2257            /* The stream is inactive. */ 
     2258            return (new_si->dir != PJMEDIA_DIR_NONE); 
     2259        } 
     2260 
     2261        /* Compare remote RTP address */ 
     2262        if (pj_sockaddr_cmp(&old_si->rem_addr, &new_si->rem_addr)) 
     2263            return PJ_TRUE; 
     2264 
     2265        /* Compare codec info */ 
     2266        if (pj_stricmp(&old_ci->encoding_name, &new_ci->encoding_name) || 
     2267            old_ci->clock_rate != new_ci->clock_rate || 
     2268            old_ci->channel_cnt != new_ci->channel_cnt || 
     2269            old_si->rx_pt != new_si->rx_pt || 
     2270            old_si->tx_pt != new_si->tx_pt || 
     2271            old_si->rx_event_pt != new_si->tx_event_pt || 
     2272            old_si->tx_event_pt != new_si->tx_event_pt) 
     2273        { 
     2274            return PJ_TRUE; 
     2275        } 
     2276 
     2277        /* Compare codec param */ 
     2278        if (old_cp->setting.frm_per_pkt != new_cp->setting.frm_per_pkt || 
     2279            old_cp->setting.vad != new_cp->setting.vad || 
     2280            old_cp->setting.cng != new_cp->setting.cng || 
     2281            old_cp->setting.plc != new_cp->setting.plc || 
     2282            old_cp->setting.penh != new_cp->setting.penh || 
     2283            !match_codec_fmtp(&old_cp->setting.dec_fmtp, 
     2284                              &new_cp->setting.dec_fmtp) || 
     2285            !match_codec_fmtp(&old_cp->setting.enc_fmtp, 
     2286                              &new_cp->setting.enc_fmtp)) 
     2287        { 
     2288            return PJ_TRUE; 
     2289        } 
     2290    } 
     2291 
     2292#if PJMEDIA_HAS_VIDEO 
     2293    else if (call_med->type == PJMEDIA_TYPE_VIDEO) { 
     2294        pjmedia_vid_stream_info the_old_si; 
     2295        const pjmedia_vid_stream_info *old_si = NULL; 
     2296        const pjmedia_vid_stream_info *new_si = &new_si_->info.vid; 
     2297        const pjmedia_vid_codec_info *old_ci = NULL; 
     2298        const pjmedia_vid_codec_info *new_ci = &new_si->codec_info; 
     2299        const pjmedia_vid_codec_param *old_cp = NULL; 
     2300        const pjmedia_vid_codec_param *new_cp = new_si->codec_param; 
     2301 
     2302        /* Compare media direction */ 
     2303        if (call_med->dir != new_si->dir) 
     2304            return PJ_TRUE; 
     2305 
     2306        /* Get current active stream info */ 
     2307        if (call_med->strm.v.stream) { 
     2308            pjmedia_vid_stream_get_info(call_med->strm.v.stream, &the_old_si); 
     2309            old_si = &the_old_si; 
     2310            old_ci = &old_si->codec_info; 
     2311            old_cp = old_si->codec_param; 
     2312        } else { 
     2313            /* The stream is inactive. */ 
     2314            return (new_si->dir != PJMEDIA_DIR_NONE); 
     2315        } 
     2316 
     2317        /* Compare remote RTP address */ 
     2318        if (pj_sockaddr_cmp(&old_si->rem_addr, &new_si->rem_addr)) 
     2319            return PJ_TRUE; 
     2320 
     2321        /* Compare codec info */ 
     2322        if (pj_stricmp(&old_ci->encoding_name, &new_ci->encoding_name) || 
     2323            old_si->rx_pt != new_si->rx_pt || 
     2324            old_si->tx_pt != new_si->tx_pt) 
     2325        { 
     2326            return PJ_TRUE; 
     2327        } 
     2328 
     2329        /* Compare codec param */ 
     2330        if (/* old_cp->enc_mtu != new_cp->enc_mtu || */ 
     2331            pj_memcmp(&old_cp->enc_fmt.det, &new_cp->enc_fmt.det, 
     2332                      sizeof(pjmedia_video_format_detail)) || 
     2333            !match_codec_fmtp(&old_cp->dec_fmtp, &new_cp->dec_fmtp) || 
     2334            !match_codec_fmtp(&old_cp->enc_fmtp, &new_cp->enc_fmtp)) 
     2335        { 
     2336            return PJ_TRUE; 
     2337        } 
     2338    } 
     2339 
     2340#endif 
     2341 
     2342    else { 
     2343        /* Just return PJ_TRUE for other media type */ 
     2344        return PJ_TRUE; 
     2345    } 
     2346 
     2347    return PJ_FALSE; 
     2348} 
     2349 
     2350#else /* PJSUA_MEDIA_HAS_PJMEDIA || PJSUA_THIRD_PARTY_STREAM_HAS_GET_INFO */ 
     2351 
     2352static pj_bool_t is_media_changed(const pjsua_call *call, 
     2353                                  unsigned med_idx, 
     2354                                  const pjsua_stream_info *new_si_) 
     2355{ 
     2356    PJ_UNUSED_ARG(call); 
     2357    PJ_UNUSED_ARG(med_idx); 
     2358    PJ_UNUSED_ARG(new_si_); 
     2359    /* Always assume that media has been changed */ 
     2360    return PJ_TRUE; 
     2361} 
     2362 
     2363#endif /* PJSUA_MEDIA_HAS_PJMEDIA || PJSUA_THIRD_PARTY_STREAM_HAS_GET_INFO */ 
    21892364 
    21902365 
     
    22172392 
    22182393    /* Destroy existing media session, if any. */ 
    2219     stop_media_session(call->index); 
     2394    //stop_media_session(call->index); 
    22202395 
    22212396    /* Call media count must be at least equal to SDP media. Note that 
     
    22712446    for (mi=0; mi < call->med_prov_cnt; ++mi) { 
    22722447        pjsua_call_media *call_med = &call->media_prov[mi]; 
     2448        pj_bool_t media_changed = PJ_FALSE; 
    22732449 
    22742450        if (mi >= local_sdp->media_count || 
     
    22782454             * its re-offer. 
    22792455             */ 
     2456 
     2457            /* Stop stream */ 
     2458            stop_media_stream(call, mi); 
     2459 
     2460            /* Close the media transport */ 
    22802461            if (call_med->tp) { 
    2281                 /* Close the media transport */ 
    22822462                pjsua_set_media_tp_state(call_med, PJSUA_MED_TP_NULL); 
    22832463                pjmedia_transport_close(call_med->tp); 
     
    22942474        } 
    22952475 
     2476        /* Apply media update action */ 
    22962477        if (call_med->type==PJMEDIA_TYPE_AUDIO) { 
    22972478            pjmedia_stream_info the_si, *si = &the_si; 
    2298  
    2299             status = pjmedia_stream_info_from_sdp(si, tmp_pool, pjsua_var.med_endpt, 
    2300                                                   local_sdp, remote_sdp, mi); 
     2479            pjsua_stream_info stream_info; 
     2480 
     2481            status = pjmedia_stream_info_from_sdp( 
     2482                                        si, tmp_pool, pjsua_var.med_endpt, 
     2483                                        local_sdp, remote_sdp, mi); 
    23012484            if (status != PJ_SUCCESS) { 
    23022485                PJ_PERROR(1,(THIS_FILE, status, 
     
    23072490            } 
    23082491 
     2492            /* Check if this media is changed */ 
     2493            stream_info.type = PJMEDIA_TYPE_AUDIO; 
     2494            stream_info.info.aud = the_si; 
     2495            if (pjsua_var.media_cfg.no_smart_media_update || 
     2496                is_media_changed(call, mi, &stream_info)) 
     2497            { 
     2498                media_changed = PJ_TRUE; 
     2499                /* Stop the media */ 
     2500                stop_media_stream(call, mi); 
     2501            } else { 
     2502                PJ_LOG(4,(THIS_FILE, "Call %d: stream #%d (audio) unchanged.", 
     2503                          call_id, mi)); 
     2504            } 
     2505 
    23092506            /* Check if no media is active */ 
    23102507            if (si->dir == PJMEDIA_DIR_NONE) { 
     2508 
    23112509                /* Update call media state and direction */ 
    23122510                call_med->state = PJSUA_CALL_MEDIA_NONE; 
     
    23362534                    unsigned i; 
    23372535                    for (i = 0; i < tp_info.specific_info_cnt; ++i) { 
    2338                         if (tp_info.spc_info[i].type == PJMEDIA_TRANSPORT_TYPE_SRTP) 
     2536                        if (tp_info.spc_info[i].type ==  
     2537                            PJMEDIA_TRANSPORT_TYPE_SRTP) 
    23392538                        { 
    23402539                            pjmedia_srtp_info *srtp_info = 
    2341                                         (pjmedia_srtp_info*) tp_info.spc_info[i].buffer; 
     2540                                (pjmedia_srtp_info*)tp_info.spc_info[i].buffer; 
    23422541 
    23432542                            call_med->rem_srtp_use = srtp_info->peer_use; 
    23442543                            break; 
    23452544                        } 
     2545                    } 
     2546                } 
     2547 
     2548                /* Update audio channel */ 
     2549                if (media_changed) { 
     2550                    status = pjsua_aud_channel_update(call_med, 
     2551                                                      call->inv->pool, si, 
     2552                                                      local_sdp, remote_sdp); 
     2553                    if (status != PJ_SUCCESS) { 
     2554                        PJ_PERROR(1,(THIS_FILE, status, 
     2555                                     "pjsua_aud_channel_update() failed " 
     2556                                         "for call_id %d media %d", 
     2557                                     call_id, mi)); 
     2558                        continue; 
    23462559                    } 
    23472560                } 
     
    23572570                else 
    23582571                    call_med->state = PJSUA_CALL_MEDIA_ACTIVE; 
    2359             } 
    2360  
    2361             /* Call implementation */ 
    2362             status = pjsua_aud_channel_update(call_med, tmp_pool, si, 
    2363                                               local_sdp, remote_sdp); 
    2364             if (status != PJ_SUCCESS) { 
    2365                 PJ_PERROR(1,(THIS_FILE, status, 
    2366                              "pjsua_aud_channel_update() failed " 
    2367                                  "for call_id %d media %d", 
    2368                              call_id, mi)); 
    2369                 continue; 
    23702572            } 
    23712573 
     
    24142616        } else if (call_med->type==PJMEDIA_TYPE_VIDEO) { 
    24152617            pjmedia_vid_stream_info the_si, *si = &the_si; 
    2416  
    2417             status = pjmedia_vid_stream_info_from_sdp(si, tmp_pool, pjsua_var.med_endpt, 
    2418                                                       local_sdp, remote_sdp, mi); 
     2618            pjsua_stream_info stream_info; 
     2619 
     2620            status = pjmedia_vid_stream_info_from_sdp( 
     2621                                        si, tmp_pool, pjsua_var.med_endpt, 
     2622                                        local_sdp, remote_sdp, mi); 
    24192623            if (status != PJ_SUCCESS) { 
    24202624                PJ_PERROR(1,(THIS_FILE, status, 
     
    24252629            } 
    24262630 
     2631            /* Check if this media is changed */ 
     2632            stream_info.type = PJMEDIA_TYPE_VIDEO; 
     2633            stream_info.info.vid = the_si; 
     2634            if (is_media_changed(call, mi, &stream_info)) { 
     2635                media_changed = PJ_TRUE; 
     2636                /* Stop the media */ 
     2637                stop_media_stream(call, mi); 
     2638            } else { 
     2639                PJ_LOG(4,(THIS_FILE, "Call %d: stream #%d (video) unchanged.", 
     2640                          call_id, mi)); 
     2641            } 
     2642 
    24272643            /* Check if no media is active */ 
    24282644            if (si->dir == PJMEDIA_DIR_NONE) { 
     2645 
    24292646                /* Update call media state and direction */ 
    24302647                call_med->state = PJSUA_CALL_MEDIA_NONE; 
     
    24652682                } 
    24662683 
     2684                /* Update audio channel */ 
     2685                if (media_changed) { 
     2686                    status = pjsua_vid_channel_update(call_med, 
     2687                                                      call->inv->pool, si, 
     2688                                                      local_sdp, remote_sdp); 
     2689                    if (status != PJ_SUCCESS) { 
     2690                        PJ_PERROR(1,(THIS_FILE, status, 
     2691                                     "pjsua_vid_channel_update() failed " 
     2692                                         "for call_id %d media %d", 
     2693                                     call_id, mi)); 
     2694                        continue; 
     2695                    } 
     2696                } 
     2697 
    24672698                /* Call media direction */ 
    24682699                call_med->dir = si->dir; 
     
    24752706                else 
    24762707                    call_med->state = PJSUA_CALL_MEDIA_ACTIVE; 
    2477             } 
    2478  
    2479             status = pjsua_vid_channel_update(call_med, tmp_pool, si, 
    2480                                               local_sdp, remote_sdp); 
    2481             if (status != PJ_SUCCESS) { 
    2482                 PJ_PERROR(1,(THIS_FILE, status, 
    2483                              "pjsua_vid_channel_update() failed " 
    2484                                  "for call_id %d media %d", 
    2485                              call_id, mi)); 
    2486                 continue; 
    24872708            } 
    24882709 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_vid.c

    r4236 r4254  
    706706} 
    707707 
    708 /* Internal function: update video channel after SDP negotiation */ 
     708/* Internal function: update video channel after SDP negotiation. 
     709 * Warning: do not use temporary/flip-flop pool, e.g: inv->pool_prov, 
     710 *          for creating stream, etc, as after SDP negotiation and when 
     711 *          the SDP media is not changed, the stream should remain running 
     712 *          while the temporary/flip-flop pool may be released. 
     713 */ 
    709714pj_status_t pjsua_vid_channel_update(pjsua_call_media *call_med, 
    710715                                     pj_pool_t *tmp_pool, 
Note: See TracChangeset for help on using the changeset viewer.