示例#1
0
/*
 * Get statistics
 */
PJ_DEF(pj_status_t) pjmedia_session_get_stream_stat( pjmedia_session *session,
						     unsigned index,
						     pjmedia_rtcp_stat *stat)
{
    PJ_ASSERT_RETURN(session && stat && index < session->stream_cnt, 
		     PJ_EINVAL);

    return pjmedia_stream_get_stat(session->stream[index], stat);
}
示例#2
0
/* Dump media session */
static void dump_media_session(const char *indent,
			       char *buf, unsigned maxlen,
			       pjsua_call *call)
{
    unsigned i;
    char *p = buf, *end = buf+maxlen;
    int len;

    for (i=0; i<call->med_cnt; ++i) {
	pjsua_call_media *call_med = &call->media[i];
	pjmedia_rtcp_stat stat;
	pj_bool_t has_stat;
	pjmedia_transport_info tp_info;
	char rem_addr_buf[80];
	char codec_info[32] = {'0'};
	char rx_info[80] = {'\0'};
	char tx_info[80] = {'\0'};
	const char *rem_addr;
	const char *dir_str;
	const char *media_type_str;

	switch (call_med->type) {
	case PJMEDIA_TYPE_AUDIO:
	    media_type_str = "audio";
	    break;
	case PJMEDIA_TYPE_VIDEO:
	    media_type_str = "video";
	    break;
	case PJMEDIA_TYPE_APPLICATION:
	    media_type_str = "application";
	    break;
	default:
	    media_type_str = "unknown";
	    break;
	}

	/* Check if the stream is deactivated */
	if (call_med->tp == NULL ||
	    (!call_med->strm.a.stream && !call_med->strm.v.stream))
	{
	    len = pj_ansi_snprintf(p, end-p,
		      "%s  #%d %s deactivated\n",
		      indent, i, media_type_str);
	    if (len < 1 || len > end-p) {
		*p = '\0';
		return;
	    }

	    p += len;
	    continue;
	}

	pjmedia_transport_info_init(&tp_info);
	pjmedia_transport_get_info(call_med->tp, &tp_info);

	// rem_addr will contain actual address of RTP originator, instead of
	// remote RTP address specified by stream which is fetched from the SDP.
	// Please note that we are assuming only one stream per call.
	//rem_addr = pj_sockaddr_print(&info.stream_info[i].rem_addr,
	//			     rem_addr_buf, sizeof(rem_addr_buf), 3);
	if (pj_sockaddr_has_addr(&tp_info.src_rtp_name)) {
	    rem_addr = pj_sockaddr_print(&tp_info.src_rtp_name, rem_addr_buf,
					 sizeof(rem_addr_buf), 3);
	} else {
	    pj_ansi_snprintf(rem_addr_buf, sizeof(rem_addr_buf), "-");
	    rem_addr = rem_addr_buf;
	}

	if (call_med->dir == PJMEDIA_DIR_NONE) {
	    /* To handle when the stream that is currently being paused
	     * (http://trac.pjsip.org/repos/ticket/1079)
	     */
	    dir_str = "inactive";
	} else if (call_med->dir == PJMEDIA_DIR_ENCODING)
	    dir_str = "sendonly";
	else if (call_med->dir == PJMEDIA_DIR_DECODING)
	    dir_str = "recvonly";
	else if (call_med->dir == PJMEDIA_DIR_ENCODING_DECODING)
	    dir_str = "sendrecv";
	else
	    dir_str = "inactive";

	if (call_med->type == PJMEDIA_TYPE_AUDIO) {
	    pjmedia_stream *stream = call_med->strm.a.stream;
	    pjmedia_stream_info info;

	    pjmedia_stream_get_stat(stream, &stat);
	    has_stat = PJ_TRUE;

	    pjmedia_stream_get_info(stream, &info);
	    pj_ansi_snprintf(codec_info, sizeof(codec_info), " %.*s @%dkHz",
			     (int)info.fmt.encoding_name.slen,
			     info.fmt.encoding_name.ptr,
			     info.fmt.clock_rate / 1000);
	    pj_ansi_snprintf(rx_info, sizeof(rx_info), "pt=%d,",
			     info.rx_pt);
	    pj_ansi_snprintf(tx_info, sizeof(tx_info), "pt=%d, ptime=%d,",
			     info.tx_pt,
			     info.param->setting.frm_per_pkt*
			     info.param->info.frm_ptime);

#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
	} else if (call_med->type == PJMEDIA_TYPE_VIDEO) {
	    pjmedia_vid_stream *stream = call_med->strm.v.stream;
	    pjmedia_vid_stream_info info;

	    pjmedia_vid_stream_get_stat(stream, &stat);
	    has_stat = PJ_TRUE;

	    pjmedia_vid_stream_get_info(stream, &info);
	    pj_ansi_snprintf(codec_info, sizeof(codec_info), " %.*s",
	                     (int)info.codec_info.encoding_name.slen,
			     info.codec_info.encoding_name.ptr);
	    if (call_med->dir & PJMEDIA_DIR_DECODING) {
		pjmedia_video_format_detail *vfd;
		vfd = pjmedia_format_get_video_format_detail(
					&info.codec_param->dec_fmt, PJ_TRUE);
		pj_ansi_snprintf(rx_info, sizeof(rx_info),
				 "pt=%d, size=%dx%d, fps=%.2f,",
				 info.rx_pt,
				 vfd->size.w, vfd->size.h,
				 vfd->fps.num*1.0/vfd->fps.denum);
	    }
	    if (call_med->dir & PJMEDIA_DIR_ENCODING) {
		pjmedia_video_format_detail *vfd;
		vfd = pjmedia_format_get_video_format_detail(
					&info.codec_param->enc_fmt, PJ_TRUE);
		pj_ansi_snprintf(tx_info, sizeof(tx_info),
				 "pt=%d, size=%dx%d, fps=%.2f,",
				 info.tx_pt,
				 vfd->size.w, vfd->size.h,
				 vfd->fps.num*1.0/vfd->fps.denum);
	    }
#endif /* PJMEDIA_HAS_VIDEO */

	} else {
	    has_stat = PJ_FALSE;
	}

	len = pj_ansi_snprintf(p, end-p,
		  "%s  #%d %s%s, %s, peer=%s\n",
		  indent,
		  call_med->idx,
		  media_type_str,
		  codec_info,
		  dir_str,
		  rem_addr);
	if (len < 1 || len > end-p) {
	    *p = '\0';
	    return;
	}
	p += len;

	/* Get and ICE SRTP status */
	if (call_med->tp) {
	    pjmedia_transport_info tp_info;

	    pjmedia_transport_info_init(&tp_info);
	    pjmedia_transport_get_info(call_med->tp, &tp_info);
	    if (tp_info.specific_info_cnt > 0) {
		unsigned j;
		for (j = 0; j < tp_info.specific_info_cnt; ++j) {
		    if (tp_info.spc_info[j].type == PJMEDIA_TRANSPORT_TYPE_SRTP)
		    {
			pjmedia_srtp_info *srtp_info =
				    (pjmedia_srtp_info*) tp_info.spc_info[j].buffer;

			len = pj_ansi_snprintf(p, end-p,
					       "   %s  SRTP status: %s Crypto-suite: %s",
					       indent,
					       (srtp_info->active?"Active":"Not active"),
					       srtp_info->tx_policy.name.ptr);
			if (len > 0 && len < end-p) {
			    p += len;
			    *p++ = '\n';
			    *p = '\0';
			}
		    } else if (tp_info.spc_info[j].type==PJMEDIA_TRANSPORT_TYPE_ICE) {
			const pjmedia_ice_transport_info *ii;
			unsigned jj;

			ii = (const pjmedia_ice_transport_info*)
			     tp_info.spc_info[j].buffer;

			len = pj_ansi_snprintf(p, end-p,
					       "   %s  ICE role: %s, state: %s, comp_cnt: %u",
					       indent,
					       pj_ice_sess_role_name(ii->role),
					       pj_ice_strans_state_name(ii->sess_state),
					       ii->comp_cnt);
			if (len > 0 && len < end-p) {
			    p += len;
			    *p++ = '\n';
			    *p = '\0';
			}

			for (jj=0; ii->sess_state==PJ_ICE_STRANS_STATE_RUNNING && jj<2; ++jj) {
			    const char *type1 = pj_ice_get_cand_type_name(ii->comp[jj].lcand_type);
			    const char *type2 = pj_ice_get_cand_type_name(ii->comp[jj].rcand_type);
			    char addr1[PJ_INET6_ADDRSTRLEN+10];
			    char addr2[PJ_INET6_ADDRSTRLEN+10];

			    if (pj_sockaddr_has_addr(&ii->comp[jj].lcand_addr))
				pj_sockaddr_print(&ii->comp[jj].lcand_addr, addr1, sizeof(addr1), 3);
			    else
				strcpy(addr1, "0.0.0.0:0");
			    if (pj_sockaddr_has_addr(&ii->comp[jj].rcand_addr))
				pj_sockaddr_print(&ii->comp[jj].rcand_addr, addr2, sizeof(addr2), 3);
			    else
				strcpy(addr2, "0.0.0.0:0");
			    len = pj_ansi_snprintf(p, end-p,
			                           "   %s     [%d]: L:%s (%c) --> R:%s (%c)\n",
			                           indent, jj,
			                           addr1, type1[0],
			                           addr2, type2[0]);
			    if (len > 0 && len < end-p) {
				p += len;
				*p = '\0';
			    }
			}
		    }
		}
	    }
	}


	if (has_stat) {
	    len = dump_media_stat(indent, p, end-p, &stat,
				  rx_info, tx_info);
	    p += len;
	}

#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
#   define SAMPLES_TO_USEC(usec, samples, clock_rate) \
	do { \
	    if (samples <= 4294) \
		usec = samples * 1000000 / clock_rate; \
	    else { \
		usec = samples * 1000 / clock_rate; \
		usec *= 1000; \
	    } \
	} while(0)

#   define PRINT_VOIP_MTC_VAL(s, v) \
	if (v == 127) \
	    sprintf(s, "(na)"); \
	else \
	    sprintf(s, "%d", v)

#   define VALIDATE_PRINT_BUF() \
	if (len < 1 || len > end-p) { *p = '\0'; return; } \
	p += len; *p++ = '\n'; *p = '\0'


	if (call_med->type == PJMEDIA_TYPE_AUDIO) {
	    pjmedia_stream_info info;
	    char last_update[64];
	    char loss[16], dup[16];
	    char jitter[80];
	    char toh[80];
	    char plc[16], jba[16], jbr[16];
	    char signal_lvl[16], noise_lvl[16], rerl[16];
	    char r_factor[16], ext_r_factor[16], mos_lq[16], mos_cq[16];
	    pjmedia_rtcp_xr_stat xr_stat;
	    unsigned clock_rate;
	    pj_time_val now;

	    if (pjmedia_stream_get_stat_xr(call_med->strm.a.stream,
	                                   &xr_stat) != PJ_SUCCESS)
	    {
		continue;
	    }

	    if (pjmedia_stream_get_info(call_med->strm.a.stream, &info)
		    != PJ_SUCCESS)
	    {
		continue;
	    }

	    clock_rate = info.fmt.clock_rate;
	    pj_gettimeofday(&now);

	    len = pj_ansi_snprintf(p, end-p, "\n%s  Extended reports:", indent);
	    VALIDATE_PRINT_BUF();

	    /* Statistics Summary */
	    len = pj_ansi_snprintf(p, end-p, "%s   Statistics Summary", indent);
	    VALIDATE_PRINT_BUF();

	    if (xr_stat.rx.stat_sum.l)
		sprintf(loss, "%d", xr_stat.rx.stat_sum.lost);
	    else
		sprintf(loss, "(na)");

	    if (xr_stat.rx.stat_sum.d)
		sprintf(dup, "%d", xr_stat.rx.stat_sum.dup);
	    else
		sprintf(dup, "(na)");

	    if (xr_stat.rx.stat_sum.j) {
		unsigned jmin, jmax, jmean, jdev;

		SAMPLES_TO_USEC(jmin, xr_stat.rx.stat_sum.jitter.min,
				clock_rate);
		SAMPLES_TO_USEC(jmax, xr_stat.rx.stat_sum.jitter.max,
				clock_rate);
		SAMPLES_TO_USEC(jmean, xr_stat.rx.stat_sum.jitter.mean,
				clock_rate);
		SAMPLES_TO_USEC(jdev,
			       pj_math_stat_get_stddev(&xr_stat.rx.stat_sum.jitter),
			       clock_rate);
		sprintf(jitter, "%7.3f %7.3f %7.3f %7.3f",
			jmin/1000.0, jmean/1000.0, jmax/1000.0, jdev/1000.0);
	    } else
		sprintf(jitter, "(report not available)");

	    if (xr_stat.rx.stat_sum.t) {
		sprintf(toh, "%11d %11d %11d %11d",
			xr_stat.rx.stat_sum.toh.min,
			xr_stat.rx.stat_sum.toh.mean,
			xr_stat.rx.stat_sum.toh.max,
			pj_math_stat_get_stddev(&xr_stat.rx.stat_sum.toh));
	    } else
		sprintf(toh, "(report not available)");

	    if (xr_stat.rx.stat_sum.update.sec == 0)
		strcpy(last_update, "never");
	    else {
		pj_gettimeofday(&now);
		PJ_TIME_VAL_SUB(now, xr_stat.rx.stat_sum.update);
		sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
			now.sec / 3600,
			(now.sec % 3600) / 60,
			now.sec % 60,
			now.msec);
	    }

	    len = pj_ansi_snprintf(p, end-p,
		    "%s     RX last update: %s\n"
		    "%s        begin seq=%d, end seq=%d\n"
		    "%s        pkt loss=%s, dup=%s\n"
		    "%s              (msec)    min     avg     max     dev\n"
		    "%s        jitter     : %s\n"
		    "%s        toh        : %s",
		    indent, last_update,
		    indent,
		    xr_stat.rx.stat_sum.begin_seq, xr_stat.rx.stat_sum.end_seq,
		    indent, loss, dup,
		    indent,
		    indent, jitter,
		    indent, toh
		    );
	    VALIDATE_PRINT_BUF();

	    if (xr_stat.tx.stat_sum.l)
		sprintf(loss, "%d", xr_stat.tx.stat_sum.lost);
	    else
		sprintf(loss, "(na)");

	    if (xr_stat.tx.stat_sum.d)
		sprintf(dup, "%d", xr_stat.tx.stat_sum.dup);
	    else
		sprintf(dup, "(na)");

	    if (xr_stat.tx.stat_sum.j) {
		unsigned jmin, jmax, jmean, jdev;

		SAMPLES_TO_USEC(jmin, xr_stat.tx.stat_sum.jitter.min,
				clock_rate);
		SAMPLES_TO_USEC(jmax, xr_stat.tx.stat_sum.jitter.max,
				clock_rate);
		SAMPLES_TO_USEC(jmean, xr_stat.tx.stat_sum.jitter.mean,
				clock_rate);
		SAMPLES_TO_USEC(jdev,
			       pj_math_stat_get_stddev(&xr_stat.tx.stat_sum.jitter),
			       clock_rate);
		sprintf(jitter, "%7.3f %7.3f %7.3f %7.3f",
			jmin/1000.0, jmean/1000.0, jmax/1000.0, jdev/1000.0);
	    } else
		sprintf(jitter, "(report not available)");

	    if (xr_stat.tx.stat_sum.t) {
		sprintf(toh, "%11d %11d %11d %11d",
			xr_stat.tx.stat_sum.toh.min,
			xr_stat.tx.stat_sum.toh.mean,
			xr_stat.tx.stat_sum.toh.max,
			pj_math_stat_get_stddev(&xr_stat.rx.stat_sum.toh));
	    } else
		sprintf(toh,    "(report not available)");

	    if (xr_stat.tx.stat_sum.update.sec == 0)
		strcpy(last_update, "never");
	    else {
		pj_gettimeofday(&now);
		PJ_TIME_VAL_SUB(now, xr_stat.tx.stat_sum.update);
		sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
			now.sec / 3600,
			(now.sec % 3600) / 60,
			now.sec % 60,
			now.msec);
	    }

	    len = pj_ansi_snprintf(p, end-p,
		    "%s     TX last update: %s\n"
		    "%s        begin seq=%d, end seq=%d\n"
		    "%s        pkt loss=%s, dup=%s\n"
		    "%s              (msec)    min     avg     max     dev\n"
		    "%s        jitter     : %s\n"
		    "%s        toh        : %s",
		    indent, last_update,
		    indent,
		    xr_stat.tx.stat_sum.begin_seq, xr_stat.tx.stat_sum.end_seq,
		    indent, loss, dup,
		    indent,
		    indent, jitter,
		    indent, toh
		    );
	    VALIDATE_PRINT_BUF();


	    /* VoIP Metrics */
	    len = pj_ansi_snprintf(p, end-p, "%s   VoIP Metrics", indent);
	    VALIDATE_PRINT_BUF();

	    PRINT_VOIP_MTC_VAL(signal_lvl, xr_stat.rx.voip_mtc.signal_lvl);
	    PRINT_VOIP_MTC_VAL(noise_lvl, xr_stat.rx.voip_mtc.noise_lvl);
	    PRINT_VOIP_MTC_VAL(rerl, xr_stat.rx.voip_mtc.rerl);
	    PRINT_VOIP_MTC_VAL(r_factor, xr_stat.rx.voip_mtc.r_factor);
	    PRINT_VOIP_MTC_VAL(ext_r_factor, xr_stat.rx.voip_mtc.ext_r_factor);
	    PRINT_VOIP_MTC_VAL(mos_lq, xr_stat.rx.voip_mtc.mos_lq);
	    PRINT_VOIP_MTC_VAL(mos_cq, xr_stat.rx.voip_mtc.mos_cq);

	    switch ((xr_stat.rx.voip_mtc.rx_config>>6) & 3) {
		case PJMEDIA_RTCP_XR_PLC_DIS:
		    sprintf(plc, "DISABLED");
		    break;
		case PJMEDIA_RTCP_XR_PLC_ENH:
		    sprintf(plc, "ENHANCED");
		    break;
		case PJMEDIA_RTCP_XR_PLC_STD:
		    sprintf(plc, "STANDARD");
		    break;
		case PJMEDIA_RTCP_XR_PLC_UNK:
		default:
		    sprintf(plc, "UNKNOWN");
		    break;
	    }

	    switch ((xr_stat.rx.voip_mtc.rx_config>>4) & 3) {
		case PJMEDIA_RTCP_XR_JB_FIXED:
		    sprintf(jba, "FIXED");
		    break;
		case PJMEDIA_RTCP_XR_JB_ADAPTIVE:
		    sprintf(jba, "ADAPTIVE");
		    break;
		default:
		    sprintf(jba, "UNKNOWN");
		    break;
	    }

	    sprintf(jbr, "%d", xr_stat.rx.voip_mtc.rx_config & 0x0F);

	    if (xr_stat.rx.voip_mtc.update.sec == 0)
		strcpy(last_update, "never");
	    else {
		pj_gettimeofday(&now);
		PJ_TIME_VAL_SUB(now, xr_stat.rx.voip_mtc.update);
		sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
			now.sec / 3600,
			(now.sec % 3600) / 60,
			now.sec % 60,
			now.msec);
	    }

	    len = pj_ansi_snprintf(p, end-p,
		    "%s     RX last update: %s\n"
		    "%s        packets    : loss rate=%d (%.2f%%), discard rate=%d (%.2f%%)\n"
		    "%s        burst      : density=%d (%.2f%%), duration=%d%s\n"
		    "%s        gap        : density=%d (%.2f%%), duration=%d%s\n"
		    "%s        delay      : round trip=%d%s, end system=%d%s\n"
		    "%s        level      : signal=%s%s, noise=%s%s, RERL=%s%s\n"
		    "%s        quality    : R factor=%s, ext R factor=%s\n"
		    "%s                     MOS LQ=%s, MOS CQ=%s\n"
		    "%s        config     : PLC=%s, JB=%s, JB rate=%s, Gmin=%d\n"
		    "%s        JB delay   : cur=%d%s, max=%d%s, abs max=%d%s",
		    indent,
		    last_update,
		    /* packets */
		    indent,
		    xr_stat.rx.voip_mtc.loss_rate, xr_stat.rx.voip_mtc.loss_rate*100.0/256,
		    xr_stat.rx.voip_mtc.discard_rate, xr_stat.rx.voip_mtc.discard_rate*100.0/256,
		    /* burst */
		    indent,
		    xr_stat.rx.voip_mtc.burst_den, xr_stat.rx.voip_mtc.burst_den*100.0/256,
		    xr_stat.rx.voip_mtc.burst_dur, "ms",
		    /* gap */
		    indent,
		    xr_stat.rx.voip_mtc.gap_den, xr_stat.rx.voip_mtc.gap_den*100.0/256,
		    xr_stat.rx.voip_mtc.gap_dur, "ms",
		    /* delay */
		    indent,
		    xr_stat.rx.voip_mtc.rnd_trip_delay, "ms",
		    xr_stat.rx.voip_mtc.end_sys_delay, "ms",
		    /* level */
		    indent,
		    signal_lvl, "dB",
		    noise_lvl, "dB",
		    rerl, "",
		    /* quality */
		    indent,
		    r_factor, ext_r_factor,
		    indent,
		    mos_lq, mos_cq,
		    /* config */
		    indent,
		    plc, jba, jbr, xr_stat.rx.voip_mtc.gmin,
		    /* JB delay */
		    indent,
		    xr_stat.rx.voip_mtc.jb_nom, "ms",
		    xr_stat.rx.voip_mtc.jb_max, "ms",
		    xr_stat.rx.voip_mtc.jb_abs_max, "ms"
		    );
	    VALIDATE_PRINT_BUF();

	    PRINT_VOIP_MTC_VAL(signal_lvl, xr_stat.tx.voip_mtc.signal_lvl);
	    PRINT_VOIP_MTC_VAL(noise_lvl, xr_stat.tx.voip_mtc.noise_lvl);
	    PRINT_VOIP_MTC_VAL(rerl, xr_stat.tx.voip_mtc.rerl);
	    PRINT_VOIP_MTC_VAL(r_factor, xr_stat.tx.voip_mtc.r_factor);
	    PRINT_VOIP_MTC_VAL(ext_r_factor, xr_stat.tx.voip_mtc.ext_r_factor);
	    PRINT_VOIP_MTC_VAL(mos_lq, xr_stat.tx.voip_mtc.mos_lq);
	    PRINT_VOIP_MTC_VAL(mos_cq, xr_stat.tx.voip_mtc.mos_cq);

	    switch ((xr_stat.tx.voip_mtc.rx_config>>6) & 3) {
		case PJMEDIA_RTCP_XR_PLC_DIS:
		    sprintf(plc, "DISABLED");
		    break;
		case PJMEDIA_RTCP_XR_PLC_ENH:
		    sprintf(plc, "ENHANCED");
		    break;
		case PJMEDIA_RTCP_XR_PLC_STD:
		    sprintf(plc, "STANDARD");
		    break;
		case PJMEDIA_RTCP_XR_PLC_UNK:
		default:
		    sprintf(plc, "unknown");
		    break;
	    }

	    switch ((xr_stat.tx.voip_mtc.rx_config>>4) & 3) {
		case PJMEDIA_RTCP_XR_JB_FIXED:
		    sprintf(jba, "FIXED");
		    break;
		case PJMEDIA_RTCP_XR_JB_ADAPTIVE:
		    sprintf(jba, "ADAPTIVE");
		    break;
		default:
		    sprintf(jba, "unknown");
		    break;
	    }

	    sprintf(jbr, "%d", xr_stat.tx.voip_mtc.rx_config & 0x0F);

	    if (xr_stat.tx.voip_mtc.update.sec == 0)
		strcpy(last_update, "never");
	    else {
		pj_gettimeofday(&now);
		PJ_TIME_VAL_SUB(now, xr_stat.tx.voip_mtc.update);
		sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
			now.sec / 3600,
			(now.sec % 3600) / 60,
			now.sec % 60,
			now.msec);
	    }

	    len = pj_ansi_snprintf(p, end-p,
		    "%s     TX last update: %s\n"
		    "%s        packets    : loss rate=%d (%.2f%%), discard rate=%d (%.2f%%)\n"
		    "%s        burst      : density=%d (%.2f%%), duration=%d%s\n"
		    "%s        gap        : density=%d (%.2f%%), duration=%d%s\n"
		    "%s        delay      : round trip=%d%s, end system=%d%s\n"
		    "%s        level      : signal=%s%s, noise=%s%s, RERL=%s%s\n"
		    "%s        quality    : R factor=%s, ext R factor=%s\n"
		    "%s                     MOS LQ=%s, MOS CQ=%s\n"
		    "%s        config     : PLC=%s, JB=%s, JB rate=%s, Gmin=%d\n"
		    "%s        JB delay   : cur=%d%s, max=%d%s, abs max=%d%s",
		    indent,
		    last_update,
		    /* pakcets */
		    indent,
		    xr_stat.tx.voip_mtc.loss_rate, xr_stat.tx.voip_mtc.loss_rate*100.0/256,
		    xr_stat.tx.voip_mtc.discard_rate, xr_stat.tx.voip_mtc.discard_rate*100.0/256,
		    /* burst */
		    indent,
		    xr_stat.tx.voip_mtc.burst_den, xr_stat.tx.voip_mtc.burst_den*100.0/256,
		    xr_stat.tx.voip_mtc.burst_dur, "ms",
		    /* gap */
		    indent,
		    xr_stat.tx.voip_mtc.gap_den, xr_stat.tx.voip_mtc.gap_den*100.0/256,
		    xr_stat.tx.voip_mtc.gap_dur, "ms",
		    /* delay */
		    indent,
		    xr_stat.tx.voip_mtc.rnd_trip_delay, "ms",
		    xr_stat.tx.voip_mtc.end_sys_delay, "ms",
		    /* level */
		    indent,
		    signal_lvl, "dB",
		    noise_lvl, "dB",
		    rerl, "",
		    /* quality */
		    indent,
		    r_factor, ext_r_factor,
		    indent,
		    mos_lq, mos_cq,
		    /* config */
		    indent,
		    plc, jba, jbr, xr_stat.tx.voip_mtc.gmin,
		    /* JB delay */
		    indent,
		    xr_stat.tx.voip_mtc.jb_nom, "ms",
		    xr_stat.tx.voip_mtc.jb_max, "ms",
		    xr_stat.tx.voip_mtc.jb_abs_max, "ms"
		    );
	    VALIDATE_PRINT_BUF();


	    /* RTT delay (by receiver side) */
	    len = pj_ansi_snprintf(p, end-p,
		    "%s   RTT (from recv)      min     avg     max     last    dev",
		    indent);
	    VALIDATE_PRINT_BUF();
	    len = pj_ansi_snprintf(p, end-p,
		    "%s     RTT msec      : %7.3f %7.3f %7.3f %7.3f %7.3f",
		    indent,
		    xr_stat.rtt.min / 1000.0,
		    xr_stat.rtt.mean / 1000.0,
		    xr_stat.rtt.max / 1000.0,
		    xr_stat.rtt.last / 1000.0,
		    pj_math_stat_get_stddev(&xr_stat.rtt) / 1000.0
		   );
	    VALIDATE_PRINT_BUF();
	} /* if audio */;
