mgcp: Move Annex A counting out of patch/count method
mgcp_patch_and_count has grown due supporting linearizing timestamps, ssrc and other things for equipment like the ip.access nanoBTS. Fight back and move the Annex A code into a dedicated method. The result is updated as we now count after all the patching and for the Annex A code no change in SSRC can be detected.
This commit is contained in:
parent
2a7ab868e3
commit
a5a59c9a05
|
@ -54,17 +54,22 @@ struct mgcp_rtp_state {
|
|||
|
||||
uint32_t orig_ssrc;
|
||||
|
||||
uint16_t base_seq;
|
||||
int seq_offset;
|
||||
int cycles;
|
||||
|
||||
int32_t timestamp_offset;
|
||||
uint32_t packet_duration;
|
||||
uint32_t jitter;
|
||||
int32_t transit;
|
||||
|
||||
struct mgcp_rtp_stream_state in_stream;
|
||||
struct mgcp_rtp_stream_state out_stream;
|
||||
|
||||
/* jitter and packet loss calculation */
|
||||
int stats_initialized;
|
||||
uint16_t stats_base_seq;
|
||||
uint16_t stats_max_seq;
|
||||
uint32_t stats_ssrc;
|
||||
uint32_t stats_jitter;
|
||||
int32_t stats_transit;
|
||||
int stats_cycles;
|
||||
};
|
||||
|
||||
struct mgcp_rtp_codec {
|
||||
|
|
|
@ -331,6 +331,60 @@ void mgcp_get_net_downlink_format_default(struct mgcp_endpoint *endp,
|
|||
*fmtp_extra = endp->bts_end.fmtp_extra;
|
||||
}
|
||||
|
||||
|
||||
void mgcp_rtp_annex_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state,
|
||||
const uint16_t seq, const int32_t transit,
|
||||
const uint32_t ssrc)
|
||||
{
|
||||
uint16_t udelta;
|
||||
int32_t d;
|
||||
|
||||
/* initialize or re-initialize */
|
||||
if (!state->stats_initialized || state->stats_ssrc != ssrc) {
|
||||
state->stats_initialized = 1;
|
||||
state->stats_base_seq = seq;
|
||||
state->stats_max_seq = seq - 1;
|
||||
state->stats_ssrc = ssrc;
|
||||
state->stats_jitter = 0;
|
||||
state->stats_transit = transit;
|
||||
state->stats_cycles = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The below takes the shape of the validation of
|
||||
* Appendix A. Check if there is something weird with
|
||||
* the sequence number, otherwise check for a wrap
|
||||
* around in the sequence number.
|
||||
* It can't wrap during the initialization so let's
|
||||
* skip it here. The Appendix A probably doesn't have
|
||||
* this issue because of the probation.
|
||||
*/
|
||||
udelta = seq - state->stats_max_seq;
|
||||
if (udelta < RTP_MAX_DROPOUT) {
|
||||
if (seq < state->stats_max_seq)
|
||||
state->stats_cycles += RTP_SEQ_MOD;
|
||||
} else if (udelta <= RTP_SEQ_MOD - RTP_MAX_MISORDER) {
|
||||
LOGP(DMGCP, LOGL_NOTICE,
|
||||
"RTP seqno made a very large jump on 0x%x delta: %u\n",
|
||||
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. Timestamp and arrival_time have a 1/rate
|
||||
* resolution.
|
||||
*/
|
||||
d = transit - state->stats_transit;
|
||||
state->stats_transit = transit;
|
||||
if (d < 0)
|
||||
d = -d;
|
||||
state->stats_jitter += d - ((state->stats_jitter + 8) >> 4);
|
||||
state->stats_max_seq = seq;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The RFC 3550 Appendix A assumes there are multiple sources but
|
||||
* some of the supported endpoints (e.g. the nanoBTS) can only handle
|
||||
|
@ -344,8 +398,8 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta
|
|||
char *data, int len)
|
||||
{
|
||||
uint32_t arrival_time;
|
||||
int32_t transit, d;
|
||||
uint16_t seq, udelta;
|
||||
int32_t transit;
|
||||
uint16_t seq;
|
||||
uint32_t timestamp, ssrc;
|
||||
struct rtp_hdr *rtp_hdr;
|
||||
int payload = rtp_end->codec.payload_type;
|
||||
|
@ -361,13 +415,10 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta
|
|||
transit = arrival_time - timestamp;
|
||||
|
||||
if (!state->initialized) {
|
||||
state->initialized = 1;
|
||||
state->in_stream.last_seq = seq - 1;
|
||||
state->in_stream.ssrc = state->orig_ssrc = ssrc;
|
||||
state->in_stream.last_tsdelta = 0;
|
||||
state->base_seq = seq;
|
||||
state->initialized = 1;
|
||||
state->jitter = 0;
|
||||
state->transit = transit;
|
||||
state->packet_duration = mgcp_rtp_packet_duration(endp, rtp_end);
|
||||
state->out_stream = state->in_stream;
|
||||
state->out_stream.last_timestamp = timestamp;
|
||||
|
@ -398,8 +449,6 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta
|
|||
endp->conn_mode);
|
||||
|
||||
state->in_stream.ssrc = ssrc;
|
||||
state->jitter = 0;
|
||||
state->transit = transit;
|
||||
if (rtp_end->force_constant_ssrc) {
|
||||
int16_t delta_seq;
|
||||
|
||||
|
@ -470,34 +519,7 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta
|
|||
addr, seq, timestamp, "output",
|
||||
&state->out_stream.last_tsdelta);
|
||||
|
||||
/*
|
||||
* The below takes the shape of the validation from Appendix A. Check
|
||||
* if there is something weird with the sequence number, otherwise check
|
||||
* for a wrap around in the sequence number.
|
||||
*
|
||||
* Note that last_seq is used where the appendix mentions max_seq.
|
||||
*/
|
||||
udelta = seq - state->out_stream.last_seq;
|
||||
if (udelta < RTP_MAX_DROPOUT) {
|
||||
if (seq < state->out_stream.last_seq)
|
||||
state->cycles += RTP_SEQ_MOD;
|
||||
} else if (udelta <= RTP_SEQ_MOD - RTP_MAX_MISORDER) {
|
||||
LOGP(DMGCP, LOGL_NOTICE,
|
||||
"RTP seqno made a very large jump on 0x%x delta: %u\n",
|
||||
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. Timestamp and arrival_time have a 1/rate
|
||||
* resolution.
|
||||
*/
|
||||
d = transit - state->transit;
|
||||
state->transit = transit;
|
||||
if (d < 0)
|
||||
d = -d;
|
||||
state->jitter += d - ((state->jitter + 8) >> 4);
|
||||
mgcp_rtp_annex_count(endp, state, seq, transit, ssrc);
|
||||
|
||||
/* Save output values */
|
||||
state->out_stream.last_seq = seq;
|
||||
|
@ -998,10 +1020,10 @@ void mgcp_state_calc_loss(struct mgcp_rtp_state *state,
|
|||
struct mgcp_rtp_end *end, uint32_t *expected,
|
||||
int *loss)
|
||||
{
|
||||
*expected = state->cycles + state->out_stream.last_seq;
|
||||
*expected = *expected - state->base_seq + 1;
|
||||
*expected = state->stats_cycles + state->stats_max_seq;
|
||||
*expected = *expected - state->stats_base_seq + 1;
|
||||
|
||||
if (!state->initialized) {
|
||||
if (!state->stats_initialized) {
|
||||
*expected = 0;
|
||||
*loss = 0;
|
||||
return;
|
||||
|
@ -1023,7 +1045,7 @@ void mgcp_state_calc_loss(struct mgcp_rtp_state *state,
|
|||
|
||||
uint32_t mgcp_state_calc_jitter(struct mgcp_rtp_state *state)
|
||||
{
|
||||
if (!state->initialized)
|
||||
if (!state->stats_initialized)
|
||||
return 0;
|
||||
return state->jitter >> 4;
|
||||
return state->stats_jitter >> 4;
|
||||
}
|
||||
|
|
|
@ -699,10 +699,10 @@ static void test_packet_loss_calc(void)
|
|||
memset(&state, 0, sizeof(state));
|
||||
memset(&rtp, 0, sizeof(rtp));
|
||||
|
||||
state.initialized = 1;
|
||||
state.base_seq = pl_test_dat[i].base_seq;
|
||||
state.out_stream.last_seq = pl_test_dat[i].max_seq;
|
||||
state.cycles = pl_test_dat[i].cycles;
|
||||
state.stats_initialized = 1;
|
||||
state.stats_base_seq = pl_test_dat[i].base_seq;
|
||||
state.stats_max_seq = pl_test_dat[i].max_seq;
|
||||
state.stats_cycles = pl_test_dat[i].cycles;
|
||||
|
||||
rtp.packets = pl_test_dat[i].packets;
|
||||
mgcp_state_calc_loss(&state, &rtp, &expected, &loss);
|
||||
|
@ -921,7 +921,7 @@ static void test_packet_error_detection(int patch_ssrc, int patch_ts)
|
|||
state.out_stream.err_ts_counter - last_out_ts_err_cnt);
|
||||
|
||||
printf("Stats: Jitter = %u, Transit = %d\n",
|
||||
mgcp_state_calc_jitter(&state), state.transit);
|
||||
mgcp_state_calc_jitter(&state), state.stats_transit);
|
||||
|
||||
last_in_ts_err_cnt = state.in_stream.err_ts_counter;
|
||||
last_out_ts_err_cnt = state.out_stream.err_ts_counter;
|
||||
|
|
|
@ -142,58 +142,58 @@ Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
|||
Stats: Jitter = 15, Transit = 40
|
||||
In TS: 34688, dTS: 0, Seq: 12
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 0, Transit = -32768
|
||||
Stats: Jitter = 2065, Transit = -32768
|
||||
In TS: 34848, dTS: 160, Seq: 13
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 0, Transit = -32768
|
||||
Stats: Jitter = 1935, Transit = -32768
|
||||
In TS: 35008, dTS: 160, Seq: 14
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 0, Transit = -32768
|
||||
Stats: Jitter = 1814, Transit = -32768
|
||||
In TS: 35128, dTS: 120, Seq: 15
|
||||
Out TS change: 120, dTS: 120, Seq change: 1, TS Err change: in +1, out +1
|
||||
Stats: Jitter = 2, Transit = -32728
|
||||
Stats: Jitter = 1704, Transit = -32728
|
||||
In TS: 35288, dTS: 160, Seq: 16
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 2, Transit = -32728
|
||||
Stats: Jitter = 1597, Transit = -32728
|
||||
In TS: 35448, dTS: 160, Seq: 17
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 2, Transit = -32728
|
||||
Stats: Jitter = 1497, Transit = -32728
|
||||
In TS: 35768, dTS: 160, Seq: 19
|
||||
Out TS change: 320, dTS: 160, Seq change: 2, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 12, Transit = -32888
|
||||
Stats: Jitter = 1414, Transit = -32888
|
||||
In TS: 35928, dTS: 160, Seq: 20
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 11, Transit = -32888
|
||||
Stats: Jitter = 1325, Transit = -32888
|
||||
In TS: 36088, dTS: 160, Seq: 21
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 20, Transit = -33048
|
||||
Stats: Jitter = 1252, Transit = -33048
|
||||
In TS: 36088, dTS: 160, Seq: 21
|
||||
Out TS change: 0, dTS: 160, Seq change: 0, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 29, Transit = -32888
|
||||
Stats: Jitter = 1184, Transit = -32888
|
||||
In TS: 36248, dTS: 160, Seq: 22
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 27, Transit = -32888
|
||||
Stats: Jitter = 1110, Transit = -32888
|
||||
In TS: 36408, dTS: 160, Seq: 23
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 25, Transit = -32888
|
||||
Stats: Jitter = 1041, Transit = -32888
|
||||
In TS: 36568, dTS: 160, Seq: 23
|
||||
Out TS change: 160, dTS: 160, Seq change: 0, TS Err change: in +1, out +1
|
||||
Stats: Jitter = 24, Transit = -32888
|
||||
Stats: Jitter = 976, Transit = -32888
|
||||
In TS: 36728, dTS: 160, Seq: 24
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 22, Transit = -32888
|
||||
Stats: Jitter = 915, Transit = -32888
|
||||
In TS: 36888, dTS: 160, Seq: 25
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 21, Transit = -32888
|
||||
Stats: Jitter = 857, Transit = -32888
|
||||
In TS: 160000, dTS: 0, Seq: 1000
|
||||
Out TS change: 12000, dTS: 12000, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 0, Transit = -144000
|
||||
Stats: Jitter = 7748, Transit = -144000
|
||||
In TS: 160160, dTS: 160, Seq: 1001
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 0, Transit = -144000
|
||||
Stats: Jitter = 7264, Transit = -144000
|
||||
In TS: 160320, dTS: 160, Seq: 1002
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 0, Transit = -144000
|
||||
Stats: Jitter = 6810, Transit = -144000
|
||||
Testing packet error detection.
|
||||
Output SSRC changed to 11223344
|
||||
In TS: 0, dTS: 0, Seq: 0
|
||||
|
@ -422,57 +422,57 @@ Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
|||
Stats: Jitter = 15, Transit = 40
|
||||
In TS: 34688, dTS: 0, Seq: 12
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 0, Transit = -32768
|
||||
Stats: Jitter = 2065, Transit = -32768
|
||||
In TS: 34848, dTS: 160, Seq: 13
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 0, Transit = -32768
|
||||
Stats: Jitter = 1935, Transit = -32768
|
||||
In TS: 35008, dTS: 160, Seq: 14
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 0, Transit = -32768
|
||||
Stats: Jitter = 1814, Transit = -32768
|
||||
In TS: 35128, dTS: 120, Seq: 15
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0
|
||||
Stats: Jitter = 2, Transit = -32728
|
||||
Stats: Jitter = 1704, Transit = -32728
|
||||
In TS: 35288, dTS: 160, Seq: 16
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 2, Transit = -32728
|
||||
Stats: Jitter = 1597, Transit = -32728
|
||||
In TS: 35448, dTS: 160, Seq: 17
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 2, Transit = -32728
|
||||
Stats: Jitter = 1497, Transit = -32728
|
||||
In TS: 35768, dTS: 160, Seq: 19
|
||||
Out TS change: 320, dTS: 160, Seq change: 2, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 12, Transit = -32888
|
||||
Stats: Jitter = 1414, Transit = -32888
|
||||
In TS: 35928, dTS: 160, Seq: 20
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 11, Transit = -32888
|
||||
Stats: Jitter = 1325, Transit = -32888
|
||||
In TS: 36088, dTS: 160, Seq: 21
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 20, Transit = -33048
|
||||
Stats: Jitter = 1252, Transit = -33048
|
||||
In TS: 36088, dTS: 160, Seq: 21
|
||||
Out TS change: 0, dTS: 160, Seq change: 0, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 29, Transit = -32888
|
||||
Stats: Jitter = 1184, Transit = -32888
|
||||
In TS: 36248, dTS: 160, Seq: 22
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 27, Transit = -32888
|
||||
Stats: Jitter = 1110, Transit = -32888
|
||||
In TS: 36408, dTS: 160, Seq: 23
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 25, Transit = -32888
|
||||
Stats: Jitter = 1041, Transit = -32888
|
||||
In TS: 36568, dTS: 160, Seq: 23
|
||||
Out TS change: 160, dTS: 160, Seq change: 0, TS Err change: in +1, out +1
|
||||
Stats: Jitter = 24, Transit = -32888
|
||||
Stats: Jitter = 976, Transit = -32888
|
||||
In TS: 36728, dTS: 160, Seq: 24
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 22, Transit = -32888
|
||||
Stats: Jitter = 915, Transit = -32888
|
||||
In TS: 36888, dTS: 160, Seq: 25
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 21, Transit = -32888
|
||||
Stats: Jitter = 857, Transit = -32888
|
||||
In TS: 160000, dTS: 0, Seq: 1000
|
||||
Out TS change: 12000, dTS: 12000, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 0, Transit = -144000
|
||||
Stats: Jitter = 7748, Transit = -144000
|
||||
In TS: 160160, dTS: 160, Seq: 1001
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 0, Transit = -144000
|
||||
Stats: Jitter = 7264, Transit = -144000
|
||||
In TS: 160320, dTS: 160, Seq: 1002
|
||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||
Stats: Jitter = 0, Transit = -144000
|
||||
Stats: Jitter = 6810, Transit = -144000
|
||||
Testing multiple payload types
|
||||
Done
|
||||
|
|
Reference in New Issue