Ticket #513: xr.2.patch
File xr.2.patch, 39.4 KB (added by nanang, 17 years ago) |
---|
-
pjsip-apps/src/samples/streamutil.c
168 168 info.tx_pt = codec_info->pt; 169 169 info.ssrc = pj_rand(); 170 170 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 171 175 172 176 /* Copy remote address */ 173 177 pj_memcpy(&info.rem_addr, rem_addr, sizeof(pj_sockaddr_in)); … … 695 699 } 696 700 697 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) 698 711 712 #define PRINT_VOIP_MTC_VAL(s, v) \ 713 if (v == 127) \ 714 sprintf(s, "(na)"); \ 715 else \ 716 sprintf(s, "%d", v) 717 718 699 719 /* 700 720 * Print stream statistics 701 721 */ … … 827 847 "" 828 848 ); 829 849 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 830 1183 } 831 1184 -
pjmedia/include/pjmedia/rtcp_xr.h
229 229 typedef struct pjmedia_rtcp_xr_stream_stat 230 230 { 231 231 struct { 232 pj_uint32_t begin_seq; 233 pj_uint32_t end_seq; 232 pj_time_val update; /**< Time of last update. */ 233 234 pj_uint32_t begin_seq; /**< Begin # seq of this interval. */ 235 pj_uint32_t end_seq; /**< End # seq of this interval. */ 234 236 unsigned count; /**< Number of packets. */ 235 237 236 238 /** … … 263 265 } stat_sum; 264 266 265 267 struct { 268 pj_time_val update; /**< Time of last update. */ 269 266 270 pj_uint8_t loss_rate; /**< Packet loss rate */ 267 271 pj_uint8_t discard_rate; /**< Packet discarded rate */ 268 272 pj_uint8_t burst_den; /**< Burst density */ … … 271 275 pj_uint16_t gap_dur; /**< Gap duration */ 272 276 pj_uint16_t rnd_trip_delay; /**< Round trip delay */ 273 277 pj_uint16_t end_sys_delay; /**< End system delay */ 274 pj_ uint8_t signal_lvl; /**< Signal level */275 pj_ uint8_t noise_lvl; /**< Noise level */278 pj_int8_t signal_lvl; /**< Signal level */ 279 pj_int8_t noise_lvl; /**< Noise level */ 276 280 pj_uint8_t rerl; /**< Residual Echo Return Loss */ 277 281 pj_uint8_t gmin; /**< The gap threshold */ 278 282 pj_uint8_t r_factor; /**< Voice quality metric carried -
pjmedia/include/pjmedia/stream.h
95 95 pj_sockaddr rem_rtcp; /**< Optional remote RTCP address. If 96 96 sin_family is zero, the RTP address 97 97 will be calculated from RTP. */ 98 #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0) 99 pj_bool_t rtcp_xr_enabled; 100 /**< Specify whether RTCP XR is enabled.*/ 101 #endif 98 102 pjmedia_codec_info fmt; /**< Incoming codec format info. */ 99 103 pjmedia_codec_param *param; /**< Optional codec param. */ 100 104 unsigned tx_pt; /**< Outgoing codec paylaod type. */ … … 206 210 PJ_DECL(pj_status_t) pjmedia_stream_get_stat( const pjmedia_stream *stream, 207 211 pjmedia_rtcp_stat *stat); 208 212 213 #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0) 209 214 /** 215 * Get the stream extended report statistics (RTCP XR). 216 * 217 * @param stream The media stream. 218 * @param stat Media stream extended report statistics. 219 * 220 * @return PJ_SUCCESS on success. 221 */ 222 PJ_DECL(pj_status_t) pjmedia_stream_get_stat_xr( const pjmedia_stream *stream, 223 pjmedia_rtcp_xr_stat *stat); 224 #endif 225 226 /** 210 227 * Pause the individual channel in the stream. 211 228 * 212 229 * @param stream The media channel. -
pjmedia/src/pjmedia/rtcp_xr.c
86 86 { 87 87 pj_bzero(session, sizeof(pjmedia_rtcp_xr_session)); 88 88 89 session->name = parent_session->name; 89 90 session->rtcp_session = parent_session; 90 91 pj_memcpy(&session->pkt.common, &session->rtcp_session->rtcp_sr_pkt.common, 91 92 sizeof(pjmedia_rtcp_common)); 92 93 session->pkt.common.pt = RTCP_XR; 93 94 94 95 /* Init config */ 95 session->stat. tx.voip_mtc.gmin = (pj_uint8_t)(gmin? gmin : DEFAULT_GMIN);96 session->stat.rx.voip_mtc.gmin = (pj_uint8_t)(gmin? gmin : DEFAULT_GMIN); 96 97 session->ptime = session->rtcp_session->pkt_size * 1000 / 97 98 session->rtcp_session->clock_rate; 98 99 session->frames_per_packet = frames_per_packet; 99 100 100 101 /* Init Statistics Summary fields which have non-zero default */ 101 session->stat. tx.stat_sum.jitter.min = (unsigned) -1;102 session->stat. tx.stat_sum.toh.min = (unsigned) -1;102 session->stat.rx.stat_sum.jitter.min = (unsigned) -1; 103 session->stat.rx.stat_sum.toh.min = (unsigned) -1; 103 104 104 105 /* Init VoIP Metrics fields which have non-zero default */ 106 session->stat.rx.voip_mtc.signal_lvl = 127; 107 session->stat.rx.voip_mtc.noise_lvl = 127; 108 session->stat.rx.voip_mtc.rerl = 127; 109 session->stat.rx.voip_mtc.r_factor = 127; 110 session->stat.rx.voip_mtc.ext_r_factor = 127; 111 session->stat.rx.voip_mtc.mos_lq = 127; 112 session->stat.rx.voip_mtc.mos_cq = 127; 113 105 114 session->stat.tx.voip_mtc.signal_lvl = 127; 106 115 session->stat.tx.voip_mtc.noise_lvl = 127; 107 116 session->stat.tx.voip_mtc.rerl = 127; … … 189 198 /* Statistics Summary Block */ 190 199 /* Build this block if we have received packets since last build */ 191 200 if ((rpt_types == 0 || (rpt_types & PJMEDIA_RTCP_XR_STATS)) && 192 sess->stat. tx.stat_sum.count > 0)201 sess->stat.rx.stat_sum.count > 0) 193 202 { 194 203 pjmedia_rtcp_xr_rb_stats *r; 195 204 pj_uint8_t specific = 0; … … 198 207 pj_bzero(r, sizeof(pjmedia_rtcp_xr_rb_stats)); 199 208 200 209 /* Init block header */ 201 specific |= sess->stat. tx.stat_sum.l ? (1 << 7) : 0;202 specific |= sess->stat. tx.stat_sum.d ? (1 << 6) : 0;203 specific |= sess->stat. tx.stat_sum.j ? (1 << 5) : 0;204 specific |= (sess->stat. tx.stat_sum.t & 3) << 3;210 specific |= sess->stat.rx.stat_sum.l ? (1 << 7) : 0; 211 specific |= sess->stat.rx.stat_sum.d ? (1 << 6) : 0; 212 specific |= sess->stat.rx.stat_sum.j ? (1 << 5) : 0; 213 specific |= (sess->stat.rx.stat_sum.t & 3) << 3; 205 214 r->header.bt = BT_STATS; 206 215 r->header.specific = specific; 207 216 r->header.length = pj_htons(9); … … 209 218 /* Generate block contents */ 210 219 r->ssrc = pj_htonl(sess->rtcp_session->peer_ssrc); 211 220 r->begin_seq = pj_htons((pj_uint16_t) 212 (sess->stat. tx.stat_sum.begin_seq & 0xFFFF));221 (sess->stat.rx.stat_sum.begin_seq & 0xFFFF)); 213 222 r->end_seq = pj_htons((pj_uint16_t) 214 (sess->stat. tx.stat_sum.end_seq & 0xFFFF));215 if (sess->stat. tx.stat_sum.l) {216 r->lost = pj_htonl(sess->stat. tx.stat_sum.lost);223 (sess->stat.rx.stat_sum.end_seq & 0xFFFF)); 224 if (sess->stat.rx.stat_sum.l) { 225 r->lost = pj_htonl(sess->stat.rx.stat_sum.lost); 217 226 } 218 if (sess->stat. tx.stat_sum.d) {219 r->dup = pj_htonl(sess->stat. tx.stat_sum.dup);227 if (sess->stat.rx.stat_sum.d) { 228 r->dup = pj_htonl(sess->stat.rx.stat_sum.dup); 220 229 } 221 if (sess->stat. tx.stat_sum.j) {222 r->jitter_min = pj_htonl(sess->stat. tx.stat_sum.jitter.min);223 r->jitter_max = pj_htonl(sess->stat. tx.stat_sum.jitter.max);224 r->jitter_mean = pj_htonl(sess->stat. tx.stat_sum.jitter.mean);225 sess->stat. tx.stat_sum.jitter.dev =226 my_isqrt(sess->stat. tx.stat_sum.jitter.dev);227 r->jitter_dev = pj_htonl(sess->stat. tx.stat_sum.jitter.dev);230 if (sess->stat.rx.stat_sum.j) { 231 r->jitter_min = pj_htonl(sess->stat.rx.stat_sum.jitter.min); 232 r->jitter_max = pj_htonl(sess->stat.rx.stat_sum.jitter.max); 233 r->jitter_mean = pj_htonl(sess->stat.rx.stat_sum.jitter.mean); 234 sess->stat.rx.stat_sum.jitter.dev = 235 my_isqrt(sess->stat.rx.stat_sum.jitter.dev); 236 r->jitter_dev = pj_htonl(sess->stat.rx.stat_sum.jitter.dev); 228 237 } 229 if (sess->stat. tx.stat_sum.t) {230 r->toh_min = sess->stat. tx.stat_sum.toh.min;231 r->toh_max = sess->stat. tx.stat_sum.toh.max;232 r->toh_mean = sess->stat. tx.stat_sum.toh.mean;233 sess->stat. tx.stat_sum.toh.dev =234 my_isqrt(sess->stat. tx.stat_sum.toh.dev);235 r->toh_dev = sess->stat. tx.stat_sum.toh.dev;238 if (sess->stat.rx.stat_sum.t) { 239 r->toh_min = sess->stat.rx.stat_sum.toh.min; 240 r->toh_max = sess->stat.rx.stat_sum.toh.max; 241 r->toh_mean = sess->stat.rx.stat_sum.toh.mean; 242 sess->stat.rx.stat_sum.toh.dev = 243 my_isqrt(sess->stat.rx.stat_sum.toh.dev); 244 r->toh_dev = sess->stat.rx.stat_sum.toh.dev; 236 245 } 237 246 238 247 /* Reset TX statistics summary each time built */ 239 pj_bzero(&sess->stat. tx.stat_sum, sizeof(sess->stat.tx.stat_sum));240 sess->stat. tx.stat_sum.jitter.min = (unsigned) -1;241 sess->stat. tx.stat_sum.toh.min = (unsigned) -1;248 pj_bzero(&sess->stat.rx.stat_sum, sizeof(sess->stat.rx.stat_sum)); 249 sess->stat.rx.stat_sum.jitter.min = (unsigned) -1; 250 sess->stat.rx.stat_sum.toh.min = (unsigned) -1; 242 251 243 252 /* Finally */ 244 253 size += sizeof(pjmedia_rtcp_xr_rb_stats); 254 pj_gettimeofday(&sess->stat.rx.stat_sum.update); 245 255 } 246 256 247 257 /* Voip Metrics Block */ … … 288 298 } else { 289 299 p23 = 1 - c22/(c22 + c23); 290 300 } 291 sess->stat. tx.voip_mtc.burst_den = (pj_uint8_t)(256*p23/(p23 + p32));292 sess->stat. tx.voip_mtc.gap_den = (pj_uint8_t)(256*c14/(c11 + c14));301 sess->stat.rx.voip_mtc.burst_den = (pj_uint8_t)(256*p23/(p23 + p32)); 302 sess->stat.rx.voip_mtc.gap_den = (pj_uint8_t)(256*c14/(c11 + c14)); 293 303 294 304 /* Calculate burst and gap durations in ms */ 295 sess->stat. tx.voip_mtc.gap_dur = (pj_uint16_t)((c11+c14+c13)*m/c13);296 sess->stat. tx.voip_mtc.burst_dur = (pj_uint16_t)(ctotal*m/c13 -297 sess->stat. tx.voip_mtc.gap_dur);305 sess->stat.rx.voip_mtc.gap_dur = (pj_uint16_t)((c11+c14+c13)*m/c13); 306 sess->stat.rx.voip_mtc.burst_dur = (pj_uint16_t)(ctotal*m/c13 - 307 sess->stat.rx.voip_mtc.gap_dur); 298 308 } else { 299 309 /* No burst occurred yet until this time? 300 310 * Just report full gap. 301 311 */ 302 ctotal = sess->rtcp_session->stat.rx.pkt; 312 ctotal = sess->rtcp_session->stat.rx.pkt + 313 sess->voip_mtc_stat.loss_count + 314 sess->voip_mtc_stat.discard_count; 303 315 304 sess->stat. tx.voip_mtc.burst_den = 0;305 sess->stat. tx.voip_mtc.gap_den = (pj_uint8_t)(256 *316 sess->stat.rx.voip_mtc.burst_den = 0; 317 sess->stat.rx.voip_mtc.gap_den = (pj_uint8_t)(256 * 306 318 (sess->voip_mtc_stat.loss_count + 307 319 sess->voip_mtc_stat.discard_count) / 308 320 ctotal); 309 321 310 322 /* Calculate burst and gap durations in ms */ 311 sess->stat. tx.voip_mtc.gap_dur = (pj_uint16_t)((m*ctotal) < 0xFFFF?323 sess->stat.rx.voip_mtc.gap_dur = (pj_uint16_t)((m*ctotal) < 0xFFFF? 312 324 (m*ctotal) : 0xFFFF); 313 sess->stat. tx.voip_mtc.burst_dur = 0;325 sess->stat.rx.voip_mtc.burst_dur = 0; 314 326 } 315 327 316 328 /* Calculate loss and discard rates */ 317 sess->stat. tx.voip_mtc.loss_rate = (pj_uint8_t)329 sess->stat.rx.voip_mtc.loss_rate = (pj_uint8_t) 318 330 (256 * sess->voip_mtc_stat.loss_count / ctotal); 319 sess->stat. tx.voip_mtc.discard_rate = (pj_uint8_t)331 sess->stat.rx.voip_mtc.discard_rate = (pj_uint8_t) 320 332 (256 * sess->voip_mtc_stat.discard_count / ctotal); 321 333 322 334 /* Set round trip delay (in ms) to RTT calculated after receiving 323 335 * DLRR or DLSR. 324 336 */ 325 337 if (sess->stat.rtt.last) 326 sess->stat. tx.voip_mtc.rnd_trip_delay = (pj_uint16_t)338 sess->stat.rx.voip_mtc.rnd_trip_delay = (pj_uint16_t) 327 339 (sess->stat.rtt.last / 1000); 328 340 else if (sess->rtcp_session->stat.rtt.last) 329 sess->stat. tx.voip_mtc.rnd_trip_delay = (pj_uint16_t)341 sess->stat.rx.voip_mtc.rnd_trip_delay = (pj_uint16_t) 330 342 (sess->rtcp_session->stat.rtt.last / 1000); 331 343 332 344 /* End system delay estimation = RTT/2 + current jitter buffer size + … … 336 348 * Since it is difficult to get the exact value of EXTRA, estimation 337 349 * is taken to be totally around 50 ms. 338 350 */ 339 sess->stat. tx.voip_mtc.end_sys_delay = (pj_uint16_t)340 (sess->stat. tx.voip_mtc.rnd_trip_delay / 2 +341 sess->stat. tx.voip_mtc.jb_nom + 50);351 sess->stat.rx.voip_mtc.end_sys_delay = (pj_uint16_t) 352 (sess->stat.rx.voip_mtc.rnd_trip_delay / 2 + 353 sess->stat.rx.voip_mtc.jb_nom + 50); 342 354 343 355 /* Generate block contents */ 344 356 r->ssrc = pj_htonl(sess->rtcp_session->peer_ssrc); 345 r->loss_rate = sess->stat.tx.voip_mtc.loss_rate; 346 r->discard_rate = sess->stat.tx.voip_mtc.discard_rate; 347 r->burst_den = sess->stat.tx.voip_mtc.burst_den; 348 r->gap_den = sess->stat.tx.voip_mtc.gap_den; 349 r->burst_dur = pj_htons(sess->stat.tx.voip_mtc.burst_dur); 350 r->gap_dur = pj_htons(sess->stat.tx.voip_mtc.gap_dur); 351 r->rnd_trip_delay = pj_htons(sess->stat.tx.voip_mtc.rnd_trip_delay); 352 r->end_sys_delay = pj_htons(sess->stat.tx.voip_mtc.end_sys_delay); 353 r->signal_lvl = sess->stat.tx.voip_mtc.signal_lvl; 354 r->noise_lvl = sess->stat.tx.voip_mtc.noise_lvl; 355 r->rerl = sess->stat.tx.voip_mtc.rerl; 356 r->gmin = sess->stat.tx.voip_mtc.gmin; 357 r->r_factor = sess->stat.tx.voip_mtc.r_factor; 358 r->ext_r_factor = sess->stat.tx.voip_mtc.ext_r_factor; 359 r->mos_lq = sess->stat.tx.voip_mtc.mos_lq; 360 r->mos_cq = sess->stat.tx.voip_mtc.mos_cq; 361 r->rx_config = sess->stat.tx.voip_mtc.rx_config; 362 r->jb_nom = pj_htons(sess->stat.tx.voip_mtc.jb_nom); 363 r->jb_max = pj_htons(sess->stat.tx.voip_mtc.jb_max); 364 r->jb_abs_max = pj_htons(sess->stat.tx.voip_mtc.jb_abs_max); 357 r->loss_rate = sess->stat.rx.voip_mtc.loss_rate; 358 r->discard_rate = sess->stat.rx.voip_mtc.discard_rate; 359 r->burst_den = sess->stat.rx.voip_mtc.burst_den; 360 r->gap_den = sess->stat.rx.voip_mtc.gap_den; 361 r->burst_dur = pj_htons(sess->stat.rx.voip_mtc.burst_dur); 362 r->gap_dur = pj_htons(sess->stat.rx.voip_mtc.gap_dur); 363 r->rnd_trip_delay = pj_htons(sess->stat.rx.voip_mtc.rnd_trip_delay); 364 r->end_sys_delay = pj_htons(sess->stat.rx.voip_mtc.end_sys_delay); 365 /* signal & noise level encoded in two's complement form */ 366 r->signal_lvl = (sess->stat.rx.voip_mtc.signal_lvl >= 0)? 367 sess->stat.rx.voip_mtc.signal_lvl : 368 (sess->stat.rx.voip_mtc.signal_lvl + 256); 369 r->noise_lvl = (sess->stat.rx.voip_mtc.noise_lvl >= 0)? 370 sess->stat.rx.voip_mtc.noise_lvl : 371 (sess->stat.rx.voip_mtc.noise_lvl + 256); 372 r->rerl = sess->stat.rx.voip_mtc.rerl; 373 r->gmin = sess->stat.rx.voip_mtc.gmin; 374 r->r_factor = sess->stat.rx.voip_mtc.r_factor; 375 r->ext_r_factor = sess->stat.rx.voip_mtc.ext_r_factor; 376 r->mos_lq = sess->stat.rx.voip_mtc.mos_lq; 377 r->mos_cq = sess->stat.rx.voip_mtc.mos_cq; 378 r->rx_config = sess->stat.rx.voip_mtc.rx_config; 379 r->jb_nom = pj_htons(sess->stat.rx.voip_mtc.jb_nom); 380 r->jb_max = pj_htons(sess->stat.rx.voip_mtc.jb_max); 381 r->jb_abs_max = pj_htons(sess->stat.rx.voip_mtc.jb_abs_max); 365 382 366 383 /* Finally */ 367 384 size += sizeof(pjmedia_rtcp_xr_rb_voip_mtc); 385 pj_gettimeofday(&sess->stat.rx.voip_mtc.update); 368 386 } 369 387 370 388 /* Add RTCP XR header size */ … … 532 550 if (rb_stats) { 533 551 pj_uint8_t flags = rb_stats->header.specific; 534 552 535 pj_bzero(&sess->stat. rx.stat_sum, sizeof(sess->stat.rx.stat_sum));553 pj_bzero(&sess->stat.tx.stat_sum, sizeof(sess->stat.tx.stat_sum)); 536 554 537 555 /* Range of packets sequence reported in this blocks */ 538 sess->stat. rx.stat_sum.begin_seq = pj_ntohs(rb_stats->begin_seq);539 sess->stat. rx.stat_sum.end_seq = pj_ntohs(rb_stats->end_seq);556 sess->stat.tx.stat_sum.begin_seq = pj_ntohs(rb_stats->begin_seq); 557 sess->stat.tx.stat_sum.end_seq = pj_ntohs(rb_stats->end_seq); 540 558 541 559 /* Get flags of valid fields */ 542 sess->stat. rx.stat_sum.l = (flags & (1 << 7)) != 0;543 sess->stat. rx.stat_sum.d = (flags & (1 << 6)) != 0;544 sess->stat. rx.stat_sum.j = (flags & (1 << 5)) != 0;545 sess->stat. rx.stat_sum.t = (flags & (3 << 3)) != 0;560 sess->stat.tx.stat_sum.l = (flags & (1 << 7)) != 0; 561 sess->stat.tx.stat_sum.d = (flags & (1 << 6)) != 0; 562 sess->stat.tx.stat_sum.j = (flags & (1 << 5)) != 0; 563 sess->stat.tx.stat_sum.t = (flags & (3 << 3)) != 0; 546 564 547 565 /* Fetch the reports info */ 548 if (sess->stat. rx.stat_sum.l) {549 sess->stat. rx.stat_sum.lost = pj_ntohl(rb_stats->lost);566 if (sess->stat.tx.stat_sum.l) { 567 sess->stat.tx.stat_sum.lost = pj_ntohl(rb_stats->lost); 550 568 } 551 569 552 if (sess->stat. rx.stat_sum.d) {553 sess->stat. rx.stat_sum.dup = pj_ntohl(rb_stats->dup);570 if (sess->stat.tx.stat_sum.d) { 571 sess->stat.tx.stat_sum.dup = pj_ntohl(rb_stats->dup); 554 572 } 555 573 556 if (sess->stat. rx.stat_sum.j) {557 sess->stat. rx.stat_sum.jitter.min = pj_ntohl(rb_stats->jitter_min);558 sess->stat. rx.stat_sum.jitter.max = pj_ntohl(rb_stats->jitter_max);559 sess->stat. rx.stat_sum.jitter.mean = pj_ntohl(rb_stats->jitter_mean);560 sess->stat. rx.stat_sum.jitter.dev = pj_ntohl(rb_stats->jitter_dev);574 if (sess->stat.tx.stat_sum.j) { 575 sess->stat.tx.stat_sum.jitter.min = pj_ntohl(rb_stats->jitter_min); 576 sess->stat.tx.stat_sum.jitter.max = pj_ntohl(rb_stats->jitter_max); 577 sess->stat.tx.stat_sum.jitter.mean = pj_ntohl(rb_stats->jitter_mean); 578 sess->stat.tx.stat_sum.jitter.dev = pj_ntohl(rb_stats->jitter_dev); 561 579 } 562 580 563 if (sess->stat. rx.stat_sum.t) {564 sess->stat. rx.stat_sum.toh.min = rb_stats->toh_min;565 sess->stat. rx.stat_sum.toh.max = rb_stats->toh_max;566 sess->stat. rx.stat_sum.toh.mean = rb_stats->toh_mean;567 sess->stat. rx.stat_sum.toh.dev = rb_stats->toh_dev;581 if (sess->stat.tx.stat_sum.t) { 582 sess->stat.tx.stat_sum.toh.min = rb_stats->toh_min; 583 sess->stat.tx.stat_sum.toh.max = rb_stats->toh_max; 584 sess->stat.tx.stat_sum.toh.mean = rb_stats->toh_mean; 585 sess->stat.tx.stat_sum.toh.dev = rb_stats->toh_dev; 568 586 } 587 588 pj_gettimeofday(&sess->stat.tx.stat_sum.update); 569 589 } 570 590 571 591 /* Receiving VoIP Metrics */ 572 592 if (rb_voip_mtc) { 573 sess->stat. rx.voip_mtc.loss_rate = rb_voip_mtc->loss_rate;574 sess->stat. rx.voip_mtc.discard_rate = rb_voip_mtc->discard_rate;575 sess->stat. rx.voip_mtc.burst_den = rb_voip_mtc->burst_den;576 sess->stat. rx.voip_mtc.gap_den = rb_voip_mtc->gap_den;577 sess->stat. rx.voip_mtc.burst_dur = pj_ntohs(rb_voip_mtc->burst_dur);578 sess->stat. rx.voip_mtc.gap_dur = pj_ntohs(rb_voip_mtc->gap_dur);579 sess->stat. rx.voip_mtc.rnd_trip_delay =593 sess->stat.tx.voip_mtc.loss_rate = rb_voip_mtc->loss_rate; 594 sess->stat.tx.voip_mtc.discard_rate = rb_voip_mtc->discard_rate; 595 sess->stat.tx.voip_mtc.burst_den = rb_voip_mtc->burst_den; 596 sess->stat.tx.voip_mtc.gap_den = rb_voip_mtc->gap_den; 597 sess->stat.tx.voip_mtc.burst_dur = pj_ntohs(rb_voip_mtc->burst_dur); 598 sess->stat.tx.voip_mtc.gap_dur = pj_ntohs(rb_voip_mtc->gap_dur); 599 sess->stat.tx.voip_mtc.rnd_trip_delay = 580 600 pj_ntohs(rb_voip_mtc->rnd_trip_delay); 581 sess->stat. rx.voip_mtc.end_sys_delay =601 sess->stat.tx.voip_mtc.end_sys_delay = 582 602 pj_ntohs(rb_voip_mtc->end_sys_delay); 583 sess->stat.rx.voip_mtc.signal_lvl = rb_voip_mtc->signal_lvl; 584 sess->stat.rx.voip_mtc.noise_lvl = rb_voip_mtc->noise_lvl; 585 sess->stat.rx.voip_mtc.rerl = rb_voip_mtc->rerl; 586 sess->stat.rx.voip_mtc.gmin = rb_voip_mtc->gmin; 587 sess->stat.rx.voip_mtc.r_factor = rb_voip_mtc->r_factor; 588 sess->stat.rx.voip_mtc.ext_r_factor = rb_voip_mtc->ext_r_factor; 589 sess->stat.rx.voip_mtc.mos_lq = rb_voip_mtc->mos_lq; 590 sess->stat.rx.voip_mtc.mos_cq = rb_voip_mtc->mos_cq; 591 sess->stat.rx.voip_mtc.rx_config = rb_voip_mtc->rx_config; 592 sess->stat.rx.voip_mtc.jb_nom = pj_ntohs(rb_voip_mtc->jb_nom); 593 sess->stat.rx.voip_mtc.jb_max = pj_ntohs(rb_voip_mtc->jb_max); 594 sess->stat.rx.voip_mtc.jb_abs_max = pj_ntohs(rb_voip_mtc->jb_abs_max); 603 /* signal & noise level encoded in two's complement form */ 604 sess->stat.tx.voip_mtc.signal_lvl = (rb_voip_mtc->signal_lvl > 127)? 605 (rb_voip_mtc->signal_lvl - 256) : rb_voip_mtc->signal_lvl; 606 sess->stat.tx.voip_mtc.noise_lvl = (rb_voip_mtc->noise_lvl > 127)? 607 (rb_voip_mtc->noise_lvl - 256) : rb_voip_mtc->noise_lvl; 608 sess->stat.tx.voip_mtc.rerl = rb_voip_mtc->rerl; 609 sess->stat.tx.voip_mtc.gmin = rb_voip_mtc->gmin; 610 sess->stat.tx.voip_mtc.r_factor = rb_voip_mtc->r_factor; 611 sess->stat.tx.voip_mtc.ext_r_factor = rb_voip_mtc->ext_r_factor; 612 sess->stat.tx.voip_mtc.mos_lq = rb_voip_mtc->mos_lq; 613 sess->stat.tx.voip_mtc.mos_cq = rb_voip_mtc->mos_cq; 614 sess->stat.tx.voip_mtc.rx_config = rb_voip_mtc->rx_config; 615 sess->stat.tx.voip_mtc.jb_nom = pj_ntohs(rb_voip_mtc->jb_nom); 616 sess->stat.tx.voip_mtc.jb_max = pj_ntohs(rb_voip_mtc->jb_max); 617 sess->stat.tx.voip_mtc.jb_abs_max = pj_ntohs(rb_voip_mtc->jb_abs_max); 618 619 pj_gettimeofday(&sess->stat.tx.voip_mtc.update); 595 620 } 596 621 } 597 622 … … 664 689 ext_seq = extend_seq(sess, (pj_uint16_t)seq); 665 690 666 691 /* Update statistics summary */ 667 sess->stat. tx.stat_sum.count++;692 sess->stat.rx.stat_sum.count++; 668 693 669 if (sess->stat. tx.stat_sum.begin_seq == 0 ||670 sess->stat. tx.stat_sum.begin_seq > ext_seq)694 if (sess->stat.rx.stat_sum.begin_seq == 0 || 695 sess->stat.rx.stat_sum.begin_seq > ext_seq) 671 696 { 672 sess->stat. tx.stat_sum.begin_seq = ext_seq;697 sess->stat.rx.stat_sum.begin_seq = ext_seq; 673 698 } 674 699 675 if (sess->stat. tx.stat_sum.end_seq == 0 ||676 sess->stat. tx.stat_sum.end_seq < ext_seq)700 if (sess->stat.rx.stat_sum.end_seq == 0 || 701 sess->stat.rx.stat_sum.end_seq < ext_seq) 677 702 { 678 sess->stat. tx.stat_sum.end_seq = ext_seq;703 sess->stat.rx.stat_sum.end_seq = ext_seq; 679 704 } 680 705 681 706 if (lost >= 0) { 682 sess->stat. tx.stat_sum.l = PJ_TRUE;707 sess->stat.rx.stat_sum.l = PJ_TRUE; 683 708 if (lost > 0) 684 sess->stat. tx.stat_sum.lost++;709 sess->stat.rx.stat_sum.lost++; 685 710 } 686 711 687 712 if (dup >= 0) { 688 sess->stat. tx.stat_sum.d = PJ_TRUE;713 sess->stat.rx.stat_sum.d = PJ_TRUE; 689 714 if (dup > 0) 690 sess->stat. tx.stat_sum.dup++;715 sess->stat.rx.stat_sum.dup++; 691 716 } 692 717 693 718 if (jitter >= 0) { 694 719 pj_int32_t diff; 695 720 696 sess->stat. tx.stat_sum.j = PJ_TRUE;697 if (sess->stat. tx.stat_sum.jitter.min > (pj_uint32_t)jitter)698 sess->stat. tx.stat_sum.jitter.min = jitter;699 if (sess->stat. tx.stat_sum.jitter.max < (pj_uint32_t)jitter)700 sess->stat. tx.stat_sum.jitter.max = jitter;701 sess->stat. tx.stat_sum.jitter.mean =702 (jitter + sess->stat. tx.stat_sum.jitter.mean *703 sess->stat. tx.stat_sum.jitter.count) /704 (sess->stat. tx.stat_sum.jitter.count + 1);721 sess->stat.rx.stat_sum.j = PJ_TRUE; 722 if (sess->stat.rx.stat_sum.jitter.min > (pj_uint32_t)jitter) 723 sess->stat.rx.stat_sum.jitter.min = jitter; 724 if (sess->stat.rx.stat_sum.jitter.max < (pj_uint32_t)jitter) 725 sess->stat.rx.stat_sum.jitter.max = jitter; 726 sess->stat.rx.stat_sum.jitter.mean = 727 (jitter + sess->stat.rx.stat_sum.jitter.mean * 728 sess->stat.rx.stat_sum.jitter.count) / 729 (sess->stat.rx.stat_sum.jitter.count + 1); 705 730 706 diff = sess->stat. tx.stat_sum.jitter.mean - jitter;707 sess->stat. tx.stat_sum.jitter.dev =708 (diff * diff + sess->stat. tx.stat_sum.jitter.dev *709 sess->stat. tx.stat_sum.jitter.count) /710 (sess->stat. tx.stat_sum.jitter.count + 1);731 diff = sess->stat.rx.stat_sum.jitter.mean - jitter; 732 sess->stat.rx.stat_sum.jitter.dev = 733 (diff * diff + sess->stat.rx.stat_sum.jitter.dev * 734 sess->stat.rx.stat_sum.jitter.count) / 735 (sess->stat.rx.stat_sum.jitter.count + 1); 711 736 712 ++sess->stat. tx.stat_sum.jitter.count;737 ++sess->stat.rx.stat_sum.jitter.count; 713 738 } 714 739 715 740 if (toh >= 0) { 716 741 pj_int32_t diff; 717 742 718 sess->stat. tx.stat_sum.t = toh_ipv4? 1 : 2;743 sess->stat.rx.stat_sum.t = toh_ipv4? 1 : 2; 719 744 720 if (sess->stat. tx.stat_sum.toh.min > (pj_uint32_t)toh)721 sess->stat. tx.stat_sum.toh.min = toh;722 if (sess->stat. tx.stat_sum.toh.max < (pj_uint32_t)toh)723 sess->stat. tx.stat_sum.toh.max = toh;724 sess->stat. tx.stat_sum.toh.mean =725 (toh + sess->stat. tx.stat_sum.toh.mean *726 sess->stat. tx.stat_sum.toh.count) /727 (sess->stat. tx.stat_sum.toh.count + 1);745 if (sess->stat.rx.stat_sum.toh.min > (pj_uint32_t)toh) 746 sess->stat.rx.stat_sum.toh.min = toh; 747 if (sess->stat.rx.stat_sum.toh.max < (pj_uint32_t)toh) 748 sess->stat.rx.stat_sum.toh.max = toh; 749 sess->stat.rx.stat_sum.toh.mean = 750 (toh + sess->stat.rx.stat_sum.toh.mean * 751 sess->stat.rx.stat_sum.toh.count) / 752 (sess->stat.rx.stat_sum.toh.count + 1); 728 753 729 diff = sess->stat. tx.stat_sum.toh.mean - toh;730 sess->stat. tx.stat_sum.toh.dev =731 (diff * diff + sess->stat. tx.stat_sum.toh.dev *732 sess->stat. tx.stat_sum.toh.count) /733 (sess->stat. tx.stat_sum.toh.count + 1);754 diff = sess->stat.rx.stat_sum.toh.mean - toh; 755 sess->stat.rx.stat_sum.toh.dev = 756 (diff * diff + sess->stat.rx.stat_sum.toh.dev * 757 sess->stat.rx.stat_sum.toh.count) / 758 (sess->stat.rx.stat_sum.toh.count + 1); 734 759 735 ++sess->stat. tx.stat_sum.toh.count;760 ++sess->stat.rx.stat_sum.toh.count; 736 761 } 737 762 738 763 /* Update burst metrics. … … 752 777 sess->voip_mtc_stat.pkt++; 753 778 } 754 779 else { 755 if(sess->voip_mtc_stat.pkt >= sess->stat. tx.voip_mtc.gmin) {780 if(sess->voip_mtc_stat.pkt >= sess->stat.rx.voip_mtc.gmin) { 756 781 /* Gap condition */ 757 782 if(sess->voip_mtc_stat.lost == 1) { 758 783 /* Gap -> Gap */ … … 800 825 801 826 switch(info) { 802 827 case PJMEDIA_RTCP_XR_INFO_SIGNAL_LVL: 803 sess->stat. tx.voip_mtc.signal_lvl = (pj_uint8_t) v;828 sess->stat.rx.voip_mtc.signal_lvl = (pj_int8_t) v; 804 829 break; 805 830 806 831 case PJMEDIA_RTCP_XR_INFO_NOISE_LVL: 807 sess->stat. tx.voip_mtc.noise_lvl = (pj_uint8_t) v;832 sess->stat.rx.voip_mtc.noise_lvl = (pj_int8_t) v; 808 833 break; 809 834 810 835 case PJMEDIA_RTCP_XR_INFO_RERL: 811 sess->stat. tx.voip_mtc.rerl = (pj_uint8_t) v;836 sess->stat.rx.voip_mtc.rerl = (pj_uint8_t) v; 812 837 break; 813 838 814 839 case PJMEDIA_RTCP_XR_INFO_R_FACTOR: 815 sess->stat. tx.voip_mtc.ext_r_factor = (pj_uint8_t) v;840 sess->stat.rx.voip_mtc.ext_r_factor = (pj_uint8_t) v; 816 841 break; 817 842 818 843 case PJMEDIA_RTCP_XR_INFO_MOS_LQ: 819 sess->stat. tx.voip_mtc.mos_lq = (pj_uint8_t) v;844 sess->stat.rx.voip_mtc.mos_lq = (pj_uint8_t) v; 820 845 break; 821 846 822 847 case PJMEDIA_RTCP_XR_INFO_MOS_CQ: 823 sess->stat. tx.voip_mtc.mos_cq = (pj_uint8_t) v;848 sess->stat.rx.voip_mtc.mos_cq = (pj_uint8_t) v; 824 849 break; 825 850 826 851 case PJMEDIA_RTCP_XR_INFO_CONF_PLC: 827 852 if (v >= 0 && v <= 3) { 828 sess->stat. tx.voip_mtc.rx_config &= 0x3F;829 sess->stat. tx.voip_mtc.rx_config |= (pj_uint8_t) (v << 6);853 sess->stat.rx.voip_mtc.rx_config &= 0x3F; 854 sess->stat.rx.voip_mtc.rx_config |= (pj_uint8_t) (v << 6); 830 855 } 831 856 break; 832 857 833 858 case PJMEDIA_RTCP_XR_INFO_CONF_JBA: 834 859 if (v >= 0 && v <= 3) { 835 sess->stat. tx.voip_mtc.rx_config &= 0xCF;836 sess->stat. tx.voip_mtc.rx_config |= (pj_uint8_t) (v << 4);860 sess->stat.rx.voip_mtc.rx_config &= 0xCF; 861 sess->stat.rx.voip_mtc.rx_config |= (pj_uint8_t) (v << 4); 837 862 } 838 863 break; 839 864 840 865 case PJMEDIA_RTCP_XR_INFO_CONF_JBR: 841 866 if (v >= 0 && v <= 15) { 842 sess->stat. tx.voip_mtc.rx_config &= 0xF0;843 sess->stat. tx.voip_mtc.rx_config |= (pj_uint8_t) v;867 sess->stat.rx.voip_mtc.rx_config &= 0xF0; 868 sess->stat.rx.voip_mtc.rx_config |= (pj_uint8_t) v; 844 869 } 845 870 break; 846 871 847 872 case PJMEDIA_RTCP_XR_INFO_JB_NOM: 848 sess->stat. tx.voip_mtc.jb_nom = (pj_uint16_t) v;873 sess->stat.rx.voip_mtc.jb_nom = (pj_uint16_t) v; 849 874 break; 850 875 851 876 case PJMEDIA_RTCP_XR_INFO_JB_MAX: 852 sess->stat. tx.voip_mtc.jb_max = (pj_uint16_t) v;877 sess->stat.rx.voip_mtc.jb_max = (pj_uint16_t) v; 853 878 break; 854 879 855 880 case PJMEDIA_RTCP_XR_INFO_JB_ABS_MAX: 856 sess->stat. tx.voip_mtc.jb_abs_max = (pj_uint16_t) v;881 sess->stat.rx.voip_mtc.jb_abs_max = (pj_uint16_t) v; 857 882 break; 858 883 859 884 default: -
pjmedia/src/pjmedia/stream.c
1557 1557 1558 1558 stream->transport = tp; 1559 1559 1560 #if PJMEDIA_HAS_RTCP_XR && PJMEDIA_STREAM_ENABLE_XR1561 /* Enable RTCP XR and update s ome settings*/1562 {1560 #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0) 1561 /* Enable RTCP XR and update stream info/config to RTCP XR */ 1562 if (info->rtcp_xr_enabled) { 1563 1563 int i; 1564 1564 1565 pjmedia_rtcp_enable_xr(&stream->rtcp, PJ_TRUE); 1565 1566 1566 1567 /* jitter buffer adaptive info */ … … 1713 1714 return PJ_SUCCESS; 1714 1715 } 1715 1716 1717 #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0) 1718 /* 1719 * Get stream extended statistics. 1720 */ 1721 PJ_DEF(pj_status_t) pjmedia_stream_get_stat_xr( const pjmedia_stream *stream, 1722 pjmedia_rtcp_xr_stat *stat) 1723 { 1724 PJ_ASSERT_RETURN(stream && stat, PJ_EINVAL); 1716 1725 1726 if (stream->rtcp.xr_enabled) { 1727 pj_memcpy(stat, &stream->rtcp.xr_session.stat, sizeof(pjmedia_rtcp_xr_stat)); 1728 return PJ_SUCCESS; 1729 } 1730 return PJ_ENOTFOUND; 1731 } 1732 #endif 1733 1717 1734 /* 1718 1735 * Pause stream. 1719 1736 */ -
pjmedia/src/pjmedia/session.c
166 166 167 167 pj_bzero(si, sizeof(*si)); 168 168 169 #if PJMEDIA_HAS_RTCP_XR && PJMEDIA_STREAM_ENABLE_XR 170 /* Set default RTCP XR enabled/disabled */ 171 si->rtcp_xr_enabled = PJ_TRUE; 172 #endif 173 169 174 /* Media type: */ 170 175 171 176 if (pj_stricmp(&local_m->desc.media, &ID_AUDIO) == 0) {