#endif

    }
示例#3
0
/*
 * Print stream statistics
 */
static void print_stream_stat(pjmedia_stream *stream,
			      const pjmedia_codec_param *codec_param)
{
    char duration[80], last_update[80];
    char bps[16], ipbps[16], packets[16], bytes[16], ipbytes[16];
    pjmedia_port *port;
    pjmedia_rtcp_stat stat;
    pj_time_val now;


    pj_gettimeofday(&now);
    pjmedia_stream_get_stat(stream, &stat);
    pjmedia_stream_get_port(stream, &port);

    puts("Stream statistics:");

    /* Print duration */
    PJ_TIME_VAL_SUB(now, stat.start);
    sprintf(duration, " Duration: %02ld:%02ld:%02ld.%03ld",
	    now.sec / 3600,
	    (now.sec % 3600) / 60,
	    (now.sec % 60),
	    now.msec);


    printf(" Info: audio %dHz, %dms/frame, %sB/s (%sB/s +IP hdr)\n",
	PJMEDIA_PIA_SRATE(&port->info),
	PJMEDIA_PIA_PTIME(&port->info),
	good_number(bps, (codec_param->info.avg_bps+7)/8),
	good_number(ipbps, ((codec_param->info.avg_bps+7)/8) + 
			   (40 * 1000 /
			    codec_param->setting.frm_per_pkt /
			    codec_param->info.frm_ptime)));

    if (stat.rx.update_cnt == 0)
	strcpy(last_update, "never");
    else {
	pj_gettimeofday(&now);
	PJ_TIME_VAL_SUB(now, stat.rx.update);
	sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
		now.sec / 3600,
		(now.sec % 3600) / 60,
		now.sec % 60,
		now.msec);
    }

    printf(" RX stat last update: %s\n"
	   "    total %s packets %sB received (%sB +IP hdr)%s\n"
	   "    pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)%s\n"
	   "          (msec)    min     avg     max     last    dev\n"
	   "    loss period: %7.3f %7.3f %7.3f %7.3f %7.3f%s\n"
	   "    jitter     : %7.3f %7.3f %7.3f %7.3f %7.3f%s\n",
	   last_update,
	   good_number(packets, stat.rx.pkt),
	   good_number(bytes, stat.rx.bytes),
	   good_number(ipbytes, stat.rx.bytes + stat.rx.pkt * 32),
	   "",
	   stat.rx.loss,
	   stat.rx.loss * 100.0 / (stat.rx.pkt + stat.rx.loss),
	   stat.rx.dup, 
	   stat.rx.dup * 100.0 / (stat.rx.pkt + stat.rx.loss),
	   stat.rx.reorder, 
	   stat.rx.reorder * 100.0 / (stat.rx.pkt + stat.rx.loss),
	   "",
	   stat.rx.loss_period.min / 1000.0, 
	   stat.rx.loss_period.mean / 1000.0, 
	   stat.rx.loss_period.max / 1000.0,
	   stat.rx.loss_period.last / 1000.0,
	   pj_math_stat_get_stddev(&stat.rx.loss_period) / 1000.0,
	   "",
	   stat.rx.jitter.min / 1000.0,
	   stat.rx.jitter.mean / 1000.0,
	   stat.rx.jitter.max / 1000.0,
	   stat.rx.jitter.last / 1000.0,
	   pj_math_stat_get_stddev(&stat.rx.jitter) / 1000.0,
	   ""
	   );


    if (stat.tx.update_cnt == 0)
	strcpy(last_update, "never");
    else {
	pj_gettimeofday(&now);
	PJ_TIME_VAL_SUB(now, stat.tx.update);
	sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
		now.sec / 3600,
		(now.sec % 3600) / 60,
		now.sec % 60,
		now.msec);
    }

    printf(" TX stat last update: %s\n"
	   "    total %s packets %sB sent (%sB +IP hdr)%s\n"
	   "    pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)%s\n"
	   "          (msec)    min     avg     max     last    dev\n"
	   "    loss period: %7.3f %7.3f %7.3f %7.3f %7.3f%s\n"
	   "    jitter     : %7.3f %7.3f %7.3f %7.3f %7.3f%s\n",
	   last_update,
	   good_number(packets, stat.tx.pkt),
	   good_number(bytes, stat.tx.bytes),
	   good_number(ipbytes, stat.tx.bytes + stat.tx.pkt * 32),
	   "",
	   stat.tx.loss,
	   stat.tx.loss * 100.0 / (stat.tx.pkt + stat.tx.loss),
	   stat.tx.dup, 
	   stat.tx.dup * 100.0 / (stat.tx.pkt + stat.tx.loss),
	   stat.tx.reorder, 
	   stat.tx.reorder * 100.0 / (stat.tx.pkt + stat.tx.loss),
	   "",
	   stat.tx.loss_period.min / 1000.0, 
	   stat.tx.loss_period.mean / 1000.0, 
	   stat.tx.loss_period.max / 1000.0,
	   stat.tx.loss_period.last / 1000.0,
	   pj_math_stat_get_stddev(&stat.tx.loss_period) / 1000.0,
	   "",
	   stat.tx.jitter.min / 1000.0,
	   stat.tx.jitter.mean / 1000.0,
	   stat.tx.jitter.max / 1000.0,
	   stat.tx.jitter.last / 1000.0,
	   pj_math_stat_get_stddev(&stat.tx.jitter) / 1000.0,
	   ""
	   );


    printf(" RTT delay     : %7.3f %7.3f %7.3f %7.3f %7.3f%s\n", 
	   stat.rtt.min / 1000.0,
	   stat.rtt.mean / 1000.0,
	   stat.rtt.max / 1000.0,
	   stat.rtt.last / 1000.0,
	   pj_math_stat_get_stddev(&stat.rtt) / 1000.0,
	   ""
	   );

#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
    /* RTCP XR Reports */
    do {
	char loss[16], dup[16];
	char jitter[80];
	char toh[80];
	char plc[16], jba[16], jbr[16];
	char signal_lvl[16], noise_lvl[16], rerl[16];
	char r_factor[16], ext_r_factor[16], mos_lq[16], mos_cq[16];
	pjmedia_rtcp_xr_stat xr_stat;

	if (pjmedia_stream_get_stat_xr(stream, &xr_stat) != PJ_SUCCESS)
	    break;

	puts("\nExtended reports:");

	/* Statistics Summary */
	puts(" Statistics Summary");

	if (xr_stat.rx.stat_sum.l)
	    sprintf(loss, "%d", xr_stat.rx.stat_sum.lost);
	else
	    sprintf(loss, "(na)");

	if (xr_stat.rx.stat_sum.d)
	    sprintf(dup, "%d", xr_stat.rx.stat_sum.dup);
	else
	    sprintf(dup, "(na)");

	if (xr_stat.rx.stat_sum.j) {
	    unsigned jmin, jmax, jmean, jdev;

	    SAMPLES_TO_USEC(jmin, xr_stat.rx.stat_sum.jitter.min, 
			    port->info.fmt.det.aud.clock_rate);
	    SAMPLES_TO_USEC(jmax, xr_stat.rx.stat_sum.jitter.max, 
			    port->info.fmt.det.aud.clock_rate);
	    SAMPLES_TO_USEC(jmean, xr_stat.rx.stat_sum.jitter.mean, 
			    port->info.fmt.det.aud.clock_rate);
	    SAMPLES_TO_USEC(jdev, 
			   pj_math_stat_get_stddev(&xr_stat.rx.stat_sum.jitter),
			   port->info.fmt.det.aud.clock_rate);
	    sprintf(jitter, "%7.3f %7.3f %7.3f %7.3f", 
		    jmin/1000.0, jmean/1000.0, jmax/1000.0, jdev/1000.0);
	} else
	    sprintf(jitter, "(report not available)");

	if (xr_stat.rx.stat_sum.t) {
	    sprintf(toh, "%11d %11d %11d %11d", 
		    xr_stat.rx.stat_sum.toh.min,
		    xr_stat.rx.stat_sum.toh.mean,
		    xr_stat.rx.stat_sum.toh.max,
		    pj_math_stat_get_stddev(&xr_stat.rx.stat_sum.toh));
	} else
	    sprintf(toh, "(report not available)");

	if (xr_stat.rx.stat_sum.update.sec == 0)
	    strcpy(last_update, "never");
	else {
	    pj_gettimeofday(&now);
	    PJ_TIME_VAL_SUB(now, xr_stat.rx.stat_sum.update);
	    sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
		    now.sec / 3600,
		    (now.sec % 3600) / 60,
		    now.sec % 60,
		    now.msec);
	}

	printf(" RX last update: %s\n"
	       "    begin seq=%d, end seq=%d%s\n"
	       "    pkt loss=%s, dup=%s%s\n"
	       "          (msec)    min     avg     max     dev\n"
	       "    jitter     : %s\n"
	       "    toh        : %s\n",
	       last_update,
	       xr_stat.rx.stat_sum.begin_seq, xr_stat.rx.stat_sum.end_seq,
	       "",
	       loss, dup,
	       "",
	       jitter,
	       toh
	       );

	if (xr_stat.tx.stat_sum.l)
	    sprintf(loss, "%d", xr_stat.tx.stat_sum.lost);
	else
	    sprintf(loss, "(na)");

	if (xr_stat.tx.stat_sum.d)
	    sprintf(dup, "%d", xr_stat.tx.stat_sum.dup);
	else
	    sprintf(dup, "(na)");

	if (xr_stat.tx.stat_sum.j) {
	    unsigned jmin, jmax, jmean, jdev;

	    SAMPLES_TO_USEC(jmin, xr_stat.tx.stat_sum.jitter.min, 
			    port->info.fmt.det.aud.clock_rate);
	    SAMPLES_TO_USEC(jmax, xr_stat.tx.stat_sum.jitter.max, 
			    port->info.fmt.det.aud.clock_rate);
	    SAMPLES_TO_USEC(jmean, xr_stat.tx.stat_sum.jitter.mean, 
			    port->info.fmt.det.aud.clock_rate);
	    SAMPLES_TO_USEC(jdev, 
			   pj_math_stat_get_stddev(&xr_stat.tx.stat_sum.jitter),
			   port->info.fmt.det.aud.clock_rate);
	    sprintf(jitter, "%7.3f %7.3f %7.3f %7.3f", 
		    jmin/1000.0, jmean/1000.0, jmax/1000.0, jdev/1000.0);
	} else
	    sprintf(jitter, "(report not available)");

	if (xr_stat.tx.stat_sum.t) {
	    sprintf(toh, "%11d %11d %11d %11d", 
		    xr_stat.tx.stat_sum.toh.min,
		    xr_stat.tx.stat_sum.toh.mean,
		    xr_stat.tx.stat_sum.toh.max,
		    pj_math_stat_get_stddev(&xr_stat.rx.stat_sum.toh));
	} else
	    sprintf(toh,    "(report not available)");

	if (xr_stat.tx.stat_sum.update.sec == 0)
	    strcpy(last_update, "never");
	else {
	    pj_gettimeofday(&now);
	    PJ_TIME_VAL_SUB(now, xr_stat.tx.stat_sum.update);
	    sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
		    now.sec / 3600,
		    (now.sec % 3600) / 60,
		    now.sec % 60,
		    now.msec);
	}

	printf(" TX last update: %s\n"
	       "    begin seq=%d, end seq=%d%s\n"
	       "    pkt loss=%s, dup=%s%s\n"
	       "          (msec)    min     avg     max     dev\n"
	       "    jitter     : %s\n"
	       "    toh        : %s\n",
	       last_update,
	       xr_stat.tx.stat_sum.begin_seq, xr_stat.tx.stat_sum.end_seq,
	       "",
	       loss, dup,
	       "",
	       jitter,
	       toh
	       );

	/* VoIP Metrics */
	puts(" VoIP Metrics");

	PRINT_VOIP_MTC_VAL(signal_lvl, xr_stat.rx.voip_mtc.signal_lvl);
	PRINT_VOIP_MTC_VAL(noise_lvl, xr_stat.rx.voip_mtc.noise_lvl);
	PRINT_VOIP_MTC_VAL(rerl, xr_stat.rx.voip_mtc.rerl);
	PRINT_VOIP_MTC_VAL(r_factor, xr_stat.rx.voip_mtc.r_factor);
	PRINT_VOIP_MTC_VAL(ext_r_factor, xr_stat.rx.voip_mtc.ext_r_factor);
	PRINT_VOIP_MTC_VAL(mos_lq, xr_stat.rx.voip_mtc.mos_lq);
	PRINT_VOIP_MTC_VAL(mos_cq, xr_stat.rx.voip_mtc.mos_cq);

	switch ((xr_stat.rx.voip_mtc.rx_config>>6) & 3) {
	    case PJMEDIA_RTCP_XR_PLC_DIS:
		sprintf(plc, "DISABLED");
		break;
	    case PJMEDIA_RTCP_XR_PLC_ENH:
		sprintf(plc, "ENHANCED");
		break;
	    case PJMEDIA_RTCP_XR_PLC_STD:
		sprintf(plc, "STANDARD");
		break;
	    case PJMEDIA_RTCP_XR_PLC_UNK:
	    default:
		sprintf(plc, "UNKNOWN");
		break;
	}

	switch ((xr_stat.rx.voip_mtc.rx_config>>4) & 3) {
	    case PJMEDIA_RTCP_XR_JB_FIXED:
		sprintf(jba, "FIXED");
		break;
	    case PJMEDIA_RTCP_XR_JB_ADAPTIVE:
		sprintf(jba, "ADAPTIVE");
		break;
	    default:
		sprintf(jba, "UNKNOWN");
		break;
	}

	sprintf(jbr, "%d", xr_stat.rx.voip_mtc.rx_config & 0x0F);

	if (xr_stat.rx.voip_mtc.update.sec == 0)
	    strcpy(last_update, "never");
	else {
	    pj_gettimeofday(&now);
	    PJ_TIME_VAL_SUB(now, xr_stat.rx.voip_mtc.update);
	    sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
		    now.sec / 3600,
		    (now.sec % 3600) / 60,
		    now.sec % 60,
		    now.msec);
	}

	printf(" RX last update: %s\n"
	       "    packets    : loss rate=%d (%.2f%%), discard rate=%d (%.2f%%)\n"
	       "    burst      : density=%d (%.2f%%), duration=%d%s\n"
	       "    gap        : density=%d (%.2f%%), duration=%d%s\n"
	       "    delay      : round trip=%d%s, end system=%d%s\n"
	       "    level      : signal=%s%s, noise=%s%s, RERL=%s%s\n"
	       "    quality    : R factor=%s, ext R factor=%s\n"
	       "                 MOS LQ=%s, MOS CQ=%s\n"
	       "    config     : PLC=%s, JB=%s, JB rate=%s, Gmin=%d\n"
	       "    JB delay   : cur=%d%s, max=%d%s, abs max=%d%s\n",
	       last_update,
	       /* pakcets */
	       xr_stat.rx.voip_mtc.loss_rate, xr_stat.rx.voip_mtc.loss_rate*100.0/256,
	       xr_stat.rx.voip_mtc.discard_rate, xr_stat.rx.voip_mtc.discard_rate*100.0/256,
	       /* burst */
	       xr_stat.rx.voip_mtc.burst_den, xr_stat.rx.voip_mtc.burst_den*100.0/256,
	       xr_stat.rx.voip_mtc.burst_dur, "ms",
	       /* gap */
	       xr_stat.rx.voip_mtc.gap_den, xr_stat.rx.voip_mtc.gap_den*100.0/256,
	       xr_stat.rx.voip_mtc.gap_dur, "ms",
	       /* delay */
	       xr_stat.rx.voip_mtc.rnd_trip_delay, "ms",
	       xr_stat.rx.voip_mtc.end_sys_delay, "ms",
	       /* level */
	       signal_lvl, "dB",
	       noise_lvl, "dB",
	       rerl, "",
	       /* quality */
	       r_factor, ext_r_factor, mos_lq, mos_cq,
	       /* config */
	       plc, jba, jbr, xr_stat.rx.voip_mtc.gmin,
	       /* JB delay */
	       xr_stat.rx.voip_mtc.jb_nom, "ms",
	       xr_stat.rx.voip_mtc.jb_max, "ms",
	       xr_stat.rx.voip_mtc.jb_abs_max, "ms"
	       );

	PRINT_VOIP_MTC_VAL(signal_lvl, xr_stat.tx.voip_mtc.signal_lvl);
	PRINT_VOIP_MTC_VAL(noise_lvl, xr_stat.tx.voip_mtc.noise_lvl);
	PRINT_VOIP_MTC_VAL(rerl, xr_stat.tx.voip_mtc.rerl);
	PRINT_VOIP_MTC_VAL(r_factor, xr_stat.tx.voip_mtc.r_factor);
	PRINT_VOIP_MTC_VAL(ext_r_factor, xr_stat.tx.voip_mtc.ext_r_factor);
	PRINT_VOIP_MTC_VAL(mos_lq, xr_stat.tx.voip_mtc.mos_lq);
	PRINT_VOIP_MTC_VAL(mos_cq, xr_stat.tx.voip_mtc.mos_cq);

	switch ((xr_stat.tx.voip_mtc.rx_config>>6) & 3) {
	    case PJMEDIA_RTCP_XR_PLC_DIS:
		sprintf(plc, "DISABLED");
		break;
	    case PJMEDIA_RTCP_XR_PLC_ENH:
		sprintf(plc, "ENHANCED");
		break;
	    case PJMEDIA_RTCP_XR_PLC_STD:
		sprintf(plc, "STANDARD");
		break;
	    case PJMEDIA_RTCP_XR_PLC_UNK:
	    default:
		sprintf(plc, "unknown");
		break;
	}

	switch ((xr_stat.tx.voip_mtc.rx_config>>4) & 3) {
	    case PJMEDIA_RTCP_XR_JB_FIXED:
		sprintf(jba, "FIXED");
		break;
	    case PJMEDIA_RTCP_XR_JB_ADAPTIVE:
		sprintf(jba, "ADAPTIVE");
		break;
	    default:
		sprintf(jba, "unknown");
		break;
	}

	sprintf(jbr, "%d", xr_stat.tx.voip_mtc.rx_config & 0x0F);

	if (xr_stat.tx.voip_mtc.update.sec == 0)
	    strcpy(last_update, "never");
	else {
	    pj_gettimeofday(&now);
	    PJ_TIME_VAL_SUB(now, xr_stat.tx.voip_mtc.update);
	    sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
		    now.sec / 3600,
		    (now.sec % 3600) / 60,
		    now.sec % 60,
		    now.msec);
	}

	printf(" TX last update: %s\n"
	       "    packets    : loss rate=%d (%.2f%%), discard rate=%d (%.2f%%)\n"
	       "    burst      : density=%d (%.2f%%), duration=%d%s\n"
	       "    gap        : density=%d (%.2f%%), duration=%d%s\n"
	       "    delay      : round trip=%d%s, end system=%d%s\n"
	       "    level      : signal=%s%s, noise=%s%s, RERL=%s%s\n"
	       "    quality    : R factor=%s, ext R factor=%s\n"
	       "                 MOS LQ=%s, MOS CQ=%s\n"
	       "    config     : PLC=%s, JB=%s, JB rate=%s, Gmin=%d\n"
	       "    JB delay   : cur=%d%s, max=%d%s, abs max=%d%s\n",
	       last_update,
	       /* pakcets */
	       xr_stat.tx.voip_mtc.loss_rate, xr_stat.tx.voip_mtc.loss_rate*100.0/256,
	       xr_stat.tx.voip_mtc.discard_rate, xr_stat.tx.voip_mtc.discard_rate*100.0/256,
	       /* burst */
	       xr_stat.tx.voip_mtc.burst_den, xr_stat.tx.voip_mtc.burst_den*100.0/256,
	       xr_stat.tx.voip_mtc.burst_dur, "ms",
	       /* gap */
	       xr_stat.tx.voip_mtc.gap_den, xr_stat.tx.voip_mtc.gap_den*100.0/256,
	       xr_stat.tx.voip_mtc.gap_dur, "ms",
	       /* delay */
	       xr_stat.tx.voip_mtc.rnd_trip_delay, "ms",
	       xr_stat.tx.voip_mtc.end_sys_delay, "ms",
	       /* level */
	       signal_lvl, "dB",
	       noise_lvl, "dB",
	       rerl, "",
	       /* quality */
	       r_factor, ext_r_factor, mos_lq, mos_cq,
	       /* config */
	       plc, jba, jbr, xr_stat.tx.voip_mtc.gmin,
	       /* JB delay */
	       xr_stat.tx.voip_mtc.jb_nom, "ms",
	       xr_stat.tx.voip_mtc.jb_max, "ms",
	       xr_stat.tx.voip_mtc.jb_abs_max, "ms"
	       );


	/* RTT delay (by receiver side) */
	printf("          (msec)    min     avg     max     last    dev\n");
	printf(" RTT delay     : %7.3f %7.3f %7.3f %7.3f %7.3f%s\n", 
	       xr_stat.rtt.min / 1000.0,
	       xr_stat.rtt.mean / 1000.0,
	       xr_stat.rtt.max / 1000.0,
	       xr_stat.rtt.last / 1000.0,
	       pj_math_stat_get_stddev(&xr_stat.rtt) / 1000.0,
	       ""
	       );
    } while (0);
