Ignore:
Timestamp:
Apr 29, 2008 5:15:41 PM (16 years ago)
Author:
nanang
Message:

More on ticket #513:

  • Added RTCP XR print reports to streamutil.c
  • Added new API pjmedia_stream_get_stat_xr()
  • Added field rtcp_xr_enabled to stream info structure
  • Swapped the wrong RTCP XR statistic storage (encoding direction should be stored in TX, decoding direction in RX, it was the opposite)
File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip-apps/src/samples/streamutil.c

    r1870 r1943  
    169169    info.ssrc = pj_rand(); 
    170170     
     171#if PJMEDIA_HAS_RTCP_XR && PJMEDIA_STREAM_ENABLE_XR 
     172    /* Set default RTCP XR enabled/disabled */ 
     173    info.rtcp_xr_enabled = PJ_TRUE; 
     174#endif 
    171175 
    172176    /* Copy remote address */ 
     
    695699} 
    696700 
     701 
     702#define SAMPLES_TO_USEC(usec, samples, clock_rate) \ 
     703    do { \ 
     704        if (samples <= 4294) \ 
     705            usec = samples * 1000000 / clock_rate; \ 
     706        else { \ 
     707            usec = samples * 1000 / clock_rate; \ 
     708            usec *= 1000; \ 
     709        } \ 
     710    } while(0) 
     711 
     712#define PRINT_VOIP_MTC_VAL(s, v) \ 
     713    if (v == 127) \ 
     714        sprintf(s, "(na)"); \ 
     715    else \ 
     716        sprintf(s, "%d", v) 
    697717 
    698718 
     
    828848           ); 
    829849 
     850#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0) 
     851    /* RTCP XR Reports */ 
     852    do { 
     853        char loss[16], dup[16]; 
     854        char jitter[80]; 
     855        char toh[80]; 
     856        char plc[16], jba[16], jbr[16]; 
     857        char signal_lvl[16], noise_lvl[16], rerl[16]; 
     858        char r_factor[16], ext_r_factor[16], mos_lq[16], mos_cq[16]; 
     859        pjmedia_rtcp_xr_stat xr_stat; 
     860 
     861        if (pjmedia_stream_get_stat_xr(stream, &xr_stat) != PJ_SUCCESS) 
     862            break; 
     863 
     864        puts("\nExtended reports:"); 
     865 
     866        /* Statistics Summary */ 
     867        puts(" Statistics Summary"); 
     868 
     869        if (xr_stat.rx.stat_sum.l) 
     870            sprintf(loss, "%d", xr_stat.rx.stat_sum.lost); 
     871        else 
     872            sprintf(loss, "(na)"); 
     873 
     874        if (xr_stat.rx.stat_sum.d) 
     875            sprintf(dup, "%d", xr_stat.rx.stat_sum.dup); 
     876        else 
     877            sprintf(dup, "(na)"); 
     878 
     879        if (xr_stat.rx.stat_sum.j) { 
     880            unsigned jmin, jmax, jmean, jdev; 
     881 
     882            SAMPLES_TO_USEC(jmin, xr_stat.rx.stat_sum.jitter.min,  
     883                            port->info.clock_rate); 
     884            SAMPLES_TO_USEC(jmax, xr_stat.rx.stat_sum.jitter.max,  
     885                            port->info.clock_rate); 
     886            SAMPLES_TO_USEC(jmean, xr_stat.rx.stat_sum.jitter.mean,  
     887                            port->info.clock_rate); 
     888            SAMPLES_TO_USEC(jdev, xr_stat.rx.stat_sum.jitter.dev,  
     889                            port->info.clock_rate); 
     890            sprintf(jitter, "%7.3f %7.3f %7.3f %7.3f",  
     891                    jmin/1000.0, jmean/1000.0, jmax/1000.0, jdev/1000.0); 
     892        } else 
     893            sprintf(jitter, "(report not available)"); 
     894 
     895        if (xr_stat.rx.stat_sum.t) { 
     896            sprintf(toh, "%11d %11d %11d %11d",  
     897                    xr_stat.rx.stat_sum.toh.min, 
     898                    xr_stat.rx.stat_sum.toh.mean, 
     899                    xr_stat.rx.stat_sum.toh.max, 
     900                    xr_stat.rx.stat_sum.toh.dev); 
     901        } else 
     902            sprintf(toh, "(report not available)"); 
     903 
     904        if (xr_stat.rx.stat_sum.update.sec == 0) 
     905            strcpy(last_update, "never"); 
     906        else { 
     907            pj_gettimeofday(&now); 
     908            PJ_TIME_VAL_SUB(now, xr_stat.rx.stat_sum.update); 
     909            sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago", 
     910                    now.sec / 3600, 
     911                    (now.sec % 3600) / 60, 
     912                    now.sec % 60, 
     913                    now.msec); 
     914        } 
     915 
     916        printf(" RX last update: %s\n" 
     917               "    begin seq=%d, end seq=%d%s\n" 
     918               "    pkt loss=%s, dup=%s%s\n" 
     919               "          (msec)    min     avg     max     dev\n" 
     920               "    jitter     : %s\n" 
     921               "    toh        : %s\n", 
     922               last_update, 
     923               xr_stat.rx.stat_sum.begin_seq, xr_stat.rx.stat_sum.end_seq, 
     924               "", 
     925               loss, dup, 
     926               "", 
     927               jitter, 
     928               toh 
     929               ); 
     930 
     931        if (xr_stat.tx.stat_sum.l) 
     932            sprintf(loss, "%d", xr_stat.tx.stat_sum.lost); 
     933        else 
     934            sprintf(loss, "(na)"); 
     935 
     936        if (xr_stat.tx.stat_sum.d) 
     937            sprintf(dup, "%d", xr_stat.tx.stat_sum.dup); 
     938        else 
     939            sprintf(dup, "(na)"); 
     940 
     941        if (xr_stat.tx.stat_sum.j) { 
     942            unsigned jmin, jmax, jmean, jdev; 
     943 
     944            SAMPLES_TO_USEC(jmin, xr_stat.tx.stat_sum.jitter.min,  
     945                            port->info.clock_rate); 
     946            SAMPLES_TO_USEC(jmax, xr_stat.tx.stat_sum.jitter.max,  
     947                            port->info.clock_rate); 
     948            SAMPLES_TO_USEC(jmean, xr_stat.tx.stat_sum.jitter.mean,  
     949                            port->info.clock_rate); 
     950            SAMPLES_TO_USEC(jdev, xr_stat.tx.stat_sum.jitter.dev,  
     951                            port->info.clock_rate); 
     952            sprintf(jitter, "%7.3f %7.3f %7.3f %7.3f",  
     953                    jmin/1000.0, jmean/1000.0, jmax/1000.0, jdev/1000.0); 
     954        } else 
     955            sprintf(jitter, "(report not available)"); 
     956 
     957        if (xr_stat.tx.stat_sum.t) { 
     958            sprintf(toh, "%11d %11d %11d %11d",  
     959                    xr_stat.tx.stat_sum.toh.min, 
     960                    xr_stat.tx.stat_sum.toh.mean, 
     961                    xr_stat.tx.stat_sum.toh.max, 
     962                    xr_stat.tx.stat_sum.toh.dev); 
     963        } else 
     964            sprintf(toh,    "(report not available)"); 
     965 
     966        if (xr_stat.tx.stat_sum.update.sec == 0) 
     967            strcpy(last_update, "never"); 
     968        else { 
     969            pj_gettimeofday(&now); 
     970            PJ_TIME_VAL_SUB(now, xr_stat.tx.stat_sum.update); 
     971            sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago", 
     972                    now.sec / 3600, 
     973                    (now.sec % 3600) / 60, 
     974                    now.sec % 60, 
     975                    now.msec); 
     976        } 
     977 
     978        printf(" TX last update: %s\n" 
     979               "    begin seq=%d, end seq=%d%s\n" 
     980               "    pkt loss=%s, dup=%s%s\n" 
     981               "          (msec)    min     avg     max     dev\n" 
     982               "    jitter     : %s\n" 
     983               "    toh        : %s\n", 
     984               last_update, 
     985               xr_stat.tx.stat_sum.begin_seq, xr_stat.tx.stat_sum.end_seq, 
     986               "", 
     987               loss, dup, 
     988               "", 
     989               jitter, 
     990               toh 
     991               ); 
     992 
     993        /* VoIP Metrics */ 
     994        puts(" VoIP Metrics"); 
     995 
     996        PRINT_VOIP_MTC_VAL(signal_lvl, xr_stat.rx.voip_mtc.signal_lvl); 
     997        PRINT_VOIP_MTC_VAL(noise_lvl, xr_stat.rx.voip_mtc.noise_lvl); 
     998        PRINT_VOIP_MTC_VAL(rerl, xr_stat.rx.voip_mtc.rerl); 
     999        PRINT_VOIP_MTC_VAL(r_factor, xr_stat.rx.voip_mtc.r_factor); 
     1000        PRINT_VOIP_MTC_VAL(ext_r_factor, xr_stat.rx.voip_mtc.ext_r_factor); 
     1001        PRINT_VOIP_MTC_VAL(mos_lq, xr_stat.rx.voip_mtc.mos_lq); 
     1002        PRINT_VOIP_MTC_VAL(mos_cq, xr_stat.rx.voip_mtc.mos_cq); 
     1003 
     1004        switch ((xr_stat.rx.voip_mtc.rx_config>>6) & 3) { 
     1005            case PJMEDIA_RTCP_XR_PLC_DIS: 
     1006                sprintf(plc, "DISABLED"); 
     1007                break; 
     1008            case PJMEDIA_RTCP_XR_PLC_ENH: 
     1009                sprintf(plc, "ENHANCED"); 
     1010                break; 
     1011            case PJMEDIA_RTCP_XR_PLC_STD: 
     1012                sprintf(plc, "STANDARD"); 
     1013                break; 
     1014            case PJMEDIA_RTCP_XR_PLC_UNK: 
     1015            default: 
     1016                sprintf(plc, "UNKNOWN"); 
     1017                break; 
     1018        } 
     1019 
     1020        switch ((xr_stat.rx.voip_mtc.rx_config>>4) & 3) { 
     1021            case PJMEDIA_RTCP_XR_JB_FIXED: 
     1022                sprintf(jba, "FIXED"); 
     1023                break; 
     1024            case PJMEDIA_RTCP_XR_JB_ADAPTIVE: 
     1025                sprintf(jba, "ADAPTIVE"); 
     1026                break; 
     1027            default: 
     1028                sprintf(jba, "UNKNOWN"); 
     1029                break; 
     1030        } 
     1031 
     1032        sprintf(jbr, "%d", xr_stat.rx.voip_mtc.rx_config & 0x0F); 
     1033 
     1034        if (xr_stat.rx.voip_mtc.update.sec == 0) 
     1035            strcpy(last_update, "never"); 
     1036        else { 
     1037            pj_gettimeofday(&now); 
     1038            PJ_TIME_VAL_SUB(now, xr_stat.rx.voip_mtc.update); 
     1039            sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago", 
     1040                    now.sec / 3600, 
     1041                    (now.sec % 3600) / 60, 
     1042                    now.sec % 60, 
     1043                    now.msec); 
     1044        } 
     1045 
     1046        printf(" RX last update: %s\n" 
     1047               "    packets    : loss rate=%d (%.2f%%), discard rate=%d (%.2f%%)\n" 
     1048               "    burst      : density=%d (%.2f%%), duration=%d%s\n" 
     1049               "    gap        : density=%d (%.2f%%), duration=%d%s\n" 
     1050               "    delay      : round trip=%d%s, end system=%d%s\n" 
     1051               "    level      : signal=%s%s, noise=%s%s, RERL=%s%s\n" 
     1052               "    quality    : R factor=%s, ext R factor=%s\n" 
     1053               "                 MOS LQ=%s, MOS CQ=%s\n" 
     1054               "    config     : PLC=%s, JB=%s, JB rate=%s, Gmin=%d\n" 
     1055               "    JB delay   : cur=%d%s, max=%d%s, abs max=%d%s\n", 
     1056               last_update, 
     1057               /* pakcets */ 
     1058               xr_stat.rx.voip_mtc.loss_rate, xr_stat.rx.voip_mtc.loss_rate*100.0/256, 
     1059               xr_stat.rx.voip_mtc.discard_rate, xr_stat.rx.voip_mtc.discard_rate*100.0/256, 
     1060               /* burst */ 
     1061               xr_stat.rx.voip_mtc.burst_den, xr_stat.rx.voip_mtc.burst_den*100.0/256, 
     1062               xr_stat.rx.voip_mtc.burst_dur, "ms", 
     1063               /* gap */ 
     1064               xr_stat.rx.voip_mtc.gap_den, xr_stat.rx.voip_mtc.gap_den*100.0/256, 
     1065               xr_stat.rx.voip_mtc.gap_dur, "ms", 
     1066               /* delay */ 
     1067               xr_stat.rx.voip_mtc.rnd_trip_delay, "ms", 
     1068               xr_stat.rx.voip_mtc.end_sys_delay, "ms", 
     1069               /* level */ 
     1070               signal_lvl, "dB", 
     1071               noise_lvl, "dB", 
     1072               rerl, "", 
     1073               /* quality */ 
     1074               r_factor, ext_r_factor, mos_lq, mos_cq, 
     1075               /* config */ 
     1076               plc, jba, jbr, xr_stat.rx.voip_mtc.gmin, 
     1077               /* JB delay */ 
     1078               xr_stat.rx.voip_mtc.jb_nom, "ms", 
     1079               xr_stat.rx.voip_mtc.jb_max, "ms", 
     1080               xr_stat.rx.voip_mtc.jb_abs_max, "ms" 
     1081               ); 
     1082 
     1083        PRINT_VOIP_MTC_VAL(signal_lvl, xr_stat.tx.voip_mtc.signal_lvl); 
     1084        PRINT_VOIP_MTC_VAL(noise_lvl, xr_stat.tx.voip_mtc.noise_lvl); 
     1085        PRINT_VOIP_MTC_VAL(rerl, xr_stat.tx.voip_mtc.rerl); 
     1086        PRINT_VOIP_MTC_VAL(r_factor, xr_stat.tx.voip_mtc.r_factor); 
     1087        PRINT_VOIP_MTC_VAL(ext_r_factor, xr_stat.tx.voip_mtc.ext_r_factor); 
     1088        PRINT_VOIP_MTC_VAL(mos_lq, xr_stat.tx.voip_mtc.mos_lq); 
     1089        PRINT_VOIP_MTC_VAL(mos_cq, xr_stat.tx.voip_mtc.mos_cq); 
     1090 
     1091        switch ((xr_stat.tx.voip_mtc.rx_config>>6) & 3) { 
     1092            case PJMEDIA_RTCP_XR_PLC_DIS: 
     1093                sprintf(plc, "DISABLED"); 
     1094                break; 
     1095            case PJMEDIA_RTCP_XR_PLC_ENH: 
     1096                sprintf(plc, "ENHANCED"); 
     1097                break; 
     1098            case PJMEDIA_RTCP_XR_PLC_STD: 
     1099                sprintf(plc, "STANDARD"); 
     1100                break; 
     1101            case PJMEDIA_RTCP_XR_PLC_UNK: 
     1102            default: 
     1103                sprintf(plc, "unknown"); 
     1104                break; 
     1105        } 
     1106 
     1107        switch ((xr_stat.tx.voip_mtc.rx_config>>4) & 3) { 
     1108            case PJMEDIA_RTCP_XR_JB_FIXED: 
     1109                sprintf(jba, "FIXED"); 
     1110                break; 
     1111            case PJMEDIA_RTCP_XR_JB_ADAPTIVE: 
     1112                sprintf(jba, "ADAPTIVE"); 
     1113                break; 
     1114            default: 
     1115                sprintf(jba, "unknown"); 
     1116                break; 
     1117        } 
     1118 
     1119        sprintf(jbr, "%d", xr_stat.tx.voip_mtc.rx_config & 0x0F); 
     1120 
     1121        if (xr_stat.tx.voip_mtc.update.sec == 0) 
     1122            strcpy(last_update, "never"); 
     1123        else { 
     1124            pj_gettimeofday(&now); 
     1125            PJ_TIME_VAL_SUB(now, xr_stat.tx.voip_mtc.update); 
     1126            sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago", 
     1127                    now.sec / 3600, 
     1128                    (now.sec % 3600) / 60, 
     1129                    now.sec % 60, 
     1130                    now.msec); 
     1131        } 
     1132 
     1133        printf(" TX last update: %s\n" 
     1134               "    packets    : loss rate=%d (%.2f%%), discard rate=%d (%.2f%%)\n" 
     1135               "    burst      : density=%d (%.2f%%), duration=%d%s\n" 
     1136               "    gap        : density=%d (%.2f%%), duration=%d%s\n" 
     1137               "    delay      : round trip=%d%s, end system=%d%s\n" 
     1138               "    level      : signal=%s%s, noise=%s%s, RERL=%s%s\n" 
     1139               "    quality    : R factor=%s, ext R factor=%s\n" 
     1140               "                 MOS LQ=%s, MOS CQ=%s\n" 
     1141               "    config     : PLC=%s, JB=%s, JB rate=%s, Gmin=%d\n" 
     1142               "    JB delay   : cur=%d%s, max=%d%s, abs max=%d%s\n", 
     1143               last_update, 
     1144               /* pakcets */ 
     1145               xr_stat.tx.voip_mtc.loss_rate, xr_stat.tx.voip_mtc.loss_rate*100.0/256, 
     1146               xr_stat.tx.voip_mtc.discard_rate, xr_stat.tx.voip_mtc.discard_rate*100.0/256, 
     1147               /* burst */ 
     1148               xr_stat.tx.voip_mtc.burst_den, xr_stat.tx.voip_mtc.burst_den*100.0/256, 
     1149               xr_stat.tx.voip_mtc.burst_dur, "ms", 
     1150               /* gap */ 
     1151               xr_stat.tx.voip_mtc.gap_den, xr_stat.tx.voip_mtc.gap_den*100.0/256, 
     1152               xr_stat.tx.voip_mtc.gap_dur, "ms", 
     1153               /* delay */ 
     1154               xr_stat.tx.voip_mtc.rnd_trip_delay, "ms", 
     1155               xr_stat.tx.voip_mtc.end_sys_delay, "ms", 
     1156               /* level */ 
     1157               signal_lvl, "dB", 
     1158               noise_lvl, "dB", 
     1159               rerl, "", 
     1160               /* quality */ 
     1161               r_factor, ext_r_factor, mos_lq, mos_cq, 
     1162               /* config */ 
     1163               plc, jba, jbr, xr_stat.tx.voip_mtc.gmin, 
     1164               /* JB delay */ 
     1165               xr_stat.tx.voip_mtc.jb_nom, "ms", 
     1166               xr_stat.tx.voip_mtc.jb_max, "ms", 
     1167               xr_stat.tx.voip_mtc.jb_abs_max, "ms" 
     1168               ); 
     1169 
     1170 
     1171        /* RTT delay, need this? */ 
     1172        printf("          (msec)    min     avg     max     last\n"); 
     1173        printf(" RTT delay     : %7.3f %7.3f %7.3f %7.3f%s\n",  
     1174               xr_stat.rtt.min / 1000.0, 
     1175               xr_stat.rtt.avg / 1000.0, 
     1176               xr_stat.rtt.max / 1000.0, 
     1177               xr_stat.rtt.last / 1000.0, 
     1178               "" 
     1179               ); 
     1180    } while (0); 
     1181#endif /* PJMEDIA_HAS_RTCP_XR */ 
     1182 
    8301183} 
    8311184 
Note: See TracChangeset for help on using the changeset viewer.