PJ_DEF(pj_status_t) pjmedia_jbuf_create(pj_pool_t *pool, const pj_str_t *name, unsigned frame_size, unsigned ptime, unsigned max_count, pjmedia_jbuf **p_jb) { pjmedia_jbuf *jb; pj_status_t status; jb = PJ_POOL_ZALLOC_T(pool, pjmedia_jbuf); status = jb_framelist_init(pool, &jb->jb_framelist, frame_size, max_count); if (status != PJ_SUCCESS) return status; pj_strdup_with_null(pool, &jb->jb_name, name); jb->jb_frame_size = frame_size; jb->jb_frame_ptime = ptime; jb->jb_prefetch = PJ_MIN(PJMEDIA_JB_DEFAULT_INIT_DELAY,max_count*4/5); jb->jb_min_prefetch = 0; jb->jb_max_prefetch = max_count*4/5; jb->jb_max_count = max_count; jb->jb_min_shrink_gap= PJMEDIA_JBUF_DISC_MIN_GAP / ptime; jb->jb_max_burst = PJ_MAX(MAX_BURST_MSEC / ptime, max_count*3/4); pj_math_stat_init(&jb->jb_delay); pj_math_stat_init(&jb->jb_burst); pjmedia_jbuf_set_discard(jb, PJMEDIA_JB_DISCARD_PROGRESSIVE); pjmedia_jbuf_reset(jb); *p_jb = jb; return PJ_SUCCESS; }
PJ_DEF(void) pjmedia_rtcp_init(pjmedia_rtcp_session *sess, char *name, unsigned clock_rate, unsigned samples_per_frame, pj_uint32_t ssrc) { pjmedia_rtcp_sr_pkt *sr_pkt = &sess->rtcp_sr_pkt; pj_time_val now; /* Memset everything */ pj_bzero(sess, sizeof(pjmedia_rtcp_session)); /* Last RX timestamp in RTP packet */ sess->rtp_last_ts = (unsigned)-1; /* Name */ sess->name = name ? name : (char*)THIS_FILE, /* Set clock rate */ sess->clock_rate = clock_rate; sess->pkt_size = samples_per_frame; /* Init common RTCP SR header */ sr_pkt->common.version = 2; sr_pkt->common.count = 1; sr_pkt->common.pt = RTCP_SR; sr_pkt->common.length = pj_htons(12); sr_pkt->common.ssrc = pj_htonl(ssrc); /* Copy to RTCP RR header */ pj_memcpy(&sess->rtcp_rr_pkt.common, &sr_pkt->common, sizeof(pjmedia_rtcp_common)); sess->rtcp_rr_pkt.common.pt = RTCP_RR; sess->rtcp_rr_pkt.common.length = pj_htons(7); /* Get time and timestamp base and frequency */ pj_gettimeofday(&now); sess->tv_base = now; sess->stat.start = now; pj_get_timestamp(&sess->ts_base); pj_get_timestamp_freq(&sess->ts_freq); /* Initialize statistics states */ pj_math_stat_init(&sess->stat.rtt); pj_math_stat_init(&sess->stat.rx.loss_period); pj_math_stat_init(&sess->stat.rx.jitter); pj_math_stat_init(&sess->stat.tx.loss_period); pj_math_stat_init(&sess->stat.tx.jitter); /* RR will be initialized on receipt of the first RTP packet. */ }
/* * Initialize bidirectional RTCP statistics. * */ PJ_DEF(void) pjmedia_rtcp_init_stat(pjmedia_rtcp_stat *stat) { pj_time_val now; pj_assert(stat); pj_bzero(stat, sizeof(pjmedia_rtcp_stat)); pj_math_stat_init(&stat->rtt); pj_math_stat_init(&stat->rx.loss_period); pj_math_stat_init(&stat->rx.jitter); pj_math_stat_init(&stat->tx.loss_period); pj_math_stat_init(&stat->tx.jitter); #if defined(PJMEDIA_RTCP_STAT_HAS_IPDV) && PJMEDIA_RTCP_STAT_HAS_IPDV!=0 pj_math_stat_init(&stat->rx_ipdv); #endif #if defined(PJMEDIA_RTCP_STAT_HAS_RAW_JITTER) && PJMEDIA_RTCP_STAT_HAS_RAW_JITTER!=0 pj_math_stat_init(&stat->rx_raw_jitter); #endif pj_gettimeofday(&now); stat->start = now; }
static pj_status_t play_cb(void *user_data, pjmedia_frame *frame) { struct test_data *test_data = (struct test_data *)user_data; struct stream_data *strm_data = &test_data->playback_data; pj_mutex_lock(test_data->mutex); /* Skip frames when test is not started or test has finished */ if (!test_data->running) { pj_bzero(frame->buf, frame->size); pj_mutex_unlock(test_data->mutex); return PJ_SUCCESS; } /* Save last timestamp seen (to calculate drift) */ strm_data->last_timestamp = frame->timestamp.u32.lo; if (strm_data->last_called.u64 == 0) { /* Init vars. */ pj_get_timestamp(&strm_data->last_called); pj_math_stat_init(&strm_data->delay); strm_data->first_timestamp = frame->timestamp.u32.lo; } else { pj_timestamp now; unsigned delay; /* Calculate frame interval */ pj_get_timestamp(&now); delay = pj_elapsed_usec(&strm_data->last_called, &now); strm_data->last_called = now; /* Update frame interval statistic */ pj_math_stat_update(&strm_data->delay, delay); } pj_bzero(frame->buf, frame->size); pj_mutex_unlock(test_data->mutex); return PJ_SUCCESS; }