#endif /* PJMEDIA_HAS_RTCP_XR */

}
示例#4
0
/*
 * Print stream statistics
 */
static void print_stream_stat(pjmedia_stream *stream)
{
    char duration[80], last_update[80];
    char bps[16], ipbps[16], packets[16], bytes[16], ipbytes[16];
    pjmedia_port *port;
    pjmedia_rtcp_stat stat;
    pj_time_val now;


    pj_gettimeofday(&now);
    pjmedia_stream_get_stat(stream, &stat);
    pjmedia_stream_get_port(stream, &port);

    puts("Stream statistics:");

    /* Print duration */
    PJ_TIME_VAL_SUB(now, stat.start);
    sprintf(duration, " Duration: %02ld:%02ld:%02ld.%03ld",
	    now.sec / 3600,
	    (now.sec % 3600) / 60,
	    (now.sec % 60),
	    now.msec);


    printf(" Info: audio %.*s@%dHz, %dms/frame, %sB/s (%sB/s +IP hdr)\n",
   	(int)port->info.encoding_name.slen,
	port->info.encoding_name.ptr,
	port->info.clock_rate,
	port->info.samples_per_frame * 1000 / port->info.clock_rate,
	good_number(bps, port->info.bytes_per_frame * port->info.clock_rate /
		    port->info.samples_per_frame),
	good_number(ipbps, (port->info.bytes_per_frame+32) * 
			    port->info.clock_rate / port->info.clock_rate));

    if (stat.rx.update_cnt == 0)
	strcpy(last_update, "never");
    else {
	pj_gettimeofday(&now);
	PJ_TIME_VAL_SUB(now, stat.rx.update);
	sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
		now.sec / 3600,
		(now.sec % 3600) / 60,
		now.sec % 60,
		now.msec);
    }

    printf(" RX stat last update: %s\n"
	   "    total %s packets %sB received (%sB +IP hdr)%s\n"
	   "    pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)%s\n"
	   "          (msec)    min     avg     max     last\n"
	   "    loss period: %7.3f %7.3f %7.3f %7.3f%s\n"
	   "    jitter     : %7.3f %7.3f %7.3f %7.3f%s\n",
	   last_update,
	   good_number(packets, stat.rx.pkt),
	   good_number(bytes, stat.rx.bytes),
	   good_number(ipbytes, stat.rx.bytes + stat.rx.pkt * 32),
	   "",
	   stat.rx.loss,
	   stat.rx.loss * 100.0 / (stat.rx.pkt + stat.rx.loss),
	   stat.rx.dup, 
	   stat.rx.dup * 100.0 / (stat.rx.pkt + stat.rx.loss),
	   stat.rx.reorder, 
	   stat.rx.reorder * 100.0 / (stat.rx.pkt + stat.rx.loss),
	   "",
	   stat.rx.loss_period.min / 1000.0, 
	   stat.rx.loss_period.avg / 1000.0, 
	   stat.rx.loss_period.max / 1000.0,
	   stat.rx.loss_period.last / 1000.0,
	   "",
	   stat.rx.jitter.min / 1000.0,
	   stat.rx.jitter.avg / 1000.0,
	   stat.rx.jitter.max / 1000.0,
	   stat.rx.jitter.last / 1000.0,
	   ""
	   );


    if (stat.tx.update_cnt == 0)
	strcpy(last_update, "never");
    else {
	pj_gettimeofday(&now);
	PJ_TIME_VAL_SUB(now, stat.tx.update);
	sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
		now.sec / 3600,
		(now.sec % 3600) / 60,
		now.sec % 60,
		now.msec);
    }

    printf(" TX stat last update: %s\n"
	   "    total %s packets %sB sent (%sB +IP hdr)%s\n"
	   "    pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)%s\n"
	   "          (msec)    min     avg     max     last\n"
	   "    loss period: %7.3f %7.3f %7.3f %7.3f%s\n"
	   "    jitter     : %7.3f %7.3f %7.3f %7.3f%s\n",
	   last_update,
	   good_number(packets, stat.tx.pkt),
	   good_number(bytes, stat.tx.bytes),
	   good_number(ipbytes, stat.tx.bytes + stat.tx.pkt * 32),
	   "",
	   stat.tx.loss,
	   stat.tx.loss * 100.0 / (stat.tx.pkt + stat.tx.loss),
	   stat.tx.dup, 
	   stat.tx.dup * 100.0 / (stat.tx.pkt + stat.tx.loss),
	   stat.tx.reorder, 
	   stat.tx.reorder * 100.0 / (stat.tx.pkt + stat.tx.loss),
	   "",
	   stat.tx.loss_period.min / 1000.0, 
	   stat.tx.loss_period.avg / 1000.0, 
	   stat.tx.loss_period.max / 1000.0,
	   stat.tx.loss_period.last / 1000.0,
	   "",
	   stat.tx.jitter.min / 1000.0,
	   stat.tx.jitter.avg / 1000.0,
	   stat.tx.jitter.max / 1000.0,
	   stat.tx.jitter.last / 1000.0,
	   ""
	   );


    printf(" RTT delay     : %7.3f %7.3f %7.3f %7.3f%s\n", 
	   stat.rtt.min / 1000.0,
	   stat.rtt.avg / 1000.0,
	   stat.rtt.max / 1000.0,
	   stat.rtt.last / 1000.0,
	   ""
	   );

}
示例#5
0
/* This is the RX "tick".
 * This function is called periodically every "tick" milliseconds, and
 * it will determine whether to call get_frame() from the RX stream.
 */
