mgcp: Calculate the jitter with the formula/code from the appendix

Use a usec timestamp for the local time. The seconds to usec will
swap over to the lower bits but this appears to be correct. The
CLOCK_MONOTONIC is used to fulfill the RFC 3550 requirement even
if it is a bit slower than the gettimeofday.

Make sure to initialize transit in a way that the first transit
time will be 0. Otherwise the jitter will contain the difference
of the localtime and the remote time.
This commit is contained in:
Holger Hans Peter Freyther 2012-10-24 20:31:25 +02:00
parent 38e02c5125
commit 30690adbc8
3 changed files with 45 additions and 1 deletions

View File

@ -54,6 +54,8 @@ struct mgcp_rtp_state {
uint32_t last_timestamp;
int32_t timestamp_offset;
uint32_t jitter;
int32_t transit;
};
struct mgcp_rtp_end {

View File

@ -40,6 +40,7 @@
/* attempt to determine byte order */
#include <sys/param.h>
#include <limits.h>
#include <time.h>
#ifndef __BYTE_ORDER
# ifdef __APPLE__
@ -91,6 +92,29 @@ enum {
#define DUMMY_LOAD 0x23
/**
* This does not need to be a precision timestamp and
* is allowed to wrap quite fast. The returned value is
* milli seconds now.
*/
uint32_t get_current_ts(void)
{
struct timespec tp;
uint64_t ret;
memset(&tp, 0, sizeof(tp));
if (clock_gettime(CLOCK_MONOTONIC, &tp) != 0)
LOGP(DMGCP, LOGL_NOTICE,
"Getting the clock failed.\n");
/* convert it to useconds */
ret = tp.tv_sec;
ret *= 1000;
ret += tp.tv_nsec / 1000 / 1000;
return ret;
}
static int udp_send(int fd, struct in_addr *addr, int port, char *buf, int len)
{
struct sockaddr_in out;
@ -120,6 +144,8 @@ int mgcp_send_dummy(struct mgcp_endpoint *endp)
static void patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state,
int payload, struct sockaddr_in *addr, char *data, int len)
{
uint32_t arrival_time;
int32_t transit, d;
uint16_t seq, udelta;
uint32_t timestamp;
struct rtp_hdr *rtp_hdr;
@ -130,6 +156,7 @@ static void patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *s
rtp_hdr = (struct rtp_hdr *) data;
seq = ntohs(rtp_hdr->sequence);
timestamp = ntohl(rtp_hdr->timestamp);
arrival_time = get_current_ts();
if (!state->initialized) {
state->base_seq = seq;
@ -137,6 +164,8 @@ static void patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *s
state->ssrc = state->orig_ssrc = rtp_hdr->ssrc;
state->initialized = 1;
state->last_timestamp = timestamp;
state->jitter = 0;
state->transit = arrival_time - timestamp;
} else if (state->ssrc != rtp_hdr->ssrc) {
state->ssrc = rtp_hdr->ssrc;
state->seq_offset = (state->max_seq + 1) - seq;
@ -173,6 +202,19 @@ static void patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *s
ENDPOINT_NUMBER(endp), udelta);
}
/*
* calculate the jitter between the two packages. The TS should be
* taken closer to the read function. This was taken from the
* Appendix A of RFC 3550. The local timestamp has a usec resolution.
*/
transit = arrival_time - timestamp;
d = transit - state->transit;
state->transit = transit;
if (d < 0)
d = -d;
state->jitter += d - ((state->jitter + 8) >> 4);
state->max_seq = seq;
state->last_timestamp = timestamp;

View File

@ -6,5 +6,5 @@ bin_PROGRAMS = osmo-bsc_mgcp
osmo_bsc_mgcp_SOURCES = mgcp_main.c
osmo_bsc_mgcp_LDADD = $(top_builddir)/src/libcommon/libcommon.a \
$(top_builddir)/src/libmgcp/libmgcp.a \
$(top_builddir)/src/libmgcp/libmgcp.a -lrt \
$(LIBOSMOVTY_LIBS) $(LIBOSMOCORE_LIBS)