#include #include #include #include #include "raw_rtp.h" void init_seq(source *s, u_int16 seq); int update_seq(source *s, u_int16 seq); float lost_rate(source*s); double tdbl(struct timeval *a); struct timeval db2tv(double d); double tdbl(struct timeval *a) { return a->tv_sec + a->tv_usec/1e6; } struct timeval db2tv(double d) { struct timeval tv; tv.tv_sec = (long) d; tv.tv_usec = (long) ((d - (long) d) * 1000000.0); return tv; } void init_seq(source *s, u_int16 seq) { s->base_seq = seq - 1; s->max_seq = seq; s->bad_seq = RTP_SEQ_MOD + 1; s->cycles = 0; s->received = 0; s->received_prior = 0; s->expected_prior = 0; /* other initialization */ } int update_seq(source *s, u_int16 seq) { u_int16 udelta = seq - s->max_seq; const int MAX_DROPOUT = 3000; const int MAX_MISORDER = 100; const int MIN_SEQUENTIAL = 2; /* * Source is not valid until MIN_SEQUENTIAL packets with * sequential sequence numbers have been received. */ if (s->probation) { /* packet is in sequence */ if (seq == s->max_seq + 1) { s->probation--; s->max_seq = seq; if (s->probation == 0) { init_seq(s, seq); s->received++; return 1; } } else { s->probation = MIN_SEQUENTIAL - 1; s->max_seq = seq; } return 0; } else if (udelta < MAX_DROPOUT) { /* in order, with permissible gap */ if (seq < s->max_seq) { /* * Sequence number wrapped - count another 64K cycle. */ s->cycles += RTP_SEQ_MOD; } s->max_seq = seq; } else if (udelta <= RTP_SEQ_MOD - MAX_MISORDER) { /* the sequence number made a very large jump */ if (seq == s->bad_seq) { /* * Two sequential packets -- assume that the other side * restarted without telling us so just re-sync * (i.e., pretend this was the first packet). */ init_seq(s, seq); } else { s->bad_seq = (seq + 1) & (RTP_SEQ_MOD-1); return 0; } } else { /* duplicate or reordered packet */ } s->received++; return 1; } float lost_rate(source*s) { u_int32 extended_max; u_int32 expected; int lost; u_int32 expected_interval; u_int32 received_interval; u_int32 lost_interval; float fraction; u_int32 tmp; printf(" highest seq. number seen max_seq is %d\n", s->max_seq); printf(" shifted count of seq. number cycles is %d\n", s->cycles); printf(" base seq number is %d\n", s->base_seq); printf(" last bad_seq is %d\n", s->bad_seq); printf("packets received is %d\n", s->received); printf(" packet expected at last interval is %d\n", s->expected_prior); printf(" packet received at last interval %d \n", s->received_prior); extended_max = s->cycles + s->max_seq; expected = extended_max - s->base_seq + 1; printf(" extended highest seq. number seen max_seq is %d\n", extended_max); printf("total exptected accumulation of seq# is %d \n", expected); lost = expected - s->received; printf("total lost packet number is %d\n",lost); expected_interval = expected - s->expected_prior; printf("expected_interval is %d\n", expected_interval); s->expected_prior = expected; received_interval = s->received - s->received_prior; printf("received_interval is %d\n", received_interval); s->received_prior = s->received; lost_interval = expected_interval - received_interval; printf("lost_interval is %d\n", lost_interval); if (expected_interval == 0 || lost_interval <= 0) fraction = 0; else { tmp = lost_interval; printf("lost_interval << 8/expected_interval is %d/%d\n", tmp<<8, expected_interval); fraction =(float)(lost_interval << 8) /(float)expected_interval; printf("lost_interval << 8 is %d\n", lost_interval<<8); } printf("accumulated packet lost rate is %f\n", (float)lost/(float)extended_max ); return fraction; } /* *The code fragments below implement the algorithm given in Section * 6.4.1 for calculating an estimate of the statistical variance of the * RTP data interarrival time to be inserted in the interarrival jitter * field of reception reports. The inputs are r->ts , the timestamp from * the incoming packet, and arrival , the current time in the same * units. Here s points to state for the source; s->transit holds the * relative transit time for the previous packet, and s->jitter holds * the estimated jitter. The jitter field of the reception report is * measured in timestamp units and expressed as an unsigned integer, but * the jitter estimate is kept in a floating point. As each data packet * arrives, the jitter estimate is updated: */ void rtp_jitter(source *s, rtp_hdr_t *r, rtcp_rr_t *rr, int arrival, int round_off) { int transit = arrival - r->ts; int d = transit - s->transit; s->transit = transit; if (d < 0) d = -d; if(round_off) { s->jitter += (1./16.) * ((double)d - s->jitter); rr->jitter = (u_int32) s->jitter; } else { s->jitter += d - ((s->jitter + 8) >> 4); rr->jitter = s->jitter >> 4; } }