Changeset 3463


Ignore:
Timestamp:
Mar 18, 2011 7:54:50 AM (13 years ago)
Author:
nanang
Message:

Re #1201:

  • Initial version of video stream integration into pjsua-lib.
  • Replaced audio info array in pjsua_call_info with media info array.
  • Added video media info into call dump.
  • Fixed assertion caused by pjsua_set_state(NULL) logging after pjlib shutdown.
Location:
pjproject/branches/projects/2.0-dev
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/2.0-dev/pjproject-vs8.sln

    r3425 r3463  
    110110        ProjectSection(ProjectDependencies) = postProject 
    111111                {2BB84911-C1B4-4747-B93D-36AA82CC5031} = {2BB84911-C1B4-4747-B93D-36AA82CC5031} 
     112                {9CA0FDFB-2172-41FC-B7F1-5CE915EDCB37} = {9CA0FDFB-2172-41FC-B7F1-5CE915EDCB37} 
     113                {F0DBAA03-1BA3-4E3B-A2CA-727E3D3AB858} = {F0DBAA03-1BA3-4E3B-A2CA-727E3D3AB858} 
     114                {A1989FF3-9894-40F4-B5A6-6EA364476E45} = {A1989FF3-9894-40F4-B5A6-6EA364476E45} 
     115                {E53AA5FF-B737-40AA-BD13-387EFA99023D} = {E53AA5FF-B737-40AA-BD13-387EFA99023D} 
     116                {B5FE16F8-3EDB-4110-BD80-B4238CC01E8D} = {B5FE16F8-3EDB-4110-BD80-B4238CC01E8D} 
     117                {DA0E03ED-53A7-4050-8A85-90541C5509F8} = {DA0E03ED-53A7-4050-8A85-90541C5509F8} 
     118                {B8719FD5-E8A6-4A36-943C-891D07F5DD21} = {B8719FD5-E8A6-4A36-943C-891D07F5DD21} 
     119                {4B5945CD-0CB3-49AA-A7FF-7612D93F82C0} = {4B5945CD-0CB3-49AA-A7FF-7612D93F82C0} 
     120                {855DC8C0-D3E9-4A2E-AE47-116605A7BC9B} = {855DC8C0-D3E9-4A2E-AE47-116605A7BC9B} 
     121                {4B059DBA-CD9C-4D0F-BE8C-FFB4EFD498E9} = {4B059DBA-CD9C-4D0F-BE8C-FFB4EFD498E9} 
     122                {3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA} = {3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA} 
     123                {7FDE3880-A4AB-49E3-B439-EBEF0A0C7A65} = {7FDE3880-A4AB-49E3-B439-EBEF0A0C7A65} 
     124                {6794B975-4E84-4F49-B2DC-C31F2224E03E} = {6794B975-4E84-4F49-B2DC-C31F2224E03E} 
     125                {FE07F272-AE7F-4549-9E9F-EF9B80CB1693} = {FE07F272-AE7F-4549-9E9F-EF9B80CB1693} 
     126                {4281CA5E-1D48-45D4-A991-2718A454B4BA} = {4281CA5E-1D48-45D4-A991-2718A454B4BA} 
     127                {A5D9AA24-08ED-48B9-BD65-F0A25E96BFC4} = {A5D9AA24-08ED-48B9-BD65-F0A25E96BFC4} 
     128                {4BF51C21-5A30-423B-82FE-1ED410E5769D} = {4BF51C21-5A30-423B-82FE-1ED410E5769D} 
    112129                {2A3F241E-682C-47E1-9543-DC28708B406A} = {2A3F241E-682C-47E1-9543-DC28708B406A} 
    113                 {4BF51C21-5A30-423B-82FE-1ED410E5769D} = {4BF51C21-5A30-423B-82FE-1ED410E5769D} 
    114                 {A5D9AA24-08ED-48B9-BD65-F0A25E96BFC4} = {A5D9AA24-08ED-48B9-BD65-F0A25E96BFC4} 
    115                 {4281CA5E-1D48-45D4-A991-2718A454B4BA} = {4281CA5E-1D48-45D4-A991-2718A454B4BA} 
    116                 {FE07F272-AE7F-4549-9E9F-EF9B80CB1693} = {FE07F272-AE7F-4549-9E9F-EF9B80CB1693} 
    117                 {6794B975-4E84-4F49-B2DC-C31F2224E03E} = {6794B975-4E84-4F49-B2DC-C31F2224E03E} 
    118                 {7FDE3880-A4AB-49E3-B439-EBEF0A0C7A65} = {7FDE3880-A4AB-49E3-B439-EBEF0A0C7A65} 
    119                 {3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA} = {3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA} 
    120                 {4B059DBA-CD9C-4D0F-BE8C-FFB4EFD498E9} = {4B059DBA-CD9C-4D0F-BE8C-FFB4EFD498E9} 
    121                 {855DC8C0-D3E9-4A2E-AE47-116605A7BC9B} = {855DC8C0-D3E9-4A2E-AE47-116605A7BC9B} 
    122                 {4B5945CD-0CB3-49AA-A7FF-7612D93F82C0} = {4B5945CD-0CB3-49AA-A7FF-7612D93F82C0} 
    123                 {B8719FD5-E8A6-4A36-943C-891D07F5DD21} = {B8719FD5-E8A6-4A36-943C-891D07F5DD21} 
    124                 {DA0E03ED-53A7-4050-8A85-90541C5509F8} = {DA0E03ED-53A7-4050-8A85-90541C5509F8} 
    125                 {B5FE16F8-3EDB-4110-BD80-B4238CC01E8D} = {B5FE16F8-3EDB-4110-BD80-B4238CC01E8D} 
    126                 {E53AA5FF-B737-40AA-BD13-387EFA99023D} = {E53AA5FF-B737-40AA-BD13-387EFA99023D} 
    127                 {A1989FF3-9894-40F4-B5A6-6EA364476E45} = {A1989FF3-9894-40F4-B5A6-6EA364476E45} 
    128                 {F0DBAA03-1BA3-4E3B-A2CA-727E3D3AB858} = {F0DBAA03-1BA3-4E3B-A2CA-727E3D3AB858} 
    129130        EndProjectSection 
    130131EndProject 
  • pjproject/branches/projects/2.0-dev/pjsip/include/pjsua-lib/pjsua.h

    r3457 r3463  
    30533053    pj_str_t            last_status_text; 
    30543054 
    3055     /** Call media status. */ 
     3055    /** Media status of the first audio stream. */ 
    30563056    pjsua_call_media_status media_status; 
    3057  
    3058     /** Number of active audio streams in this call */ 
    3059     unsigned            audio_cnt; 
    30603057 
    30613058    /** Media direction of the first audio stream. */ 
     
    30653062    pjsua_conf_port_id  conf_slot; 
    30663063 
    3067     /** Array of audio media stream information */ 
     3064    /** Number of media streams in this call */ 
     3065    unsigned            media_cnt; 
     3066 
     3067    /** Array of media stream information */ 
    30683068    struct 
    30693069    { 
     
    30713071        unsigned                index; 
    30723072 
     3073        /** Media type. */ 
     3074        pjmedia_type            type; 
     3075 
     3076        /** Media direction. */ 
     3077        pjmedia_dir             dir; 
     3078 
    30733079        /** Call media status. */ 
    3074         pjsua_call_media_status media_status; 
    3075  
    3076         /** Media direction. */ 
    3077         pjmedia_dir             media_dir; 
    3078  
    3079         /** The conference port number for the call. */ 
    3080         pjsua_conf_port_id      conf_slot; 
    3081  
    3082     } audio[4]; 
     3080        pjsua_call_media_status status; 
     3081 
     3082        /** The specific media stream info. */ 
     3083        union { 
     3084            /** Audio stream */ 
     3085            struct { 
     3086                pjsua_conf_port_id   conf_slot; /**< The conference port 
     3087                                                     number for the call.   */ 
     3088            } audio; 
     3089 
     3090            /** Video stream */ 
     3091            struct { 
     3092                pjmedia_vid_port    *capturer;  /**< Video capturer.        */ 
     3093                pjmedia_vid_port    *renderer;  /**< Video renderer.        */ 
     3094            } video; 
     3095        } stream; 
     3096 
     3097    } media[PJMEDIA_MAX_SDP_MEDIA]; 
    30833098 
    30843099    /** Up-to-date call connected duration (zero when call is not  
  • pjproject/branches/projects/2.0-dev/pjsip/include/pjsua-lib/pjsua_internal.h

    r3457 r3463  
    6262        /** Audio stream */ 
    6363        struct { 
    64             pjmedia_stream *stream;    /**< The media session.              */ 
     64            pjmedia_stream *stream;    /**< The audio stream.               */ 
    6565            int             conf_slot; /**< Slot # in conference bridge.    */ 
    6666        } a; 
     
    6868        /** Video stream */ 
    6969        struct { 
     70            pjmedia_vid_stream  *stream;    /**< The video stream.          */ 
     71            pjmedia_vid_port    *capturer;  /**< Video capturer.            */ 
     72            pjmedia_vid_port    *renderer;  /**< Video renderer.            */ 
     73            pjmedia_converter   *conv_enc;  /**< Converter for encoding dir.*/ 
     74            pjmedia_converter   *conv_dec;  /**< Converter for decoding dir.*/ 
    7075        } v; 
    7176 
     
    120125    unsigned             med_cnt;   /**< Number of media in SDP.            */ 
    121126    pjsua_call_media     media[PJSUA_MAX_CALL_MEDIA]; /**< Array of media   */ 
    122     unsigned             audio_idx; /**< Selected audio media.              */ 
     127    int                  audio_idx; /**< First active audio media.          */ 
    123128 
    124129    pjsip_evsub         *xfer_sub;  /**< Xfer server subscription, if this 
  • pjproject/branches/projects/2.0-dev/pjsip/src/pjsua-lib/pjsua_call.c

    r3457 r3463  
    13251325     
    13261326    /* Build array of media status and dir */ 
    1327     info->audio_cnt = 0; 
     1327    info->media_cnt = 0; 
    13281328    for (mi=0; mi < call->med_cnt && 
    1329                info->audio_cnt < PJ_ARRAY_SIZE(info->audio); ++mi) 
     1329               info->media_cnt < PJ_ARRAY_SIZE(info->media); ++mi) 
    13301330    { 
    13311331        pjsua_call_media *call_med = &call->media[mi]; 
    1332         if (call_med->type != PJMEDIA_TYPE_AUDIO) 
     1332 
     1333        info->media[info->media_cnt].index = mi; 
     1334        info->media[info->media_cnt].status = call_med->state; 
     1335        info->media[info->media_cnt].dir = call_med->dir; 
     1336        info->media[info->media_cnt].type = call_med->type; 
     1337 
     1338        if (call_med->type == PJMEDIA_TYPE_AUDIO) { 
     1339            info->media[info->media_cnt].stream.audio.conf_slot =  
     1340                                                call_med->strm.a.conf_slot; 
     1341        } else if (call_med->type == PJMEDIA_TYPE_VIDEO) { 
     1342            info->media[info->media_cnt].stream.video.capturer = 
     1343                                                call_med->strm.v.capturer; 
     1344            info->media[info->media_cnt].stream.video.renderer = 
     1345                                                call_med->strm.v.renderer; 
     1346        } else { 
    13331347            continue; 
    1334         info->audio[info->audio_cnt].index = mi; 
    1335         info->audio[info->audio_cnt].media_status = call_med->state; 
    1336         info->audio[info->audio_cnt].media_dir = call_med->dir; 
    1337         info->audio[info->audio_cnt].conf_slot = call_med->strm.a.conf_slot; 
    1338         ++info->audio_cnt; 
    1339     } 
    1340  
    1341     if (info->audio_cnt) { 
    1342         info->media_status = info->audio[0].media_status; 
    1343         info->media_dir = info->audio[0].media_dir; 
    1344     } 
    1345  
    1346     /* conference slot number */ 
    1347     info->conf_slot = call->media[call->audio_idx].strm.a.conf_slot; 
     1348        } 
     1349        ++info->media_cnt; 
     1350    } 
     1351 
     1352    if (call->audio_idx != -1) { 
     1353        info->media_status = call->media[call->audio_idx].state; 
     1354        info->media_dir = call->media[call->audio_idx].dir; 
     1355        info->conf_slot = call->media[call->audio_idx].strm.a.conf_slot; 
     1356    } 
    13481357 
    13491358    /* calculate duration */ 
     
    21922201} 
    21932202 
     2203static unsigned dump_media_stat(const char *indent,  
     2204                                char *buf, unsigned maxlen, 
     2205                                const pjmedia_rtcp_stat *stat, 
     2206                                const char *rx_info, const char *tx_info) 
     2207{ 
     2208    char last_update[64]; 
     2209    char packets[32], bytes[32], ipbytes[32], avg_bps[32], avg_ipbps[32]; 
     2210    pj_time_val media_duration, now; 
     2211    char *p = buf, *end = buf+maxlen; 
     2212    int len; 
     2213 
     2214    if (stat->rx.update_cnt == 0) 
     2215        strcpy(last_update, "never"); 
     2216    else { 
     2217        pj_gettimeofday(&now); 
     2218        PJ_TIME_VAL_SUB(now, stat->rx.update); 
     2219        sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago", 
     2220                now.sec / 3600, 
     2221                (now.sec % 3600) / 60, 
     2222                now.sec % 60, 
     2223                now.msec); 
     2224    } 
     2225 
     2226    pj_gettimeofday(&media_duration); 
     2227    PJ_TIME_VAL_SUB(media_duration, stat->start); 
     2228    if (PJ_TIME_VAL_MSEC(media_duration) == 0) 
     2229        media_duration.msec = 1; 
     2230 
     2231    len = pj_ansi_snprintf(p, end-p, 
     2232           "%s     RX %s last update:%s\n" 
     2233           "%s        total %spkt %sB (%sB +IP hdr) @avg=%sbps/%sbps\n" 
     2234           "%s        pkt loss=%d (%3.1f%%), discrd=%d (%3.1f%%), dup=%d (%2.1f%%), reord=%d (%3.1f%%)\n" 
     2235           "%s              (msec)    min     avg     max     last    dev\n" 
     2236           "%s        loss period: %7.3f %7.3f %7.3f %7.3f %7.3f\n" 
     2237           "%s        jitter     : %7.3f %7.3f %7.3f %7.3f %7.3f\n" 
     2238#if defined(PJMEDIA_RTCP_STAT_HAS_RAW_JITTER) && PJMEDIA_RTCP_STAT_HAS_RAW_JITTER!=0 
     2239           "%s        raw jitter : %7.3f %7.3f %7.3f %7.3f %7.3f\n" 
     2240#endif 
     2241#if defined(PJMEDIA_RTCP_STAT_HAS_IPDV) && PJMEDIA_RTCP_STAT_HAS_IPDV!=0 
     2242           "%s        IPDV       : %7.3f %7.3f %7.3f %7.3f %7.3f\n" 
     2243#endif 
     2244           "%s", 
     2245           indent, 
     2246           rx_info? rx_info : "", 
     2247           last_update, 
     2248 
     2249           indent, 
     2250           good_number(packets, stat->rx.pkt), 
     2251           good_number(bytes, stat->rx.bytes), 
     2252           good_number(ipbytes, stat->rx.bytes + stat->rx.pkt * 40), 
     2253           good_number(avg_bps, (pj_int32_t)((pj_int64_t)stat->rx.bytes * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))), 
     2254           good_number(avg_ipbps, (pj_int32_t)(((pj_int64_t)stat->rx.bytes + stat->rx.pkt * 40) * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))), 
     2255           indent, 
     2256           stat->rx.loss, 
     2257           (stat->rx.loss? stat->rx.loss * 100.0 / (stat->rx.pkt + stat->rx.loss) : 0), 
     2258           stat->rx.discard,  
     2259           (stat->rx.discard? stat->rx.discard * 100.0 / (stat->rx.pkt + stat->rx.loss) : 0), 
     2260           stat->rx.dup,  
     2261           (stat->rx.dup? stat->rx.dup * 100.0 / (stat->rx.pkt + stat->rx.loss) : 0), 
     2262           stat->rx.reorder,  
     2263           (stat->rx.reorder? stat->rx.reorder * 100.0 / (stat->rx.pkt + stat->rx.loss) : 0), 
     2264           indent, indent, 
     2265           stat->rx.loss_period.min / 1000.0,  
     2266           stat->rx.loss_period.mean / 1000.0,  
     2267           stat->rx.loss_period.max / 1000.0, 
     2268           stat->rx.loss_period.last / 1000.0, 
     2269           pj_math_stat_get_stddev(&stat->rx.loss_period) / 1000.0, 
     2270           indent, 
     2271           stat->rx.jitter.min / 1000.0, 
     2272           stat->rx.jitter.mean / 1000.0, 
     2273           stat->rx.jitter.max / 1000.0, 
     2274           stat->rx.jitter.last / 1000.0, 
     2275           pj_math_stat_get_stddev(&stat->rx.jitter) / 1000.0, 
     2276#if defined(PJMEDIA_RTCP_STAT_HAS_RAW_JITTER) && PJMEDIA_RTCP_STAT_HAS_RAW_JITTER!=0 
     2277           indent, 
     2278           stat->rx_raw_jitter.min / 1000.0, 
     2279           stat->rx_raw_jitter.mean / 1000.0, 
     2280           stat->rx_raw_jitter.max / 1000.0, 
     2281           stat->rx_raw_jitter.last / 1000.0, 
     2282           pj_math_stat_get_stddev(&stat->rx_raw_jitter) / 1000.0, 
     2283#endif 
     2284#if defined(PJMEDIA_RTCP_STAT_HAS_IPDV) && PJMEDIA_RTCP_STAT_HAS_IPDV!=0 
     2285           indent, 
     2286           stat->rx_ipdv.min / 1000.0, 
     2287           stat->rx_ipdv.mean / 1000.0, 
     2288           stat->rx_ipdv.max / 1000.0, 
     2289           stat->rx_ipdv.last / 1000.0, 
     2290           pj_math_stat_get_stddev(&stat->rx_ipdv) / 1000.0, 
     2291#endif 
     2292           "" 
     2293           ); 
     2294 
     2295    if (len < 1 || len > end-p) { 
     2296        *p = '\0'; 
     2297        return (p-buf); 
     2298    } 
     2299    p += len; 
     2300 
     2301    if (stat->tx.update_cnt == 0) 
     2302        strcpy(last_update, "never"); 
     2303    else { 
     2304        pj_gettimeofday(&now); 
     2305        PJ_TIME_VAL_SUB(now, stat->tx.update); 
     2306        sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago", 
     2307                now.sec / 3600, 
     2308                (now.sec % 3600) / 60, 
     2309                now.sec % 60, 
     2310                now.msec); 
     2311    } 
     2312 
     2313    len = pj_ansi_snprintf(p, end-p, 
     2314           "%s     TX %s last update:%s\n" 
     2315           "%s        total %spkt %sB (%sB +IP hdr) @avg %sbps/%sbps\n" 
     2316           "%s        pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)\n" 
     2317           "%s              (msec)    min     avg     max     last    dev \n" 
     2318           "%s        loss period: %7.3f %7.3f %7.3f %7.3f %7.3f\n" 
     2319           "%s        jitter     : %7.3f %7.3f %7.3f %7.3f %7.3f\n", 
     2320           indent, 
     2321           tx_info, 
     2322           last_update, 
     2323 
     2324           indent, 
     2325           good_number(packets, stat->tx.pkt), 
     2326           good_number(bytes, stat->tx.bytes), 
     2327           good_number(ipbytes, stat->tx.bytes + stat->tx.pkt * 40), 
     2328           good_number(avg_bps, (pj_int32_t)((pj_int64_t)stat->tx.bytes * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))), 
     2329           good_number(avg_ipbps, (pj_int32_t)(((pj_int64_t)stat->tx.bytes + stat->tx.pkt * 40) * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))), 
     2330 
     2331           indent, 
     2332           stat->tx.loss, 
     2333           (stat->tx.loss? stat->tx.loss * 100.0 / (stat->tx.pkt + stat->tx.loss) : 0), 
     2334           stat->tx.dup,  
     2335           (stat->tx.dup? stat->tx.dup * 100.0 / (stat->tx.pkt + stat->tx.loss) : 0), 
     2336           stat->tx.reorder,  
     2337           (stat->tx.reorder? stat->tx.reorder * 100.0 / (stat->tx.pkt + stat->tx.loss) : 0), 
     2338 
     2339           indent, indent, 
     2340           stat->tx.loss_period.min / 1000.0,  
     2341           stat->tx.loss_period.mean / 1000.0,  
     2342           stat->tx.loss_period.max / 1000.0, 
     2343           stat->tx.loss_period.last / 1000.0, 
     2344           pj_math_stat_get_stddev(&stat->tx.loss_period) / 1000.0, 
     2345           indent, 
     2346           stat->tx.jitter.min / 1000.0, 
     2347           stat->tx.jitter.mean / 1000.0, 
     2348           stat->tx.jitter.max / 1000.0, 
     2349           stat->tx.jitter.last / 1000.0, 
     2350           pj_math_stat_get_stddev(&stat->tx.jitter) / 1000.0 
     2351           ); 
     2352 
     2353    if (len < 1 || len > end-p) { 
     2354        *p = '\0'; 
     2355        return (p-buf); 
     2356    } 
     2357    p += len; 
     2358 
     2359    len = pj_ansi_snprintf(p, end-p, 
     2360           "%s     RTT msec      : %7.3f %7.3f %7.3f %7.3f %7.3f\n", 
     2361           indent, 
     2362           stat->rtt.min / 1000.0, 
     2363           stat->rtt.mean / 1000.0, 
     2364           stat->rtt.max / 1000.0, 
     2365           stat->rtt.last / 1000.0, 
     2366           pj_math_stat_get_stddev(&stat->rtt) / 1000.0 
     2367           ); 
     2368    if (len < 1 || len > end-p) { 
     2369        *p = '\0'; 
     2370        return (p-buf); 
     2371    } 
     2372    p += len; 
     2373 
     2374    return (p-buf); 
     2375} 
     2376 
    21942377 
    21952378/* Dump media session */ 
     
    22042387    for (i=0; i<call->med_cnt; ++i) { 
    22052388        pjsua_call_media *call_med = &call->media[i]; 
    2206         pjmedia_stream_info info; 
    2207         pjmedia_stream *stream = call_med->strm.a.stream; 
     2389        pjmedia_rtcp_stat stat; 
     2390        pj_bool_t has_stat; 
    22082391        pjmedia_transport_info tp_info; 
    2209         pjmedia_rtcp_stat stat; 
    22102392        char rem_addr_buf[80]; 
     2393        char codec_info[32] = {'0'}; 
     2394        char rx_info[80] = {'\0'}; 
     2395        char tx_info[80] = {'\0'}; 
    22112396        const char *rem_addr; 
    2212         const char *dir; 
    2213         char last_update[64]; 
    2214         char packets[32], bytes[32], ipbytes[32], avg_bps[32], avg_ipbps[32]; 
    2215         pj_time_val media_duration, now; 
     2397        const char *dir_str; 
     2398        const char *media_type_str; 
     2399 
     2400        switch (call_med->type) { 
     2401        case PJMEDIA_TYPE_AUDIO: 
     2402            media_type_str = "audio"; 
     2403            break; 
     2404        case PJMEDIA_TYPE_VIDEO: 
     2405            media_type_str = "video"; 
     2406            break; 
     2407        case PJMEDIA_TYPE_APPLICATION: 
     2408            media_type_str = "application"; 
     2409            break; 
     2410        default: 
     2411            media_type_str = "unknown"; 
     2412            break; 
     2413        } 
    22162414 
    22172415        /* Check if the stream is deactivated */ 
    2218         if (call_med->tp == NULL || stream == NULL) { 
    2219             const char *media_type_str; 
    2220  
    2221             switch (call_med->type) { 
    2222             case PJMEDIA_TYPE_AUDIO: 
    2223                 media_type_str = "audio"; 
    2224                 break; 
    2225             case PJMEDIA_TYPE_VIDEO: 
    2226                 media_type_str = "video"; 
    2227                 break; 
    2228             case PJMEDIA_TYPE_APPLICATION: 
    2229                 media_type_str = "application"; 
    2230                 break; 
    2231             default: 
    2232                 media_type_str = "unknown"; 
    2233                 break; 
    2234             } 
     2416        if (call_med->tp == NULL || 
     2417            (!call_med->strm.a.stream && !call_med->strm.v.stream)) 
     2418        { 
    22352419            len = pj_ansi_snprintf(p, end-p, 
    2236                       "%s  #%d m=%s deactivated\n", 
     2420                      "%s #%d %s deactivated\n", 
    22372421                      indent, i, media_type_str); 
    22382422            if (len < 1 || len > end-p) { 
     
    22472431        pjmedia_transport_info_init(&tp_info); 
    22482432        pjmedia_transport_get_info(call_med->tp, &tp_info); 
    2249  
    2250         pjmedia_stream_get_info(stream, &info); 
    2251         pjmedia_stream_get_stat(stream, &stat); 
    22522433 
    22532434        // rem_addr will contain actual address of RTP originator, instead of 
     
    22682449             * (http://trac.pjsip.org/repos/ticket/1079) 
    22692450             */ 
    2270             dir = "inactive"; 
    2271         } else if (info.dir == PJMEDIA_DIR_ENCODING) 
    2272             dir = "sendonly"; 
    2273         else if (info.dir == PJMEDIA_DIR_DECODING) 
    2274             dir = "recvonly"; 
    2275         else if (info.dir == PJMEDIA_DIR_ENCODING_DECODING) 
    2276             dir = "sendrecv"; 
     2451            dir_str = "inactive"; 
     2452        } else if (call_med->dir == PJMEDIA_DIR_ENCODING) 
     2453            dir_str = "sendonly"; 
     2454        else if (call_med->dir == PJMEDIA_DIR_DECODING) 
     2455            dir_str = "recvonly"; 
     2456        else if (call_med->dir == PJMEDIA_DIR_ENCODING_DECODING) 
     2457            dir_str = "sendrecv"; 
    22772458        else 
    2278             dir = "inactive"; 
    2279  
    2280          
     2459            dir_str = "inactive"; 
     2460 
     2461        if (call_med->type == PJMEDIA_TYPE_AUDIO) { 
     2462            pjmedia_stream *stream = call_med->strm.a.stream; 
     2463            pjmedia_stream_info info; 
     2464 
     2465            pjmedia_stream_get_stat(stream, &stat); 
     2466            has_stat = PJ_TRUE; 
     2467 
     2468            pjmedia_stream_get_info(stream, &info); 
     2469            pj_ansi_snprintf(codec_info, sizeof(codec_info), " %.*s @%dkHz", 
     2470                             info.fmt.encoding_name.slen, 
     2471                             info.fmt.encoding_name.ptr, 
     2472                             info.fmt.clock_rate / 1000); 
     2473            pj_ansi_snprintf(rx_info, sizeof(rx_info), "pt=%d,", 
     2474                             info.fmt.pt); 
     2475            pj_ansi_snprintf(tx_info, sizeof(tx_info), "pt=%d, ptime=%d,", 
     2476                             info.tx_pt, 
     2477                             info.param->setting.frm_per_pkt* 
     2478                             info.param->info.frm_ptime); 
     2479        } else if (call_med->type == PJMEDIA_TYPE_VIDEO) { 
     2480            pjmedia_vid_stream *stream = call_med->strm.v.stream; 
     2481            pjmedia_vid_stream_info info; 
     2482 
     2483            pjmedia_vid_stream_get_stat(stream, &stat); 
     2484            has_stat = PJ_TRUE; 
     2485 
     2486            pjmedia_vid_stream_get_info(stream, &info); 
     2487            pj_ansi_snprintf(codec_info, sizeof(codec_info), " %.*s", 
     2488                             info.codec_info.encoding_name.slen, 
     2489                             info.codec_info.encoding_name.ptr); 
     2490            if (call_med->dir & PJMEDIA_DIR_DECODING) { 
     2491                pjmedia_video_format_detail *vfd; 
     2492                vfd = pjmedia_format_get_video_format_detail( 
     2493                                        &info.codec_param->dec_fmt, PJ_TRUE); 
     2494                pj_ansi_snprintf(rx_info, sizeof(rx_info), 
     2495                                 "pt=%d, size=%dx%d, fps=%.2f,", 
     2496                                 info.rx_pt, 
     2497                                 vfd->size.w, vfd->size.h, 
     2498                                 vfd->fps.num*1.0/vfd->fps.denum); 
     2499            } 
     2500            if (call_med->dir & PJMEDIA_DIR_ENCODING) { 
     2501                pjmedia_video_format_detail *vfd; 
     2502                vfd = pjmedia_format_get_video_format_detail( 
     2503                                        &info.codec_param->enc_fmt, PJ_TRUE); 
     2504                pj_ansi_snprintf(tx_info, sizeof(tx_info), 
     2505                                 "pt=%d, size=%dx%d, fps=%.2f,", 
     2506                                 info.tx_pt, 
     2507                                 vfd->size.w, vfd->size.h, 
     2508                                 vfd->fps.num*1.0/vfd->fps.denum); 
     2509            } 
     2510        } else { 
     2511            has_stat = PJ_FALSE; 
     2512        } 
     2513 
    22812514        len = pj_ansi_snprintf(p, end-p, 
    2282                   "%s  #%d %.*s @%dKHz, %s, peer=%s", 
    2283                   indent, i, 
    2284                   (int)info.fmt.encoding_name.slen, 
    2285                   info.fmt.encoding_name.ptr, 
    2286                   info.fmt.clock_rate / 1000, 
    2287                   dir, 
     2515                  "%s  #%d %s%s, %s, peer=%s\n", 
     2516                  indent, 
     2517                  call_med->idx, 
     2518                  media_type_str, 
     2519                  codec_info, 
     2520                  dir_str, 
    22882521                  rem_addr); 
    22892522        if (len < 1 || len > end-p) { 
     
    22912524            return; 
    22922525        } 
    2293  
    22942526        p += len; 
    2295         *p++ = '\n'; 
    2296         *p = '\0'; 
    2297  
    2298         if (stat.rx.update_cnt == 0) 
    2299             strcpy(last_update, "never"); 
    2300         else { 
    2301             pj_gettimeofday(&now); 
    2302             PJ_TIME_VAL_SUB(now, stat.rx.update); 
    2303             sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago", 
    2304                     now.sec / 3600, 
    2305                     (now.sec % 3600) / 60, 
    2306                     now.sec % 60, 
    2307                     now.msec); 
    2308         } 
    2309  
    2310         pj_gettimeofday(&media_duration); 
    2311         PJ_TIME_VAL_SUB(media_duration, stat.start); 
    2312         if (PJ_TIME_VAL_MSEC(media_duration) == 0) 
    2313             media_duration.msec = 1; 
    2314  
    2315         /* protect against division by zero */ 
    2316         if (stat.rx.pkt == 0) 
    2317             stat.rx.pkt = 1; 
    2318         if (stat.tx.pkt == 0) 
    2319             stat.tx.pkt = 1; 
    2320  
    2321         len = pj_ansi_snprintf(p, end-p, 
    2322                "%s     RX pt=%d, stat last update: %s\n" 
    2323                "%s        total %spkt %sB (%sB +IP hdr) @avg=%sbps/%sbps\n" 
    2324                "%s        pkt loss=%d (%3.1f%%), discrd=%d (%3.1f%%), dup=%d (%2.1f%%), reord=%d (%3.1f%%)\n" 
    2325                "%s              (msec)    min     avg     max     last    dev\n" 
    2326                "%s        loss period: %7.3f %7.3f %7.3f %7.3f %7.3f\n" 
    2327                "%s        jitter     : %7.3f %7.3f %7.3f %7.3f %7.3f" 
    2328 #if defined(PJMEDIA_RTCP_STAT_HAS_RAW_JITTER) && PJMEDIA_RTCP_STAT_HAS_RAW_JITTER!=0 
    2329                "\n" 
    2330                "%s        raw jitter : %7.3f %7.3f %7.3f %7.3f %7.3f" 
    2331 #endif 
    2332 #if defined(PJMEDIA_RTCP_STAT_HAS_IPDV) && PJMEDIA_RTCP_STAT_HAS_IPDV!=0 
    2333                "\n" 
    2334                "%s        IPDV       : %7.3f %7.3f %7.3f %7.3f %7.3f" 
    2335 #endif 
    2336                "%s", 
    2337                indent, info.fmt.pt, 
    2338                last_update, 
    2339                indent, 
    2340                good_number(packets, stat.rx.pkt), 
    2341                good_number(bytes, stat.rx.bytes), 
    2342                good_number(ipbytes, stat.rx.bytes + stat.rx.pkt * 40), 
    2343                good_number(avg_bps, (pj_int32_t)((pj_int64_t)stat.rx.bytes * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))), 
    2344                good_number(avg_ipbps, (pj_int32_t)(((pj_int64_t)stat.rx.bytes + stat.rx.pkt * 40) * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))), 
    2345                indent, 
    2346                stat.rx.loss, 
    2347                stat.rx.loss * 100.0 / (stat.rx.pkt + stat.rx.loss), 
    2348                stat.rx.discard,  
    2349                stat.rx.discard * 100.0 / (stat.rx.pkt + stat.rx.loss), 
    2350                stat.rx.dup,  
    2351                stat.rx.dup * 100.0 / (stat.rx.pkt + stat.rx.loss), 
    2352                stat.rx.reorder,  
    2353                stat.rx.reorder * 100.0 / (stat.rx.pkt + stat.rx.loss), 
    2354                indent, indent, 
    2355                stat.rx.loss_period.min / 1000.0,  
    2356                stat.rx.loss_period.mean / 1000.0,  
    2357                stat.rx.loss_period.max / 1000.0, 
    2358                stat.rx.loss_period.last / 1000.0, 
    2359                pj_math_stat_get_stddev(&stat.rx.loss_period) / 1000.0, 
    2360                indent, 
    2361                stat.rx.jitter.min / 1000.0, 
    2362                stat.rx.jitter.mean / 1000.0, 
    2363                stat.rx.jitter.max / 1000.0, 
    2364                stat.rx.jitter.last / 1000.0, 
    2365                pj_math_stat_get_stddev(&stat.rx.jitter) / 1000.0, 
    2366 #if defined(PJMEDIA_RTCP_STAT_HAS_RAW_JITTER) && PJMEDIA_RTCP_STAT_HAS_RAW_JITTER!=0 
    2367                indent, 
    2368                stat.rx_raw_jitter.min / 1000.0, 
    2369                stat.rx_raw_jitter.mean / 1000.0, 
    2370                stat.rx_raw_jitter.max / 1000.0, 
    2371                stat.rx_raw_jitter.last / 1000.0, 
    2372                pj_math_stat_get_stddev(&stat.rx_raw_jitter) / 1000.0, 
    2373 #endif 
    2374 #if defined(PJMEDIA_RTCP_STAT_HAS_IPDV) && PJMEDIA_RTCP_STAT_HAS_IPDV!=0 
    2375                indent, 
    2376                stat.rx_ipdv.min / 1000.0, 
    2377                stat.rx_ipdv.mean / 1000.0, 
    2378                stat.rx_ipdv.max / 1000.0, 
    2379                stat.rx_ipdv.last / 1000.0, 
    2380                pj_math_stat_get_stddev(&stat.rx_ipdv) / 1000.0, 
    2381 #endif 
    2382                "" 
    2383                ); 
    2384  
    2385         if (len < 1 || len > end-p) { 
    2386             *p = '\0'; 
    2387             return; 
    2388         } 
    2389  
    2390         p += len; 
    2391         *p++ = '\n'; 
    2392         *p = '\0'; 
    2393          
    2394         if (stat.tx.update_cnt == 0) 
    2395             strcpy(last_update, "never"); 
    2396         else { 
    2397             pj_gettimeofday(&now); 
    2398             PJ_TIME_VAL_SUB(now, stat.tx.update); 
    2399             sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago", 
    2400                     now.sec / 3600, 
    2401                     (now.sec % 3600) / 60, 
    2402                     now.sec % 60, 
    2403                     now.msec); 
    2404         } 
    2405  
    2406         len = pj_ansi_snprintf(p, end-p, 
    2407                "%s     TX pt=%d, ptime=%dms, stat last update: %s\n" 
    2408                "%s        total %spkt %sB (%sB +IP hdr) @avg %sbps/%sbps\n" 
    2409                "%s        pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)\n" 
    2410                "%s              (msec)    min     avg     max     last    dev \n" 
    2411                "%s        loss period: %7.3f %7.3f %7.3f %7.3f %7.3f\n" 
    2412                "%s        jitter     : %7.3f %7.3f %7.3f %7.3f %7.3f%s", 
    2413                indent, 
    2414                info.tx_pt, 
    2415                info.param->info.frm_ptime * info.param->setting.frm_per_pkt, 
    2416                last_update, 
    2417  
    2418                indent, 
    2419                good_number(packets, stat.tx.pkt), 
    2420                good_number(bytes, stat.tx.bytes), 
    2421                good_number(ipbytes, stat.tx.bytes + stat.tx.pkt * 40), 
    2422                good_number(avg_bps, (pj_int32_t)((pj_int64_t)stat.tx.bytes * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))), 
    2423                good_number(avg_ipbps, (pj_int32_t)(((pj_int64_t)stat.tx.bytes + stat.tx.pkt * 40) * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))), 
    2424  
    2425                indent, 
    2426                stat.tx.loss, 
    2427                stat.tx.loss * 100.0 / (stat.tx.pkt + stat.tx.loss), 
    2428                stat.tx.dup,  
    2429                stat.tx.dup * 100.0 / (stat.tx.pkt + stat.tx.loss), 
    2430                stat.tx.reorder,  
    2431                stat.tx.reorder * 100.0 / (stat.tx.pkt + stat.tx.loss), 
    2432  
    2433                indent, indent, 
    2434                stat.tx.loss_period.min / 1000.0,  
    2435                stat.tx.loss_period.mean / 1000.0,  
    2436                stat.tx.loss_period.max / 1000.0, 
    2437                stat.tx.loss_period.last / 1000.0, 
    2438                pj_math_stat_get_stddev(&stat.tx.loss_period) / 1000.0, 
    2439                indent, 
    2440                stat.tx.jitter.min / 1000.0, 
    2441                stat.tx.jitter.mean / 1000.0, 
    2442                stat.tx.jitter.max / 1000.0, 
    2443                stat.tx.jitter.last / 1000.0, 
    2444                pj_math_stat_get_stddev(&stat.tx.jitter) / 1000.0, 
    2445                "" 
    2446                ); 
    2447  
    2448         if (len < 1 || len > end-p) { 
    2449             *p = '\0'; 
    2450             return; 
    2451         } 
    2452  
    2453         p += len; 
    2454         *p++ = '\n'; 
    2455         *p = '\0'; 
    2456  
    2457         len = pj_ansi_snprintf(p, end-p, 
    2458                "%s     RTT msec      : %7.3f %7.3f %7.3f %7.3f %7.3f", 
    2459                indent, 
    2460                stat.rtt.min / 1000.0, 
    2461                stat.rtt.mean / 1000.0, 
    2462                stat.rtt.max / 1000.0, 
    2463                stat.rtt.last / 1000.0, 
    2464                pj_math_stat_get_stddev(&stat.rtt) / 1000.0 
    2465                ); 
    2466         if (len < 1 || len > end-p) { 
    2467             *p = '\0'; 
    2468             return; 
    2469         } 
    2470  
    2471         p += len; 
    2472         *p++ = '\n'; 
    2473         *p = '\0'; 
     2527 
     2528        if (has_stat) { 
     2529            len = dump_media_stat(indent, p, end-p, &stat, 
     2530                                  rx_info, tx_info); 
     2531            p += len; 
     2532        } 
    24742533 
    24752534#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0) 
  • pjproject/branches/projects/2.0-dev/pjsip/src/pjsua-lib/pjsua_core.c

    r3457 r3463  
    14461446        pj_caching_pool_destroy(&pjsua_var.cp); 
    14471447 
     1448        pjsua_set_state(PJSUA_STATE_NULL); 
     1449 
    14481450        PJ_LOG(4,(THIS_FILE, "PJSUA destroyed...")); 
    14491451 
     
    14601462    /* Clear pjsua_var */ 
    14611463    pj_bzero(&pjsua_var, sizeof(pjsua_var)); 
    1462  
    1463     pjsua_set_state(PJSUA_STATE_NULL); 
    14641464 
    14651465    /* Done. */ 
  • pjproject/branches/projects/2.0-dev/pjsip/src/pjsua-lib/pjsua_media.c

    r3457 r3463  
    14741474        maudcnt = acc->cfg.max_audio_cnt; 
    14751475        for (mi=0; mi<maudcnt; ++mi) { 
    1476             maudidx[mi] = mi; 
     1476            maudidx[mi] = (pj_uint8_t)mi; 
    14771477            media_types[mi] = PJMEDIA_TYPE_AUDIO; 
    14781478        } 
     
    18361836                pjmedia_stream_destroy(strm); 
    18371837                call_med->strm.a.stream = NULL; 
    1838  
    1839                 PJ_LOG(4,(THIS_FILE, "Media session call%02d:%d is destroyed", 
    1840                                      call_id, mi)); 
    18411838            } 
    1842         } 
     1839        } else if (call_med->type == PJMEDIA_TYPE_VIDEO) { 
     1840            pjmedia_vid_stream *strm = call_med->strm.v.stream; 
     1841 
     1842            if (strm) { 
     1843                pjmedia_rtcp_stat stat; 
     1844 
     1845                if (call_med->strm.v.capturer) { 
     1846                    pjmedia_vid_port_stop(call_med->strm.v.capturer); 
     1847                    pjmedia_vid_port_destroy(call_med->strm.v.capturer); 
     1848                    call_med->strm.v.capturer = NULL; 
     1849                } 
     1850 
     1851                if (call_med->strm.v.renderer) { 
     1852                    pjmedia_vid_port_stop(call_med->strm.v.renderer); 
     1853                    pjmedia_vid_port_destroy(call_med->strm.v.renderer); 
     1854                    call_med->strm.v.renderer = NULL; 
     1855                } 
     1856 
     1857                if ((call_med->dir & PJMEDIA_DIR_ENCODING) && 
     1858                    (pjmedia_vid_stream_get_stat(strm, &stat) == PJ_SUCCESS)) 
     1859                { 
     1860                    /* Save RTP timestamp & sequence, so when media session is 
     1861                     * restarted, those values will be restored as the initial 
     1862                     * RTP timestamp & sequence of the new media session. So in 
     1863                     * the same call session, RTP timestamp and sequence are 
     1864                     * guaranteed to be contigue. 
     1865                     */ 
     1866                    call_med->rtp_tx_seq_ts_set = 1 | (1 << 1); 
     1867                    call_med->rtp_tx_seq = stat.rtp_tx_last_seq; 
     1868                    call_med->rtp_tx_ts = stat.rtp_tx_last_ts; 
     1869                } 
     1870 
     1871                pjmedia_vid_stream_destroy(strm); 
     1872                call_med->strm.v.stream = NULL; 
     1873            } 
     1874        } 
     1875 
     1876        PJ_LOG(4,(THIS_FILE, "Media session call%02d:%d is destroyed", 
     1877                             call_id, mi)); 
    18431878        call_med->state = PJSUA_CALL_MEDIA_NONE; 
    18441879    } 
     
    20992134} 
    21002135 
     2136static pj_status_t video_channel_update(pjsua_call_media *call_med, 
     2137                                        pj_pool_t *tmp_pool, 
     2138                                        const pjmedia_sdp_session *local_sdp, 
     2139                                        const pjmedia_sdp_session *remote_sdp) 
     2140{ 
     2141    pjsua_call *call = call_med->call; 
     2142    pjmedia_vid_stream_info the_si, *si = &the_si; 
     2143    pjmedia_port *media_port; 
     2144    unsigned strm_idx = call_med->idx; 
     2145    pj_status_t status; 
     2146     
     2147    status = pjmedia_vid_stream_info_from_sdp(si, tmp_pool, pjsua_var.med_endpt, 
     2148                                              local_sdp, remote_sdp, strm_idx); 
     2149    if (status != PJ_SUCCESS) 
     2150        return status; 
     2151 
     2152    /* Check if no media is active */ 
     2153    if (si->dir == PJMEDIA_DIR_NONE) { 
     2154        /* Call media state */ 
     2155        call_med->state = PJSUA_CALL_MEDIA_NONE; 
     2156 
     2157        /* Call media direction */ 
     2158        call_med->dir = PJMEDIA_DIR_NONE; 
     2159 
     2160    } else { 
     2161        pjmedia_transport_info tp_info; 
     2162 
     2163        /* Start/restart media transport */ 
     2164        status = pjmedia_transport_media_start(call_med->tp, 
     2165                                               tmp_pool, local_sdp, 
     2166                                               remote_sdp, strm_idx); 
     2167        if (status != PJ_SUCCESS) 
     2168            return status; 
     2169 
     2170        call_med->tp_st = PJSUA_MED_TP_RUNNING; 
     2171 
     2172        /* Get remote SRTP usage policy */ 
     2173        pjmedia_transport_info_init(&tp_info); 
     2174        pjmedia_transport_get_info(call_med->tp, &tp_info); 
     2175        if (tp_info.specific_info_cnt > 0) { 
     2176            unsigned i; 
     2177            for (i = 0; i < tp_info.specific_info_cnt; ++i) { 
     2178                if (tp_info.spc_info[i].type == PJMEDIA_TRANSPORT_TYPE_SRTP)  
     2179                { 
     2180                    pjmedia_srtp_info *srtp_info =  
     2181                                (pjmedia_srtp_info*) tp_info.spc_info[i].buffer; 
     2182 
     2183                    call_med->rem_srtp_use = srtp_info->peer_use; 
     2184                    break; 
     2185                } 
     2186            } 
     2187        } 
     2188 
     2189        /* Optionally, application may modify other stream settings here 
     2190         * (such as jitter buffer parameters, codec ptime, etc.) 
     2191         */ 
     2192        si->jb_init = pjsua_var.media_cfg.jb_init; 
     2193        si->jb_min_pre = pjsua_var.media_cfg.jb_min_pre; 
     2194        si->jb_max_pre = pjsua_var.media_cfg.jb_max_pre; 
     2195        si->jb_max = pjsua_var.media_cfg.jb_max; 
     2196 
     2197        /* Set SSRC */ 
     2198        si->ssrc = call_med->ssrc; 
     2199 
     2200        /* Set RTP timestamp & sequence, normally these value are intialized 
     2201         * automatically when stream session created, but for some cases (e.g: 
     2202         * call reinvite, call update) timestamp and sequence need to be kept 
     2203         * contigue. 
     2204         */ 
     2205        si->rtp_ts = call_med->rtp_tx_ts; 
     2206        si->rtp_seq = call_med->rtp_tx_seq; 
     2207        si->rtp_seq_ts_set = call_med->rtp_tx_seq_ts_set; 
     2208 
     2209#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0 
     2210        /* Enable/disable stream keep-alive and NAT hole punch. */ 
     2211        si->use_ka = pjsua_var.acc[call->acc_id].cfg.use_stream_ka; 
     2212#endif 
     2213 
     2214        /* Create session based on session info. */ 
     2215        status = pjmedia_vid_stream_create(pjsua_var.med_endpt, NULL, si, 
     2216                                           call_med->tp, NULL, 
     2217                                           &call_med->strm.v.stream); 
     2218        if (status != PJ_SUCCESS) 
     2219            return status; 
     2220 
     2221        /* Start stream */ 
     2222        status = pjmedia_vid_stream_start(call_med->strm.v.stream); 
     2223        if (status != PJ_SUCCESS) 
     2224            return status; 
     2225 
     2226        /* Setup decoding direction */ 
     2227        if (si->dir & PJMEDIA_DIR_DECODING) { 
     2228            pjmedia_vid_port_param vport_param; 
     2229 
     2230            status = pjmedia_vid_stream_get_port(call_med->strm.v.stream, 
     2231                                                 PJMEDIA_DIR_DECODING, 
     2232                                                 &media_port); 
     2233            if (status != PJ_SUCCESS) 
     2234                return status; 
     2235 
     2236            status = pjmedia_vid_dev_default_param( 
     2237                                tmp_pool, PJMEDIA_VID_DEFAULT_RENDER_DEV, 
     2238                                &vport_param.vidparam); 
     2239            if (status != PJ_SUCCESS) 
     2240                return status; 
     2241 
     2242            pjmedia_format_copy(&vport_param.vidparam.fmt, 
     2243                                &media_port->info.fmt); 
     2244 
     2245            vport_param.vidparam.dir = PJMEDIA_DIR_RENDER; 
     2246            vport_param.active = PJ_TRUE; 
     2247 
     2248            /* Create video renderer */ 
     2249            status = pjmedia_vid_port_create(tmp_pool, &vport_param,  
     2250                                             &call_med->strm.v.renderer); 
     2251            if (status != PJ_SUCCESS) 
     2252                return status; 
     2253 
     2254            /* Connect the video renderer to media_port */ 
     2255            status = pjmedia_vid_port_connect(call_med->strm.v.renderer, 
     2256                                              media_port, PJ_FALSE); 
     2257            if (status != PJ_SUCCESS) 
     2258                return status; 
     2259 
     2260            /* Start the video renderer */ 
     2261            status = pjmedia_vid_port_start(call_med->strm.v.renderer); 
     2262            if (status != PJ_SUCCESS) 
     2263                return status; 
     2264        } 
     2265 
     2266        /* Setup encoding direction */ 
     2267        if (si->dir & PJMEDIA_DIR_ENCODING) { 
     2268            pjmedia_vid_port_param vport_param; 
     2269 
     2270            status = pjmedia_vid_stream_get_port(call_med->strm.v.stream, 
     2271                                                 PJMEDIA_DIR_ENCODING, 
     2272                                                 &media_port); 
     2273            if (status != PJ_SUCCESS) 
     2274                return status; 
     2275 
     2276            status = pjmedia_vid_dev_default_param( 
     2277                                tmp_pool, PJMEDIA_VID_DEFAULT_CAPTURE_DEV, 
     2278                                &vport_param.vidparam); 
     2279            if (status != PJ_SUCCESS) 
     2280                return status; 
     2281 
     2282            pjmedia_format_copy(&vport_param.vidparam.fmt, 
     2283                                &media_port->info.fmt); 
     2284 
     2285            vport_param.vidparam.dir = PJMEDIA_DIR_CAPTURE; 
     2286            vport_param.active = PJ_TRUE; 
     2287 
     2288            /* Create video capturer */ 
     2289            status = pjmedia_vid_port_create(tmp_pool, &vport_param,  
     2290                                             &call_med->strm.v.capturer); 
     2291            if (status != PJ_SUCCESS) 
     2292                return status; 
     2293 
     2294            /* Connect the video capturer to media_port */ 
     2295            status = pjmedia_vid_port_connect(call_med->strm.v.capturer, 
     2296                                              media_port, PJ_FALSE); 
     2297            if (status != PJ_SUCCESS) 
     2298                return status; 
     2299 
     2300            /* Start the video capturer */ 
     2301            status = pjmedia_vid_port_start(call_med->strm.v.capturer); 
     2302            if (status != PJ_SUCCESS) 
     2303                return status; 
     2304        } 
     2305 
     2306        /* Call media direction */ 
     2307        call_med->dir = si->dir; 
     2308 
     2309        /* Call media state */ 
     2310        if (call->local_hold) 
     2311            call_med->state = PJSUA_CALL_MEDIA_LOCAL_HOLD; 
     2312        else if (call_med->dir == PJMEDIA_DIR_DECODING) 
     2313            call_med->state = PJSUA_CALL_MEDIA_REMOTE_HOLD; 
     2314        else 
     2315            call_med->state = PJSUA_CALL_MEDIA_ACTIVE; 
     2316    } 
     2317 
     2318    /* Print info. */ 
     2319    { 
     2320        char info[80]; 
     2321        int info_len = 0; 
     2322        int len; 
     2323        const char *dir; 
     2324 
     2325        switch (si->dir) { 
     2326        case PJMEDIA_DIR_NONE: 
     2327            dir = "inactive"; 
     2328            break; 
     2329        case PJMEDIA_DIR_ENCODING: 
     2330            dir = "sendonly"; 
     2331            break; 
     2332        case PJMEDIA_DIR_DECODING: 
     2333            dir = "recvonly"; 
     2334            break; 
     2335        case PJMEDIA_DIR_ENCODING_DECODING: 
     2336            dir = "sendrecv"; 
     2337            break; 
     2338        default: 
     2339            dir = "unknown"; 
     2340            break; 
     2341        } 
     2342        len = pj_ansi_sprintf( info+info_len, 
     2343                               ", stream #%d: %.*s (%s)", strm_idx, 
     2344                               (int)si->codec_info.encoding_name.slen, 
     2345                               si->codec_info.encoding_name.ptr, 
     2346                               dir); 
     2347        if (len > 0) 
     2348            info_len += len; 
     2349        PJ_LOG(4,(THIS_FILE,"Media updates%s", info)); 
     2350    } 
     2351 
     2352    return PJ_SUCCESS; 
     2353} 
     2354 
     2355 
    21012356pj_status_t pjsua_media_channel_update(pjsua_call_id call_id, 
    21022357                                       const pjmedia_sdp_session *local_sdp, 
     
    21062361    pj_pool_t *tmp_pool = call->inv->pool_prov; 
    21072362    unsigned mi; 
    2108     pj_status_t status; 
     2363    pj_status_t status = PJ_SUCCESS; 
    21092364 
    21102365    if (pjsua_get_state() != PJSUA_STATE_RUNNING) 
     
    21352390                                          local_sdp, remote_sdp); 
    21362391            if (call->audio_idx==-1 && status==PJ_SUCCESS && 
    2137                     call_med->strm.a.stream) 
     2392                call_med->strm.a.stream) 
    21382393            { 
    21392394                call->audio_idx = mi; 
     
    21412396            break; 
    21422397        case PJMEDIA_TYPE_VIDEO: 
    2143             PJ_LOG(4,(THIS_FILE, "-x-x-x-x-  Updating video for stream %d", mi)); 
     2398            status = video_channel_update(call_med, tmp_pool, 
     2399                                          local_sdp, remote_sdp); 
    21442400            break; 
    21452401        default: 
Note: See TracChangeset for help on using the changeset viewer.