static void rx_tick(const pj_time_val *t)
{
    struct stream *strm = g_app.rx;
    pjmedia_port *port = g_app.rx->port;
    long pkt_interval;

    pkt_interval = PJMEDIA_PIA_SPF(&port->info) * 1000 /
		   PJMEDIA_PIA_SRATE(&port->info) *
		   g_app.cfg.rx_snd_burst;

    if (PJ_TIME_VAL_GTE(*t, strm->state.rx.next_schedule)) {
	unsigned i;
	for (i=0; i<g_app.cfg.rx_snd_burst; ++i) {
	    struct log_entry entry;
	    pjmedia_rtcp_stat stat;
	    pjmedia_jb_state jstate;
	    pj_bool_t has_frame;
	    char msg[120];
	    unsigned last_empty;

	    pjmedia_stream_get_stat(g_app.rx->strm, &stat);
	    pjmedia_stream_get_stat_jbuf(g_app.rx->strm, &jstate);
	    last_empty = jstate.empty;

	    /* Pre GET event */
	    pj_bzero(&entry, sizeof(entry));
	    entry.event = EVENT_GET_PRE;
	    entry.wall_clock = *t;
	    entry.stat = &stat;
	    entry.jb_state = &jstate;

	    write_log(&entry, PJ_TRUE);

	    /* GET */
	    run_one_frame(g_app.rx->port, g_app.rx_wav, &has_frame);

	    /* Post GET event */
	    pjmedia_stream_get_stat(g_app.rx->strm, &stat);
	    pjmedia_stream_get_stat_jbuf(g_app.rx->strm, &jstate);

	    pj_bzero(&entry, sizeof(entry));
	    entry.event = EVENT_GET_POST;
	    entry.wall_clock = *t;
	    entry.stat = &stat;
	    entry.jb_state = &jstate;

	    msg[0] = '\0';
	    entry.log = msg;

	    if (jstate.empty > last_empty)
		strcat(msg, "** JBUF was empty **");
	    if (!has_frame)
		strcat(msg, "** NULL frame was returned **");

	    write_log(&entry, PJ_TRUE);

	}


	strm->state.rx.next_schedule.msec += pkt_interval;
	pj_time_val_normalize(&strm->state.rx.next_schedule);
    }
	    
}
示例#6
0
/* This is the transmission "tick".
 * This function is called periodically every "tick" milliseconds, and
 * it will determine whether to transmit packet(s) (or to drop it).
 */
