diff --git a/openbsc/include/openbsc/mgcp.h b/openbsc/include/openbsc/mgcp.h index 0d6459024..335c83d93 100644 --- a/openbsc/include/openbsc/mgcp.h +++ b/openbsc/include/openbsc/mgcp.h @@ -121,7 +121,7 @@ struct mgcp_trunk_config { /* RTP patching */ int force_constant_ssrc; /* 0: don't, 1: once */ - int force_constant_timing; + int force_aligned_timing; /* spec handling */ int force_realloc; diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h index 20c433a2e..a9ae33c73 100644 --- a/openbsc/include/openbsc/mgcp_internal.h +++ b/openbsc/include/openbsc/mgcp_internal.h @@ -87,7 +87,7 @@ struct mgcp_rtp_end { /* RTP patching */ int force_constant_ssrc; /* -1: always, 0: don't, 1: once */ - int force_constant_timing; + int force_aligned_timing; /* * Each end has a socket... diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c index 40227af01..657019e15 100644 --- a/openbsc/src/libmgcp/mgcp_network.c +++ b/openbsc/src/libmgcp/mgcp_network.c @@ -134,29 +134,47 @@ int mgcp_send_dummy(struct mgcp_endpoint *endp) endp->net_end.rtp_port, buf, 1); } +static int32_t compute_timestamp_aligment_error(struct mgcp_rtp_stream_state *sstate, + int ptime, uint32_t timestamp) +{ + int32_t timestamp_delta; + + if (ptime == 0) + return 0; + + /* Align according to: T - Tlast = k * Tptime */ + timestamp_delta = timestamp - sstate->last_timestamp; + + return timestamp_delta % ptime; +} + static int check_rtp_timestamp(struct mgcp_endpoint *endp, - struct mgcp_rtp_stream_state *state, + struct mgcp_rtp_state *state, + struct mgcp_rtp_stream_state *sstate, struct mgcp_rtp_end *rtp_end, struct sockaddr_in *addr, uint16_t seq, uint32_t timestamp, const char *text, int32_t *tsdelta_out) { int32_t tsdelta; + int32_t timestamp_error; /* Not fully intialized, skip */ - if (state->last_tsdelta == 0 && timestamp == state->last_timestamp) + if (sstate->last_tsdelta == 0 && timestamp == sstate->last_timestamp) return 0; - if (seq == state->last_seq) { - if (timestamp != state->last_timestamp) { - state->err_ts_counter += 1; + if (seq == sstate->last_seq) { + if (timestamp != sstate->last_timestamp) { + sstate->err_ts_counter += 1; LOGP(DMGCP, LOGL_ERROR, "The %s timestamp delta is != 0 but the sequence " - "number %d is the same" + "number %d is the same, " + "TS offset: %d, SeqNo offset: %d " "on 0x%x SSRC: %u timestamp: %u " "from %s:%d in %d\n", text, seq, - ENDPOINT_NUMBER(endp), state->ssrc, timestamp, + state->timestamp_offset, state->seq_offset, + ENDPOINT_NUMBER(endp), sstate->ssrc, timestamp, inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), endp->conn_mode); } @@ -164,31 +182,30 @@ static int check_rtp_timestamp(struct mgcp_endpoint *endp, } tsdelta = - (int32_t)(timestamp - state->last_timestamp) / - (int16_t)(seq - state->last_seq); + (int32_t)(timestamp - sstate->last_timestamp) / + (int16_t)(seq - sstate->last_seq); if (tsdelta == 0) { - state->err_ts_counter += 1; - LOGP(DMGCP, LOGL_ERROR, + /* Don't update *tsdelta_out */ + LOGP(DMGCP, LOGL_NOTICE, "The %s timestamp delta is %d " "on 0x%x SSRC: %u timestamp: %u " "from %s:%d in %d\n", text, tsdelta, - ENDPOINT_NUMBER(endp), state->ssrc, timestamp, + ENDPOINT_NUMBER(endp), sstate->ssrc, timestamp, inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), endp->conn_mode); return 0; } - if (state->last_tsdelta != tsdelta) { - if (state->last_tsdelta) { - state->err_ts_counter += 1; - LOGP(DMGCP, LOGL_ERROR, + if (sstate->last_tsdelta != tsdelta) { + if (sstate->last_tsdelta) { + LOGP(DMGCP, LOGL_INFO, "The %s timestamp delta changes from %d to %d " "on 0x%x SSRC: %u timestamp: %u from %s:%d in %d\n", - text, state->last_tsdelta, tsdelta, - ENDPOINT_NUMBER(endp), state->ssrc, timestamp, + text, sstate->last_tsdelta, tsdelta, + ENDPOINT_NUMBER(endp), sstate->ssrc, timestamp, inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), endp->conn_mode); } @@ -197,6 +214,25 @@ static int check_rtp_timestamp(struct mgcp_endpoint *endp, if (tsdelta_out) *tsdelta_out = tsdelta; + timestamp_error = + compute_timestamp_aligment_error(sstate, state->packet_duration, + timestamp); + + if (timestamp_error) { + sstate->err_ts_counter += 1; + LOGP(DMGCP, LOGL_NOTICE, + "The %s timestamp has an alignment error of %d " + "on 0x%x SSRC: %u " + "SeqNo delta: %d, TS delta: %d, dTS/dSeq: %d " + "from %s:%d in %d\n", + text, timestamp_error, + ENDPOINT_NUMBER(endp), sstate->ssrc, + (int16_t)(seq - sstate->last_seq), + (int32_t)(timestamp - sstate->last_timestamp), + tsdelta, + inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), + endp->conn_mode); + } return 1; } @@ -253,6 +289,42 @@ static int adjust_rtp_timestamp_offset(struct mgcp_endpoint *endp, return timestamp_offset; } +/* Set the timestamp offset according to the packet duration. */ +static int align_rtp_timestamp_offset(struct mgcp_endpoint *endp, + struct mgcp_rtp_state *state, + struct mgcp_rtp_end *rtp_end, + struct sockaddr_in *addr, + uint32_t timestamp) +{ + int timestamp_error = 0; + int ptime = state->packet_duration; + + /* Align according to: T + Toffs - Tlast = k * Tptime */ + + timestamp_error = compute_timestamp_aligment_error( + &state->out_stream, ptime, + timestamp + state->timestamp_offset); + + if (timestamp_error) { + state->timestamp_offset += ptime - timestamp_error; + + LOGP(DMGCP, LOGL_NOTICE, + "Corrected timestamp alignment error of %d on 0x%x SSRC: %u " + "new TS offset: %d, " + "from %s:%d in %d\n", + timestamp_error, + ENDPOINT_NUMBER(endp), state->in_stream.ssrc, + state->timestamp_offset, inet_ntoa(addr->sin_addr), + ntohs(addr->sin_port), endp->conn_mode); + } + + OSMO_ASSERT(compute_timestamp_aligment_error(&state->out_stream, ptime, + timestamp + state->timestamp_offset) == 0); + + return timestamp_error; +} + + /** * The RFC 3550 Appendix A assumes there are multiple sources but * some of the supported endpoints (e.g. the nanoBTS) can only handle @@ -300,15 +372,15 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta state->seq_offset, state->packet_duration, inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), endp->conn_mode); - if (state->packet_duration == 0 && rtp_end->force_constant_timing) - LOGP(DMGCP, LOGL_ERROR, - "Cannot patch timestamps on 0x%x: " - "RTP packet duration is unknown, SSRC: %u, " - "from %s:%d in %d\n", - ENDPOINT_NUMBER(endp), state->in_stream.ssrc, - inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), - endp->conn_mode); - + if (state->packet_duration == 0) { + state->packet_duration = rtp_end->rate * 20 / 1000; + LOGP(DMGCP, LOGL_NOTICE, + "Fixed packet duration is not available on 0x%x, " + "using fixed 20ms instead: %d from %s:%d in %d\n", + ENDPOINT_NUMBER(endp), state->packet_duration, + inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), + endp->conn_mode); + } } else if (state->in_stream.ssrc != ssrc) { LOGP(DMGCP, LOGL_NOTICE, "The SSRC changed on 0x%x: %u -> %u " @@ -346,7 +418,7 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta state->in_stream.last_tsdelta = 0; } else { /* Compute current per-packet timestamp delta */ - check_rtp_timestamp(endp, &state->in_stream, rtp_end, addr, + check_rtp_timestamp(endp, state, &state->in_stream, rtp_end, addr, seq, timestamp, "input", &state->in_stream.last_tsdelta); @@ -358,15 +430,10 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta state->in_stream.last_timestamp = timestamp; state->in_stream.last_seq = seq; - if (rtp_end->force_constant_timing && - state->out_stream.ssrc == ssrc && state->packet_duration) { - /* Update the timestamp offset */ - const int delta_seq = - seq + state->seq_offset - state->out_stream.last_seq; - - adjust_rtp_timestamp_offset(endp, state, rtp_end, addr, - delta_seq, timestamp); - } + if (rtp_end->force_aligned_timing && + state->out_stream.ssrc == ssrc && state->packet_duration) + /* Align the timestamp offset */ + align_rtp_timestamp_offset(endp, state, rtp_end, addr, timestamp); /* Store the updated SSRC back to the packet */ if (state->patch_ssrc) @@ -382,8 +449,8 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta /* Check again, whether the timestamps are still valid */ if (state->out_stream.ssrc == ssrc) - check_rtp_timestamp(endp, &state->out_stream, rtp_end, addr, - seq, timestamp, "output", + check_rtp_timestamp(endp, state, &state->out_stream, rtp_end, + addr, seq, timestamp, "output", &state->out_stream.last_tsdelta); /* diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index 7d3ad74df..ddec44d92 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -700,13 +700,13 @@ void mgcp_rtp_end_config(struct mgcp_endpoint *endp, int expect_ssrc_change, int patch_ssrc = expect_ssrc_change && tcfg->force_constant_ssrc; - rtp->force_constant_timing = tcfg->force_constant_timing; + rtp->force_aligned_timing = tcfg->force_aligned_timing; rtp->force_constant_ssrc = patch_ssrc ? 1 : 0; LOGP(DMGCP, LOGL_DEBUG, "Configuring RTP endpoint: local port %d%s%s\n", ntohs(rtp->rtp_port), - rtp->force_constant_timing ? ", force constant timing" : "", + rtp->force_aligned_timing ? ", force constant timing" : "", rtp->force_constant_ssrc ? ", force constant ssrc" : ""); } diff --git a/openbsc/src/libmgcp/mgcp_vty.c b/openbsc/src/libmgcp/mgcp_vty.c index 235b8bd6a..8411b4aa4 100644 --- a/openbsc/src/libmgcp/mgcp_vty.c +++ b/openbsc/src/libmgcp/mgcp_vty.c @@ -89,11 +89,11 @@ static int config_write_mgcp(struct vty *vty) vty_out(vty, " rtcp-omit%s", VTY_NEWLINE); else vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE); - if (g_cfg->trunk.force_constant_ssrc || g_cfg->trunk.force_constant_timing) { + if (g_cfg->trunk.force_constant_ssrc || g_cfg->trunk.force_aligned_timing) { vty_out(vty, " %srtp-patch ssrc%s", g_cfg->trunk.force_constant_ssrc ? "" : "no ", VTY_NEWLINE); vty_out(vty, " %srtp-patch timestamp%s", - g_cfg->trunk.force_constant_timing ? "" : "no ", VTY_NEWLINE); + g_cfg->trunk.force_aligned_timing ? "" : "no ", VTY_NEWLINE); } else vty_out(vty, " no rtp-patch%s", VTY_NEWLINE); if (g_cfg->trunk.audio_payload != -1) @@ -480,7 +480,7 @@ DEFUN(cfg_mgcp_patch_rtp_ts, "Adjust RTP timestamp\n" ) { - g_cfg->trunk.force_constant_timing = 1; + g_cfg->trunk.force_aligned_timing = 1; return CMD_SUCCESS; } @@ -491,7 +491,7 @@ DEFUN(cfg_mgcp_no_patch_rtp_ts, "Adjust RTP timestamp\n" ) { - g_cfg->trunk.force_constant_timing = 0; + g_cfg->trunk.force_aligned_timing = 0; return CMD_SUCCESS; } @@ -501,7 +501,7 @@ DEFUN(cfg_mgcp_no_patch_rtp, NO_STR RTP_PATCH_STR) { g_cfg->trunk.force_constant_ssrc = 0; - g_cfg->trunk.force_constant_timing = 0; + g_cfg->trunk.force_aligned_timing = 0; return CMD_SUCCESS; } @@ -598,11 +598,11 @@ static int config_write_trunk(struct vty *vty) vty_out(vty, " rtcp-omit%s", VTY_NEWLINE); else vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE); - if (trunk->force_constant_ssrc || trunk->force_constant_timing) { + if (trunk->force_constant_ssrc || trunk->force_aligned_timing) { vty_out(vty, " %srtp-patch ssrc%s", trunk->force_constant_ssrc ? "" : "no ", VTY_NEWLINE); vty_out(vty, " %srtp-patch timestamp%s", - trunk->force_constant_timing ? "" : "no ", VTY_NEWLINE); + trunk->force_aligned_timing ? "" : "no ", VTY_NEWLINE); } else vty_out(vty, " no rtp-patch%s", VTY_NEWLINE); if (trunk->audio_fmtp_extra) @@ -747,7 +747,7 @@ DEFUN(cfg_trunk_patch_rtp_ts, ) { struct mgcp_trunk_config *trunk = vty->index; - trunk->force_constant_timing = 1; + trunk->force_aligned_timing = 1; return CMD_SUCCESS; } @@ -759,7 +759,7 @@ DEFUN(cfg_trunk_no_patch_rtp_ts, ) { struct mgcp_trunk_config *trunk = vty->index; - trunk->force_constant_timing = 0; + trunk->force_aligned_timing = 0; return CMD_SUCCESS; } @@ -770,7 +770,7 @@ DEFUN(cfg_trunk_no_patch_rtp, { struct mgcp_trunk_config *trunk = vty->index; trunk->force_constant_ssrc = 0; - trunk->force_constant_timing = 0; + trunk->force_aligned_timing = 0; return CMD_SUCCESS; } diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c index 8b1b92415..3cfc183e7 100644 --- a/openbsc/tests/mgcp/mgcp_test.c +++ b/openbsc/tests/mgcp/mgcp_test.c @@ -660,7 +660,7 @@ static void test_packet_error_detection(int patch_ssrc, int patch_ts) trunk.number_endpoints = 1; trunk.endpoints = &endp; trunk.force_constant_ssrc = patch_ssrc; - trunk.force_constant_timing = patch_ts; + trunk.force_aligned_timing = patch_ts; endp.tcfg = &trunk; diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index 03c1cf0a7..638ac9215 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -72,21 +72,21 @@ Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 320, dTS: 160, Seq: 2 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 320, dTS: 160, Seq: 3 -Out TS change: 0, dTS: 160, Seq change: 1, TS Err change: in +1, out +1 +Out TS change: 0, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 480, dTS: 160, Seq: 4 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 640, dTS: 160, Seq: 5 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 960, dTS: 320, Seq: 6 -Out TS change: 320, dTS: 320, Seq change: 1, TS Err change: in +1, out +1 +Out TS change: 320, dTS: 320, Seq change: 1, TS Err change: in +0, out +0 In TS: 1120, dTS: 160, Seq: 7 -Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +1 +Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 1280, dTS: 160, Seq: 8 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 1400, dTS: 120, Seq: 9 Out TS change: 120, dTS: 120, Seq change: 1, TS Err change: in +1, out +1 In TS: 1560, dTS: 160, Seq: 10 -Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +1 +Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 1720, dTS: 160, Seq: 11 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 34688, dTS: 0, Seq: 12 @@ -98,7 +98,7 @@ Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 35128, dTS: 120, Seq: 15 Out TS change: 120, dTS: 120, Seq change: 1, TS Err change: in +1, out +1 In TS: 35288, dTS: 160, Seq: 16 -Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +1 +Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 35448, dTS: 160, Seq: 17 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 35768, dTS: 160, Seq: 19 @@ -128,21 +128,21 @@ Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 320, dTS: 160, Seq: 2 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 320, dTS: 160, Seq: 3 -Out TS change: 0, dTS: 160, Seq change: 1, TS Err change: in +1, out +1 +Out TS change: 0, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 480, dTS: 160, Seq: 4 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 640, dTS: 160, Seq: 5 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 960, dTS: 320, Seq: 6 -Out TS change: 320, dTS: 320, Seq change: 1, TS Err change: in +1, out +1 +Out TS change: 320, dTS: 320, Seq change: 1, TS Err change: in +0, out +0 In TS: 1120, dTS: 160, Seq: 7 -Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +1 +Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 1280, dTS: 160, Seq: 8 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 1400, dTS: 120, Seq: 9 Out TS change: 120, dTS: 120, Seq change: 1, TS Err change: in +1, out +1 In TS: 1560, dTS: 160, Seq: 10 -Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +1 +Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 1720, dTS: 160, Seq: 11 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 Output SSRC changed to 10203040 @@ -155,7 +155,7 @@ Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 35128, dTS: 120, Seq: 15 Out TS change: 120, dTS: 120, Seq change: 1, TS Err change: in +1, out +1 In TS: 35288, dTS: 160, Seq: 16 -Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +1 +Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 35448, dTS: 160, Seq: 17 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 35768, dTS: 160, Seq: 19 @@ -185,21 +185,21 @@ Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 320, dTS: 160, Seq: 2 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 320, dTS: 160, Seq: 3 -Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 +Out TS change: 0, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 480, dTS: 160, Seq: 4 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 640, dTS: 160, Seq: 5 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 960, dTS: 320, Seq: 6 -Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 +Out TS change: 320, dTS: 320, Seq change: 1, TS Err change: in +0, out +0 In TS: 1120, dTS: 160, Seq: 7 -Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 +Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 1280, dTS: 160, Seq: 8 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 1400, dTS: 120, Seq: 9 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 In TS: 1560, dTS: 160, Seq: 10 -Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 +Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 1720, dTS: 160, Seq: 11 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 Output SSRC changed to 10203040 @@ -212,7 +212,7 @@ Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 35128, dTS: 120, Seq: 15 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 In TS: 35288, dTS: 160, Seq: 16 -Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 +Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 35448, dTS: 160, Seq: 17 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 35768, dTS: 160, Seq: 19 @@ -228,7 +228,7 @@ Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 36408, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 36568, dTS: 160, Seq: 23 -Out TS change: 0, dTS: 160, Seq change: 0, TS Err change: in +1, out +0 +Out TS change: 160, dTS: 160, Seq change: 0, TS Err change: in +1, out +1 In TS: 36728, dTS: 160, Seq: 24 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 36888, dTS: 160, Seq: 25 @@ -242,21 +242,21 @@ Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 320, dTS: 160, Seq: 2 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 320, dTS: 160, Seq: 3 -Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 +Out TS change: 0, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 480, dTS: 160, Seq: 4 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 640, dTS: 160, Seq: 5 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 960, dTS: 320, Seq: 6 -Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 +Out TS change: 320, dTS: 320, Seq change: 1, TS Err change: in +0, out +0 In TS: 1120, dTS: 160, Seq: 7 -Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 +Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 1280, dTS: 160, Seq: 8 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 1400, dTS: 120, Seq: 9 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 In TS: 1560, dTS: 160, Seq: 10 -Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 +Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 1720, dTS: 160, Seq: 11 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 34688, dTS: 0, Seq: 12 @@ -268,7 +268,7 @@ Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 35128, dTS: 120, Seq: 15 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 In TS: 35288, dTS: 160, Seq: 16 -Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 +Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 35448, dTS: 160, Seq: 17 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 35768, dTS: 160, Seq: 19 @@ -284,7 +284,7 @@ Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 36408, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 36568, dTS: 160, Seq: 23 -Out TS change: 0, dTS: 160, Seq change: 0, TS Err change: in +1, out +0 +Out TS change: 160, dTS: 160, Seq change: 0, TS Err change: in +1, out +1 In TS: 36728, dTS: 160, Seq: 24 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 In TS: 36888, dTS: 160, Seq: 25