void ms_filter_log_statistics(void){ MSList *sorted=NULL; MSList *elem; uint64_t total=1; ms_message("Filter usage statistics:"); for(elem=stats_list;elem!=NULL;elem=elem->next){ MSFilterStats *stats=(MSFilterStats *)elem->data; sorted=ms_list_insert_sorted(sorted,stats,(MSCompareFunc)usage_compare); total+=stats->elapsed; } ms_message("Name\tCount\tTime/tick (ms)\tCPU Usage"); for(elem=sorted;elem!=NULL;elem=elem->next){ MSFilterStats *stats=(MSFilterStats *)elem->data; double percentage=100.0*((double)stats->elapsed)/(double)total; double tpt=((double)stats->elapsed*1e-6)/((double)stats->count+1.0); ms_message("%s %i %g %g",stats->name,stats->count,tpt,percentage); } ms_list_free(sorted); }
void ms_factory_log_statistics(MSFactory *obj){ MSList *sorted=NULL; MSList *elem; uint64_t total=1; for(elem=obj->stats_list;elem!=NULL;elem=elem->next){ MSFilterStats *stats=(MSFilterStats *)elem->data; sorted=ms_list_insert_sorted(sorted,stats,(MSCompareFunc)usage_compare); total+=stats->elapsed; } ms_message("==========================================================="); ms_message(" FILTER USAGE STATISTICS "); ms_message("Name Count Time/tick (ms) CPU Usage"); ms_message("-----------------------------------------------------------"); for(elem=sorted;elem!=NULL;elem=elem->next){ MSFilterStats *stats=(MSFilterStats *)elem->data; double percentage=100.0*((double)stats->elapsed)/(double)total; double tpt=((double)stats->elapsed*1e-6)/((double)stats->count+1.0); ms_message("%-19s %-9i %-19g %-10g",stats->name,stats->count,tpt,percentage); } ms_message("==========================================================="); ms_list_free(sorted); }
static bool_t stateful_analyzer_process_rtcp(MSQosAnalyzer *objbase, mblk_t *rtcp){ MSStatefulQosAnalyzer *obj=(MSStatefulQosAnalyzer*)objbase; const report_block_t *rb=NULL; if (rtcp_is_SR(rtcp)){ rb=rtcp_SR_get_report_block(rtcp,0); }else if (rtcp_is_RR(rtcp)){ rb=rtcp_RR_get_report_block(rtcp,0); } if (rb && report_block_get_ssrc(rb)==rtp_session_get_send_ssrc(obj->session)){ if (ortp_loss_rate_estimator_process_report_block(objbase->lre,&obj->session->rtp,rb)){ int i; float loss_rate = ortp_loss_rate_estimator_get_value(objbase->lre); float up_bw = stateful_qos_analyzer_upload_bandwidth(obj,report_block_get_high_ext_seq(rb)); obj->curindex++; /*flush bandwidth estimation measures for seq number lower than remote report block received*/ for (i=0;i<BW_HISTORY;i++){ if (obj->upload_bandwidth[i].seq_number<report_block_get_high_ext_seq(rb)){ obj->upload_bandwidth[i].seq_number=0; obj->upload_bandwidth[i].up_bandwidth=0.f; } } /* Always skip the first report, since values might be erroneous due to initialization of multiples objects (encoder/decoder/stats computing..) Instead assume loss rate is a good estimation of network capacity */ if (obj->curindex==1) { obj->network_loss_rate=loss_rate; return TRUE; } obj->latest=ms_new0(rtcpstatspoint_t, 1); obj->latest->timestamp=ms_time(0); obj->latest->bandwidth=up_bw; obj->latest->loss_percent=loss_rate; obj->latest->rtt=rtp_session_get_round_trip_propagation(obj->session); obj->rtcpstatspoint=ms_list_insert_sorted(obj->rtcpstatspoint, obj->latest, (MSCompareFunc)sort_by_bandwidth); /*if the measure was 0% loss, reset to 0% every measures below it*/ if (obj->latest->loss_percent < 1e-5){ MSList *it=obj->rtcpstatspoint; MSList *latest_pos=ms_list_find(obj->rtcpstatspoint,obj->latest); while (it!=latest_pos->next){ ((rtcpstatspoint_t *)it->data)->loss_percent=0.f; it = it->next; } } ms_message("MSStatefulQosAnalyzer[%p]: one more %d: %f %f", obj, obj->curindex-1, obj->latest->bandwidth, obj->latest->loss_percent); if (ms_list_size(obj->rtcpstatspoint) > ESTIM_HISTORY){ int prev_size = ms_list_size(obj->rtcpstatspoint); /*clean everything which occurred 60 sec or more ago*/ time_t clear_time = ms_time(0) - 60; obj->rtcpstatspoint = ms_list_remove_custom(obj->rtcpstatspoint, (MSCompareFunc)earlier_than, &clear_time); ms_message("MSStatefulQosAnalyzer[%p]: reached list maximum capacity " "(count=%d) --> Cleaned list (count=%d)", obj, prev_size, ms_list_size(obj->rtcpstatspoint)); } return TRUE; } } return FALSE; }
static bool_t stateful_analyzer_process_rtcp(MSQosAnalyzer *objbase, mblk_t *rtcp){ MSStatefulQosAnalyzer *obj=(MSStatefulQosAnalyzer*)objbase; rtpstats_t *cur; const report_block_t *rb=NULL; if (rtcp_is_SR(rtcp)){ rb=rtcp_SR_get_report_block(rtcp,0); }else if (rtcp_is_RR(rtcp)){ rb=rtcp_RR_get_report_block(rtcp,0); } if (rb && report_block_get_ssrc(rb)==rtp_session_get_send_ssrc(obj->session)){ double up_bw = stateful_qos_analyzer_upload_bandwidth(obj); int total_emitted=stateful_qos_analyzer_get_total_emitted(obj, rb); obj->curindex++; cur=&obj->stats[obj->curindex % STATS_HISTORY]; if (obj->clockrate==0){ PayloadType *pt=rtp_profile_get_payload(rtp_session_get_send_profile(obj->session),rtp_session_get_send_payload_type(obj->session)); if (pt!=NULL) obj->clockrate=pt->clock_rate; else return FALSE; } cur->lost_percentage=100.0*(float)report_block_get_fraction_lost(rb)/256.0; cur->int_jitter=1000.0*(float)report_block_get_interarrival_jitter(rb)/(float)obj->clockrate; cur->rt_prop=rtp_session_get_round_trip_propagation(obj->session); ms_message("MSSimpleQosAnalyzer: lost_percentage=%f, int_jitter=%f ms, rt_prop=%f sec",cur->lost_percentage,cur->int_jitter,cur->rt_prop); if (obj->curindex>2){ double loss_rate = cur->lost_percentage/100.0; int cum_loss=report_block_get_cum_packet_loss(rb); int cum_loss_curr=cum_loss - obj->cum_loss_prev; int uniq_emitted=report_block_get_high_ext_seq(rb) - obj->previous_ext_high_seq_num_rec; if (obj->previous_ext_high_seq_num_rec > 0){ loss_rate=(1. - (uniq_emitted - cum_loss_curr) * 1.f / total_emitted); ms_debug("MSQosStatefulAnalyzer[%p]: RECEIVE estimated loss rate=%f vs 'real'=%f", obj, loss_rate, report_block_get_fraction_lost(rb)/256.); } obj->latest=ms_new0(rtcpstatspoint_t, 1); obj->latest->timestamp=ms_time(0); obj->latest->bandwidth=up_bw; obj->latest->loss_percent=MAX(0,loss_rate); obj->latest->rtt=cur->rt_prop; obj->rtcpstatspoint=ms_list_insert_sorted(obj->rtcpstatspoint, obj->latest, (MSCompareFunc)sort_points); if (obj->latest->loss_percent < 1e-5){ MSList *it=obj->rtcpstatspoint; MSList *latest_pos=ms_list_find(obj->rtcpstatspoint,obj->latest); while (it!=latest_pos->next){ ((rtcpstatspoint_t *)it->data)->loss_percent=0.f; it = it->next; } } ms_debug("MSQosStatefulAnalyzer[%p]: one more %d: %f %f", obj, obj->curindex-2, obj->latest->bandwidth, obj->latest->loss_percent); if (ms_list_size(obj->rtcpstatspoint) > ESTIM_HISTORY){ #ifdef DEBUG int prev_size = ms_list_size(obj->rtcpstatspoint); #endif /*clean everything which occurred 60 sec or more ago*/ time_t clear_time = ms_time(0) - 60; obj->rtcpstatspoint = ms_list_remove_custom(obj->rtcpstatspoint, (MSCompareFunc)earlier_than, &clear_time); ms_debug("MSQosStatefulAnalyzer[%p]: Reached list maximum capacity (count=%d) --> Cleaned list (count=%d)", obj, prev_size, ms_list_size(obj->rtcpstatspoint)); } } obj->cum_loss_prev=report_block_get_cum_packet_loss(rb); obj->previous_ext_high_seq_num_rec=report_block_get_high_ext_seq(rb); } return rb!=NULL; }