static void tx_tick(const pj_time_val *t)
{
    struct stream *strm = g_app.tx;
    static char log_msg[120];
    pjmedia_port *port = g_app.tx->port;
    long pkt_interval; 

    /* packet interval, without jitter */
    pkt_interval = PJMEDIA_PIA_SPF(&port->info) * 1000 /
		   PJMEDIA_PIA_SRATE(&port->info);

    while (PJ_TIME_VAL_GTE(*t, strm->state.tx.next_schedule)) {
	struct log_entry entry;
	pj_bool_t drop_this_pkt = PJ_FALSE;
	int jitter;

	/* Init log entry */
	pj_bzero(&entry, sizeof(entry));
	entry.wall_clock = *t;

	/* 
	 * Determine whether to drop this packet 
	 */
	if (strm->state.tx.cur_lost_burst) {
	    /* We are currently dropping packet */

	    /* Make it comply to minimum lost burst */
	    if (strm->state.tx.cur_lost_burst < g_app.cfg.tx_min_lost_burst) {
		drop_this_pkt = PJ_TRUE;
	    }

	    /* Correlate the next packet loss */
	    if (!drop_this_pkt && 
		strm->state.tx.cur_lost_burst < g_app.cfg.tx_max_lost_burst &&
		MAX(strm->state.tx.total_lost-LOSS_EXTRA,0) * 100 / MAX(strm->state.tx.total_tx,1) < g_app.cfg.tx_pct_avg_lost
	       ) 
	    {
		strm->state.tx.drop_prob = ((g_app.cfg.tx_pct_loss_corr * strm->state.tx.drop_prob) +
					     ((100-g_app.cfg.tx_pct_loss_corr) * (pj_rand()%100))
					   ) / 100;
		if (strm->state.tx.drop_prob >= 100)
		    strm->state.tx.drop_prob = 99;

		if (strm->state.tx.drop_prob >= 100 - g_app.cfg.tx_pct_avg_lost)
		    drop_this_pkt = PJ_TRUE;
	    }
	}

	/* If we're not dropping packet then use randomly distributed loss */
	if (!drop_this_pkt &&
	    MAX(strm->state.tx.total_lost-LOSS_EXTRA,0) * 100 / MAX(strm->state.tx.total_tx,1) < g_app.cfg.tx_pct_avg_lost)
	{
	    strm->state.tx.drop_prob = pj_rand() % 100;

	    if (strm->state.tx.drop_prob >= 100 - g_app.cfg.tx_pct_avg_lost)
		drop_this_pkt = PJ_TRUE;
	}

	if (drop_this_pkt) {
	    /* Drop the frame */
	    pjmedia_transport_simulate_lost(g_app.loop, PJMEDIA_DIR_ENCODING, 100);
	    run_one_frame(g_app.tx_wav, g_app.tx->port, NULL);
	    pjmedia_transport_simulate_lost(g_app.loop, PJMEDIA_DIR_ENCODING, 0);

	    entry.event = EVENT_TX_DROP;
	    entry.log = "** This packet was lost **";

	    ++strm->state.tx.total_lost;
	    ++strm->state.tx.cur_lost_burst;

	} else {
	    pjmedia_rtcp_stat stat;
	    pjmedia_jb_state jstate;
	    unsigned last_discard;

	    pjmedia_stream_get_stat_jbuf(g_app.rx->strm, &jstate);
	    last_discard = jstate.discard;

	    run_one_frame(g_app.tx_wav, g_app.tx->port, NULL);

	    pjmedia_stream_get_stat(g_app.rx->strm, &stat);
	    pjmedia_stream_get_stat_jbuf(g_app.rx->strm, &jstate);

	    entry.event = EVENT_TX;
	    entry.jb_state = &jstate;
	    entry.stat = &stat;
	    entry.log = log_msg;

	    if (jstate.discard > last_discard)
		strcat(log_msg, "** Note: packet was discarded by jitter buffer **");

	    strm->state.tx.cur_lost_burst = 0;
	}

	write_log(&entry, PJ_TRUE);

	++strm->state.tx.total_tx;

	/* Calculate next schedule */
	strm->state.tx.next_schedule.sec = 0;
	strm->state.tx.next_schedule.msec = (strm->state.tx.total_tx + 1) * pkt_interval;

	/* Apply jitter */
	if (g_app.cfg.tx_max_jitter || g_app.cfg.tx_min_jitter) {

	    if (g_app.cfg.tx_max_jitter == g_app.cfg.tx_min_jitter) {
		/* Fixed jitter */
		switch (pj_rand() % 3) {
		case 0:
		    jitter = 0 - g_app.cfg.tx_min_jitter;
		    break;
		case 2:
		    jitter = g_app.cfg.tx_min_jitter;
		    break;
		default:
		    jitter = 0;
		    break;
		}
	    } else {
		int jitter_range;
		jitter_range = (g_app.cfg.tx_max_jitter-g_app.cfg.tx_min_jitter)*2;
		jitter = pj_rand() % jitter_range;
		if (jitter < jitter_range/2) {
		    jitter = 0 - g_app.cfg.tx_min_jitter - (jitter/2);
		} else {
		    jitter = g_app.cfg.tx_min_jitter + (jitter/2);
		}
	    }

	} else {
	    jitter = 0;
	}

	pj_time_val_normalize(&strm->state.tx.next_schedule);

	sprintf(log_msg, "** Packet #%u tick is at %d.%03d, %d ms jitter applied **", 
		strm->state.tx.total_tx+1,
		(int)strm->state.tx.next_schedule.sec, (int)strm->state.tx.next_schedule.msec,
		jitter);

	strm->state.tx.next_schedule.msec += jitter;
	pj_time_val_normalize(&strm->state.tx.next_schedule);

    } /* while */
}
示例#7
-1
int dummy_function()
{
    pj_caching_pool cp;
 
    sprintf(NULL, "%d", 0);
    rand();
    
#ifdef HAS_PJLIB
    pj_init();
    pj_caching_pool_init(&cp, NULL, 0);
    pj_array_erase(NULL, 0, 0, 0);
    pj_create_unique_string(NULL, NULL);
    pj_hash_create(NULL, 0);
    pj_hash_get(NULL, NULL, 0, NULL);
    pj_hash_set(NULL, NULL, NULL, 0, 0, NULL);
    pj_ioqueue_create(NULL, 0, NULL);
    pj_ioqueue_register_sock(NULL, NULL, 0, NULL, NULL, NULL);
    pj_pool_alloc(NULL, 0);
    pj_timer_heap_create(NULL, 0, NULL);
#endif

#ifdef HAS_PJLIB_STUN
    pjstun_get_mapped_addr(&cp.factory, 0, NULL, NULL, 80, NULL, 80, NULL);
#endif

#ifdef HAS_PJLIB_GETOPT
    pj_getopt_long(0, NULL, NULL, NULL, NULL);
#endif
    
#ifdef HAS_PJLIB_XML
    pj_xml_parse(NULL, NULL, 100);
    pj_xml_print(NULL, NULL, 10, PJ_FALSE);
    pj_xml_clone(NULL, NULL);
    pj_xml_node_new(NULL, NULL);
    pj_xml_attr_new(NULL, NULL, NULL);
    pj_xml_add_node(NULL, NULL);
    pj_xml_add_attr(NULL, NULL);
    pj_xml_find_node(NULL, NULL);
    pj_xml_find_next_node(NULL, NULL, NULL);
    pj_xml_find_attr(NULL, NULL, NULL);
    pj_xml_find(NULL, NULL, NULL, NULL);
#endif

#ifdef HAS_PJLIB_SCANNER
    pj_cis_buf_init(NULL);
    pj_cis_init(NULL, NULL);
    pj_cis_dup(NULL, NULL);
    pj_cis_add_alpha(NULL);
    pj_cis_add_str(NULL, NULL);

    pj_scan_init(NULL, NULL, 0, 0, NULL);
    pj_scan_fini(NULL);
    pj_scan_peek(NULL, NULL, NULL);
    pj_scan_peek_n(NULL, 0, NULL);
    pj_scan_peek_until(NULL, NULL, NULL);
    pj_scan_get(NULL, NULL, NULL);
    pj_scan_get_unescape(NULL, NULL, NULL);
    pj_scan_get_quote(NULL, 0, 0, NULL);
    pj_scan_get_n(NULL, 0, NULL);
    pj_scan_get_char(NULL);
    pj_scan_get_until(NULL, NULL, NULL);
    pj_scan_strcmp(NULL, NULL, 0);
    pj_scan_stricmp(NULL, NULL, 0);
    pj_scan_stricmp_alnum(NULL, NULL, 0);
    pj_scan_get_newline(NULL);
    pj_scan_restore_state(NULL, NULL);
#endif

#ifdef HAS_PJLIB_DNS
    pj_dns_make_query(NULL, NULL, 0, 0, NULL);
    pj_dns_parse_packet(NULL, NULL, 0, NULL);
    pj_dns_packet_dup(NULL, NULL, 0, NULL);
#endif

#ifdef HAS_PJLIB_RESOLVER
    pj_dns_resolver_create(NULL, NULL, 0, NULL, NULL, NULL);
    pj_dns_resolver_set_ns(NULL, 0, NULL, NULL);
    pj_dns_resolver_handle_events(NULL, NULL);
    pj_dns_resolver_destroy(NULL, 0);
    pj_dns_resolver_start_query(NULL, NULL, 0, 0, NULL, NULL, NULL);
    pj_dns_resolver_cancel_query(NULL, 0);
    pj_dns_resolver_add_entry(NULL, NULL, 0);
#endif

#ifdef HAS_PJLIB_SRV_RESOLVER
    pj_dns_srv_resolve(NULL, NULL, 0, NULL, NULL, PJ_FALSE, NULL, NULL);
#endif

#ifdef HAS_PJLIB_CRC32
    pj_crc32_init(NULL);
    pj_crc32_update(NULL, NULL, 0);
    pj_crc32_final(NULL);
#endif

#ifdef HAS_PJLIB_HMAC_MD5
    pj_hmac_md5(NULL, 0, NULL, 0, NULL);
#endif

#ifdef HAS_PJLIB_HMAC_SHA1
    pj_hmac_sha1(NULL, 0, NULL, 0, NULL);
#endif

#ifdef HAS_PJNATH_STUN
    pj_stun_session_create(NULL, NULL, NULL, PJ_FALSE, NULL);
    pj_stun_session_destroy(NULL);
    pj_stun_session_set_credential(NULL, NULL);
    pj_stun_session_create_req(NULL, 0, NULL, NULL);
    pj_stun_session_create_ind(NULL, 0, NULL);
    pj_stun_session_create_res(NULL, NULL, 0, NULL, NULL);
    pj_stun_session_send_msg(NULL, PJ_FALSE, NULL, 0, NULL);
#endif

#ifdef HAS_PJNATH_ICE
    pj_ice_strans_create(NULL, NULL, 0, NULL, NULL, NULL);
    pj_ice_strans_set_stun_domain(NULL, NULL, NULL);
    pj_ice_strans_create_comp(NULL, 0, 0, NULL);
    pj_ice_strans_add_cand(NULL, 0, PJ_ICE_CAND_TYPE_HOST, 0, NULL, PJ_FALSE);
    pj_ice_strans_init_ice(NULL, PJ_ICE_SESS_ROLE_CONTROLLED, NULL, NULL);
    pj_ice_strans_start_ice(NULL, NULL, NULL, 0, NULL);
    pj_ice_strans_stop_ice(NULL);
    pj_ice_strans_sendto(NULL, 0, NULL, 0, NULL, 0);
#endif

#ifdef HAS_PJSIP_CORE_MSG_ELEM
    /* Parameter container */
    pjsip_param_find(NULL, NULL);
    pjsip_param_print_on(NULL, NULL, 0, NULL, NULL, 0);

    /* SIP URI */
    pjsip_sip_uri_create(NULL, 0);
    pjsip_name_addr_create(NULL);

    /* TEL URI */
    pjsip_tel_uri_create(NULL);

    /* Message and headers */
    pjsip_msg_create(NULL, PJSIP_REQUEST_MSG);
    pjsip_msg_print(NULL, NULL, 0);
    pjsip_accept_hdr_create(NULL);
    pjsip_allow_hdr_create(NULL);
    pjsip_cid_hdr_create(NULL);
    pjsip_clen_hdr_create(NULL);
    pjsip_cseq_hdr_create(NULL);
    pjsip_contact_hdr_create(NULL);
    pjsip_ctype_hdr_create(NULL);
    pjsip_expires_hdr_create(NULL, 0);
    pjsip_from_hdr_create(NULL);
    pjsip_max_fwd_hdr_create(NULL, 0);
    pjsip_min_expires_hdr_create(NULL, 0);
    pjsip_rr_hdr_create(NULL);
    pjsip_require_hdr_create(NULL);
    pjsip_retry_after_hdr_create(NULL, 0);
    pjsip_supported_hdr_create(NULL);
    pjsip_unsupported_hdr_create(NULL);
    pjsip_via_hdr_create(NULL);
    pjsip_warning_hdr_create(NULL, 0, NULL, NULL);

    pjsip_parse_uri(NULL, NULL, 0, 0);
    pjsip_parse_msg(NULL, NULL, 0, NULL);
    pjsip_parse_rdata(NULL, 0, NULL);
    pjsip_find_msg(NULL, 0, 0, NULL);
#endif

#ifdef HAS_PJSIP_CORE
    pjsip_endpt_create(NULL, NULL, NULL);

    pjsip_tpmgr_create(NULL, NULL, NULL, NULL, NULL);
    pjsip_tpmgr_destroy(NULL);
    pjsip_transport_send(NULL, NULL, NULL, 0, NULL, NULL);


#endif

#ifdef HAS_PJSIP_CORE_MSG_UTIL
    pjsip_endpt_create_request(NULL, NULL, NULL, NULL, NULL, NULL, NULL,
			       -1, NULL, NULL);
    pjsip_endpt_create_request_from_hdr(NULL, NULL, NULL, NULL, NULL, NULL,
					NULL, -1, NULL, NULL);
    pjsip_endpt_create_response(NULL, NULL, -1, NULL, NULL);
    pjsip_endpt_create_ack(NULL, NULL, NULL, NULL);
    pjsip_endpt_create_cancel(NULL, NULL, NULL);
    pjsip_get_request_dest(NULL, NULL);
    pjsip_endpt_send_request_stateless(NULL, NULL, NULL, NULL);
    pjsip_get_response_addr(NULL, NULL, NULL);
    pjsip_endpt_send_response(NULL, NULL, NULL, NULL, NULL);
    pjsip_endpt_respond_stateless(NULL, NULL, -1, NULL, NULL, NULL);
#endif

#ifdef HAS_PJSIP_UDP_TRANSPORT
    pjsip_udp_transport_start(NULL, NULL, NULL, 1, NULL);
#endif

#ifdef HAS_PJSIP_TCP_TRANSPORT
    pjsip_tcp_transport_start(NULL, NULL, 1, NULL);
#endif

#ifdef HAS_PJSIP_TLS_TRANSPORT
    pjsip_tls_transport_start(NULL, NULL, NULL, NULL, 0, NULL);
#endif

#ifdef HAS_PJSIP_TRANSACTION
    pjsip_tsx_layer_init_module(NULL);

    pjsip_tsx_layer_destroy();
    pjsip_tsx_create_uac(NULL, NULL, NULL);
    pjsip_tsx_create_uas(NULL, NULL, NULL);
    pjsip_tsx_recv_msg(NULL, NULL);
    pjsip_tsx_send_msg(NULL, NULL);
    pjsip_tsx_terminate(NULL, 200);

    pjsip_endpt_send_request(NULL, NULL, -1, NULL, NULL);
    pjsip_endpt_respond(NULL, NULL, NULL, -1, NULL, NULL, NULL, NULL);
#endif

#ifdef HAS_PJMEDIA_SDP
    pjmedia_sdp_parse(NULL, NULL, 1024, NULL);
    pjmedia_sdp_print(NULL, NULL, 1024);
    pjmedia_sdp_validate(NULL);
    pjmedia_sdp_session_clone(NULL, NULL);
    pjmedia_sdp_session_cmp(NULL, NULL, 0);
    pjmedia_sdp_attr_to_rtpmap(NULL, NULL, NULL);
    pjmedia_sdp_attr_get_fmtp(NULL, NULL);
    pjmedia_sdp_attr_get_rtcp(NULL, NULL);
    pjmedia_sdp_conn_clone(NULL, NULL);
    pjmedia_sdp_media_clone(NULL, NULL);
    pjmedia_sdp_media_find_attr(NULL, NULL, NULL);
#endif

#ifdef HAS_PJMEDIA_SDP_NEGOTIATOR
    pjmedia_sdp_neg_create_w_local_offer(NULL, NULL, NULL);
    pjmedia_sdp_neg_create_w_remote_offer(NULL, NULL, NULL, NULL);
    pjmedia_sdp_neg_get_state(NULL);
    pjmedia_sdp_neg_negotiate(NULL, NULL, PJ_FALSE);
#endif

#ifdef HAS_PJSIP_UA_LAYER
    pjsip_ua_init_module(NULL, NULL);
    pjsip_ua_destroy();
    pjsip_dlg_create_uac(NULL, NULL, NULL, NULL, NULL, NULL);
    pjsip_dlg_create_uas_and_inc_lock(NULL, NULL, NULL, NULL);
    pjsip_dlg_terminate(NULL);
    pjsip_dlg_set_route_set(NULL, NULL);
    pjsip_dlg_create_request(NULL, NULL, -1, NULL);
    pjsip_dlg_send_request(NULL, NULL, -1, NULL);
    pjsip_dlg_create_response(NULL, NULL, -1, NULL, NULL);
    pjsip_dlg_modify_response(NULL, NULL, -1, NULL);
    pjsip_dlg_send_response(NULL, NULL, NULL);
    pjsip_dlg_respond(NULL, NULL, -1, NULL, NULL, NULL);
#endif

#ifdef HAS_PJSIP_AUTH_CLIENT
    pjsip_auth_clt_init(NULL, NULL, NULL, 0);
    pjsip_auth_clt_clone(NULL, NULL, NULL);
    pjsip_auth_clt_set_credentials(NULL, 0, NULL);
    pjsip_auth_clt_init_req(NULL, NULL);
    pjsip_auth_clt_reinit_req(NULL, NULL, NULL, NULL);
#endif

#ifdef HAS_PJSIP_INV_SESSION
    pjsip_inv_usage_init(NULL, NULL);
    pjsip_inv_create_uac(NULL, NULL, 0, NULL);
    pjsip_inv_verify_request(NULL, NULL, NULL, NULL, NULL, NULL);
    pjsip_inv_create_uas(NULL, NULL, NULL, 0, NULL);
    pjsip_inv_terminate(NULL, 200, PJ_FALSE);
    pjsip_inv_invite(NULL, NULL);
    pjsip_inv_initial_answer(NULL, NULL, 200, NULL, NULL, NULL);
    pjsip_inv_answer(NULL, 200, NULL, NULL, NULL);
    pjsip_inv_end_session(NULL, 200, NULL, NULL);
    pjsip_inv_reinvite(NULL, NULL, NULL, NULL);
    pjsip_inv_update(NULL, NULL, NULL, NULL);
    pjsip_inv_send_msg(NULL, NULL);
    pjsip_dlg_get_inv_session(NULL);
    //pjsip_tsx_get_inv_session(NULL);
    pjsip_inv_state_name(PJSIP_INV_STATE_NULL);
#endif

#ifdef HAS_PJSIP_REGC
    //pjsip_regc_get_module();
    pjsip_regc_create(NULL, NULL, NULL, NULL);
    pjsip_regc_destroy(NULL);
    pjsip_regc_get_info(NULL, NULL);
    pjsip_regc_get_pool(NULL);
    pjsip_regc_init(NULL, NULL, NULL, NULL, 0, NULL, 600);
    pjsip_regc_set_credentials(NULL, 1, NULL);
    pjsip_regc_set_route_set(NULL, NULL);
    pjsip_regc_register(NULL, PJ_TRUE, NULL);
    pjsip_regc_unregister(NULL, NULL);
    pjsip_regc_update_contact(NULL, 10, NULL);
    pjsip_regc_update_expires(NULL, 600);
    pjsip_regc_send(NULL, NULL);
#endif

#ifdef HAS_PJSIP_EVENT_FRAMEWORK
    pjsip_evsub_init_module(NULL);
    pjsip_evsub_instance();
    pjsip_evsub_register_pkg(NULL, NULL, 30, 10, NULL);
    pjsip_evsub_create_uac(NULL, NULL, NULL, 10, NULL);
    pjsip_evsub_create_uas(NULL, NULL, NULL, 10, NULL);
    pjsip_evsub_terminate(NULL, PJ_FALSE);
    pjsip_evsub_get_state(NULL);
    pjsip_evsub_get_state_name(NULL);
    pjsip_evsub_initiate(NULL, NULL, -1, NULL);
    pjsip_evsub_accept(NULL, NULL, 200, NULL);
    pjsip_evsub_notify(NULL, PJSIP_EVSUB_STATE_ACTIVE, NULL, NULL, NULL);
    pjsip_evsub_current_notify(NULL, NULL);
    pjsip_evsub_send_request(NULL, NULL);
    pjsip_tsx_get_evsub(NULL);
    pjsip_evsub_set_mod_data(NULL, 1, NULL);
    pjsip_evsub_get_mod_data(NULL, 1);
#endif

#ifdef HAS_PJSIP_CALL_TRANSFER
    pjsip_xfer_init_module(NULL);
    pjsip_xfer_create_uac(NULL, NULL, NULL);
    pjsip_xfer_create_uas(NULL, NULL, NULL, NULL);
    pjsip_xfer_initiate(NULL, NULL, NULL);
    pjsip_xfer_accept(NULL, NULL, 200, NULL);
    pjsip_xfer_notify(NULL, PJSIP_EVSUB_STATE_ACTIVE, 200, NULL, NULL);
    pjsip_xfer_current_notify(NULL, NULL);
    pjsip_xfer_send_request(NULL, NULL);
#endif

#ifdef HAS_PJSIP_PRESENCE
    pjsip_pres_init_module(NULL, NULL);
    pjsip_pres_instance();
    pjsip_pres_create_uac(NULL, NULL, 0, NULL);
    pjsip_pres_create_uas(NULL, NULL, NULL, NULL);
    pjsip_pres_terminate(NULL, PJ_FALSE);
    pjsip_pres_initiate(NULL, 100, NULL);
    pjsip_pres_accept(NULL, NULL, 200, NULL);
    pjsip_pres_notify(NULL, PJSIP_EVSUB_STATE_ACTIVE, NULL, NULL, NULL);
    pjsip_pres_current_notify(NULL, NULL);
    pjsip_pres_send_request(NULL, NULL);
    pjsip_pres_get_status(NULL, NULL);
    pjsip_pres_set_status(NULL, NULL);
#endif

#ifdef HAS_PJSIP_IS_COMPOSING
    pjsip_iscomposing_create_xml(NULL, PJ_TRUE, NULL, NULL, 0);
    pjsip_iscomposing_create_body(NULL, PJ_TRUE, NULL, NULL, 0);
    pjsip_iscomposing_parse(NULL, NULL, 0, NULL, NULL, NULL, NULL);
#endif

#ifdef HAS_PJMEDIA
    pjmedia_endpt_create(NULL, NULL, 1, NULL);
    pjmedia_endpt_destroy(NULL);
    pjmedia_endpt_create_sdp(NULL, NULL, 1, NULL, NULL);
#endif

#ifdef HAS_PJMEDIA_EC
    pjmedia_echo_create(NULL, 0, 0, 0, 0, 0, NULL);
    pjmedia_echo_destroy(NULL);
    pjmedia_echo_playback(NULL, NULL);
    pjmedia_echo_capture(NULL, NULL, 0);
    pjmedia_echo_cancel(NULL, NULL, NULL, 0, NULL);
#endif

#ifdef HAS_PJMEDIA_SND_DEV
    pjmedia_snd_init(NULL);
    pjmedia_snd_get_dev_count();
    pjmedia_snd_get_dev_info(0);
    pjmedia_snd_open(-1, -1, 8000, 1, 80, 16, NULL, NULL, NULL, NULL);
    pjmedia_snd_open_rec(-1, 8000, 1, 160, 16, NULL, NULL, NULL);
    pjmedia_snd_open_player(-1, 8000, 1, 160, 16, NULL, NULL, NULL);
    pjmedia_snd_stream_start(NULL);
    pjmedia_snd_stream_stop(NULL);
    pjmedia_snd_stream_close(NULL);
    pjmedia_snd_deinit();
#endif

#ifdef HAS_PJMEDIA_SND_PORT
    pjmedia_snd_port_create(NULL, -1, -1, 8000, 1, 180, 16, 0, NULL);
    pjmedia_snd_port_create_rec(NULL, -1, 8000, 1, 160, 16, 0, NULL);
    pjmedia_snd_port_create_player(NULL, -1, 8000, 1, 160, 16, 0, NULL);
    pjmedia_snd_port_destroy(NULL);
    pjmedia_snd_port_get_snd_stream(NULL);
    pjmedia_snd_port_connect(NULL, NULL);
    pjmedia_snd_port_get_port(NULL);
    pjmedia_snd_port_disconnect(NULL);
#endif

#ifdef HAS_PJMEDIA_RESAMPLE
    pjmedia_resample_create(NULL, PJ_TRUE, PJ_TRUE, 0, 0, 0, 0, NULL);
    pjmedia_resample_run(NULL, NULL, NULL);
#endif

#ifdef HAS_PJMEDIA_SILENCE_DET
    pjmedia_silence_det_create(NULL, 8000, 80, NULL);
    pjmedia_silence_det_detect(NULL, NULL, 0, NULL);
    pjmedia_silence_det_apply(NULL, 0);
#endif

#ifdef HAS_PJMEDIA_PLC
    pjmedia_plc_create(NULL, 8000, 80, 0, NULL);
    pjmedia_plc_save(NULL, NULL);
    pjmedia_plc_generate(NULL, NULL);
#endif

#ifdef HAS_PJMEDIA_CONFERENCE
    pjmedia_conf_create(NULL, 10, 8000, 1, 160, 16, 0, NULL);
    pjmedia_conf_destroy(NULL);
    pjmedia_conf_get_master_port(NULL);
    pjmedia_conf_add_port(NULL, NULL, NULL, NULL, NULL);
    pjmedia_conf_configure_port(NULL, 1, 0, 0);
    pjmedia_conf_connect_port(NULL, 0, 0, 0);
    pjmedia_conf_disconnect_port(NULL, 0, 0);
    pjmedia_conf_remove_port(NULL, 0);
    pjmedia_conf_enum_ports(NULL, NULL, NULL);
    pjmedia_conf_get_port_info(NULL, 0, NULL);
    pjmedia_conf_get_ports_info(NULL, NULL, NULL);
    pjmedia_conf_get_signal_level(NULL, 0, NULL, NULL);
    pjmedia_conf_adjust_rx_level(NULL, 0, 0);
    pjmedia_conf_adjust_tx_level(NULL, 0, 0);
#endif

#ifdef HAS_PJMEDIA_MASTER_PORT
    pjmedia_master_port_create(NULL, NULL, NULL, 0, NULL);
    pjmedia_master_port_start(NULL);
    pjmedia_master_port_stop(NULL);
    pjmedia_master_port_set_uport(NULL, NULL);
    pjmedia_master_port_get_uport(NULL);
    pjmedia_master_port_set_dport(NULL, NULL);
    pjmedia_master_port_get_dport(NULL);
    pjmedia_master_port_destroy(NULL, PJ_FALSE);
#endif

#ifdef HAS_PJMEDIA_RTP
    pjmedia_rtp_session_init(NULL, 0, 0);
    pjmedia_rtp_encode_rtp(NULL, 0, 0, 0, 0, NULL, NULL);
    pjmedia_rtp_decode_rtp(NULL, NULL, 0, NULL, NULL, NULL);
    pjmedia_rtp_session_update(NULL, NULL, NULL);
#endif

#ifdef HAS_PJMEDIA_RTCP
    pjmedia_rtcp_init(NULL, NULL, 0, 0, 0);
    pjmedia_rtcp_get_ntp_time(NULL, NULL);
    pjmedia_rtcp_fini(NULL);
    pjmedia_rtcp_rx_rtp(NULL, 0, 0, 0);
    pjmedia_rtcp_tx_rtp(NULL, 0);
    pjmedia_rtcp_rx_rtcp(NULL, NULL, 0);
    pjmedia_rtcp_build_rtcp(NULL, NULL, NULL);
#endif

#ifdef HAS_PJMEDIA_JBUF
    pjmedia_jbuf_create(NULL, NULL, 0, 0, 0, NULL);
    pjmedia_jbuf_set_fixed(NULL, 0);
    pjmedia_jbuf_set_adaptive(NULL, 0, 0, 0);
    pjmedia_jbuf_destroy(NULL);
    pjmedia_jbuf_put_frame(NULL, NULL, 0, 0);
    pjmedia_jbuf_get_frame(NULL, NULL, NULL);
#endif

#ifdef HAS_PJMEDIA_STREAM
    pjmedia_stream_create(NULL, NULL, NULL, NULL, NULL, NULL);
    pjmedia_stream_destroy(NULL);
    pjmedia_stream_get_port(NULL, NULL);
    pjmedia_stream_get_transport(NULL);
    pjmedia_stream_start(NULL);
    pjmedia_stream_get_stat(NULL, NULL);
    pjmedia_stream_pause(NULL, PJMEDIA_DIR_ENCODING);
    pjmedia_stream_resume(NULL, PJMEDIA_DIR_ENCODING);
    pjmedia_stream_dial_dtmf(NULL, NULL);
    pjmedia_stream_check_dtmf(NULL);
    pjmedia_stream_get_dtmf(NULL, NULL, NULL);
#endif

#ifdef HAS_PJMEDIA_TONEGEN
    pjmedia_tonegen_create(NULL, 0, 0, 0, 0, 0, NULL);
    pjmedia_tonegen_is_busy(NULL);
    pjmedia_tonegen_stop(NULL);
    pjmedia_tonegen_play(NULL, 0, NULL, 0);
    pjmedia_tonegen_play_digits(NULL, 0, NULL, 0);
    pjmedia_tonegen_get_digit_map(NULL, NULL);
    pjmedia_tonegen_set_digit_map(NULL, NULL);
#endif

#ifdef HAS_PJMEDIA_UDP_TRANSPORT
    pjmedia_transport_udp_create(NULL, NULL, 0, 0, NULL);
    pjmedia_transport_udp_close(NULL);
#endif

#ifdef HAS_PJMEDIA_FILE_PLAYER
    pjmedia_wav_player_port_create(NULL, NULL, 0, 0, 0, NULL);
    pjmedia_wav_player_port_set_pos(NULL, 0);
    pjmedia_wav_player_port_get_pos(NULL);
    pjmedia_wav_player_set_eof_cb(NULL, NULL, NULL);
#endif

#ifdef HAS_PJMEDIA_FILE_CAPTURE
    pjmedia_wav_writer_port_create(NULL, NULL, 8000, 1, 80, 16, 0, 0, NULL);
    pjmedia_wav_writer_port_get_pos(NULL);
    pjmedia_wav_writer_port_set_cb(NULL, 0, NULL, NULL);
#endif

#ifdef HAS_PJMEDIA_MEM_PLAYER
    pjmedia_mem_player_create(NULL, NULL, 1000, 8000, 1, 80, 16, 0, NULL);
#endif

#ifdef HAS_PJMEDIA_MEM_CAPTURE
    pjmedia_mem_capture_create(NULL, NULL, 1000, 8000, 1, 80, 16, 0, NULL);
#endif

#ifdef HAS_PJMEDIA_ICE
    pjmedia_ice_create(NULL, NULL, 0, NULL, NULL);
    pjmedia_ice_destroy(NULL);
    pjmedia_ice_start_init(NULL, 0, NULL, NULL, NULL);
    pjmedia_ice_init_ice(NULL, PJ_ICE_SESS_ROLE_CONTROLLED, NULL, NULL);
    pjmedia_ice_modify_sdp(NULL, NULL, NULL);
    pjmedia_ice_start_ice(NULL, NULL, NULL, 0);
    pjmedia_ice_stop_ice(NULL);
#endif

#ifdef HAS_PJMEDIA_G711_CODEC
    pjmedia_codec_g711_init(NULL);
    pjmedia_codec_g711_deinit();
#endif

#ifdef HAS_PJMEDIA_GSM_CODEC
    pjmedia_codec_gsm_init(NULL);
    pjmedia_codec_gsm_deinit();
#endif

#ifdef HAS_PJMEDIA_SPEEX_CODEC
    pjmedia_codec_speex_init(NULL, 0, 0, 0);
    pjmedia_codec_speex_deinit();
#endif

#ifdef HAS_PJMEDIA_ILBC_CODEC
    pjmedia_codec_ilbc_init(NULL, 0);
    pjmedia_codec_ilbc_deinit();
#endif

    return 0;
}