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:
parent
38e02c5125
commit
30690adbc8
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue