diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2013-11-29 11:20:06 +0100 |
---|---|---|
committer | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2013-12-10 11:17:44 +0100 |
commit | 58340e5b5bfa37b09a61d544904330c1932ccfec (patch) | |
tree | f98ce03291a86ceb5e1d418569c8ed115a44b519 | |
parent | e2292f3aa1e9ae1faf5521a9cb108775f1ac0540 (diff) |
mgcp/rtp: Fix RTP timestamps if enabled
This forces the output timing to fulfill
dTS = dSegNo * fixedPacketDuration
where dSegNo = seqNo - lastSeqNo.
If timestamp patching is enabled, the output timestamp will be set
to lastTimestamp + dTS. This kind of relative updating is used to
handle seqNo- and timestamp-wraparounds properly.
The updating of timestamp and SSRC has been separated and the patch
field of mgcp_rtp_state has been renamed to patch_ssrc to reflect
it's semantics more closely. The offset fields are now used always
and will change the corresponding header field if they are != 0.
Ticket: OW#1065
Sponsored-by: On-Waves ehf
-rw-r--r-- | openbsc/include/openbsc/mgcp_internal.h | 2 | ||||
-rw-r--r-- | openbsc/src/libmgcp/mgcp_network.c | 40 | ||||
-rw-r--r-- | openbsc/tests/mgcp/mgcp_test.ok | 72 |
3 files changed, 68 insertions, 46 deletions
diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h index 255161f45..b6f4a0df1 100644 --- a/openbsc/include/openbsc/mgcp_internal.h +++ b/openbsc/include/openbsc/mgcp_internal.h @@ -50,7 +50,7 @@ struct mgcp_rtp_stream_state { struct mgcp_rtp_state { int initialized; - int patch; + int patch_ssrc; uint32_t orig_ssrc; diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c index 79c9e1aba..6463ae0bb 100644 --- a/openbsc/src/libmgcp/mgcp_network.c +++ b/openbsc/src/libmgcp/mgcp_network.c @@ -278,7 +278,7 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta state->timestamp_offset = (state->out_stream.last_timestamp + tsdelta) - timestamp; - state->patch = 1; + state->patch_ssrc = 1; ssrc = state->orig_ssrc; if (rtp_end->force_constant_ssrc != -1) rtp_end->force_constant_ssrc -= 1; @@ -300,7 +300,7 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta seq, timestamp, "input", &state->in_stream.last_tsdelta); - if (state->patch) + if (state->patch_ssrc) ssrc = state->orig_ssrc; } @@ -308,16 +308,38 @@ 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; - /* apply the offset and store it back to the packet */ - if (state->patch) { - seq += state->seq_offset; - rtp_hdr->sequence = htons(seq); - rtp_hdr->ssrc = htonl(ssrc); + if (rtp_end->force_constant_timing && + state->out_stream.ssrc == ssrc && state->packet_duration) { + int delta_seq = seq + state->seq_offset - state->out_stream.last_seq; + int timestamp_offset = + state->out_stream.last_timestamp - timestamp + + delta_seq * state->packet_duration; + if (state->timestamp_offset != timestamp_offset) { + state->timestamp_offset = timestamp_offset; - timestamp += state->timestamp_offset; - rtp_hdr->timestamp = htonl(timestamp); + LOGP(DMGCP, LOGL_NOTICE, + "Timestamp patching enabled on 0x%x SSRC: %u " + "SeqNo delta: %d, TS offset: %d, " + "from %s:%d in %d\n", + ENDPOINT_NUMBER(endp), state->in_stream.ssrc, + delta_seq, state->timestamp_offset, + inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), + endp->conn_mode); + } } + /* Store the updated SSRC back to the packet */ + if (state->patch_ssrc) + rtp_hdr->ssrc = htonl(ssrc); + + /* Apply the offset and store it back to the packet. + * This won't change anything if the offset is 0, so the conditional is + * omitted. */ + seq += state->seq_offset; + rtp_hdr->sequence = htons(seq); + timestamp += state->timestamp_offset; + rtp_hdr->timestamp = htonl(timestamp); + /* Check again, whether the timestamps are still valid */ if (state->out_stream.ssrc == ssrc) check_rtp_timestamp(endp, &state->out_stream, rtp_end, addr, diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index 4d3caacb5..3beeb5970 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -94,46 +94,46 @@ Output SSRC changed to 11223344 TS: 0, dTS: 0, TS Errs: in 0, out 0 TS: 160, dTS: 160, TS Errs: in 0, out 0 TS: 320, dTS: 160, TS Errs: in 0, out 0 -TS: 320, dTS: 160, TS Errs: in 1, out 1 -TS: 480, dTS: 160, TS Errs: in 1, out 1 -TS: 640, dTS: 160, TS Errs: in 1, out 1 -TS: 960, dTS: 320, TS Errs: in 2, out 2 -TS: 1120, dTS: 160, TS Errs: in 3, out 3 -TS: 1280, dTS: 160, TS Errs: in 3, out 3 -TS: 1400, dTS: 120, TS Errs: in 4, out 4 -TS: 1560, dTS: 160, TS Errs: in 5, out 5 -TS: 1720, dTS: 160, TS Errs: in 5, out 5 +TS: 480, dTS: 160, TS Errs: in 1, out 0 +TS: 640, dTS: 160, TS Errs: in 1, out 0 +TS: 800, dTS: 160, TS Errs: in 1, out 0 +TS: 960, dTS: 160, TS Errs: in 2, out 0 +TS: 1120, dTS: 160, TS Errs: in 3, out 0 +TS: 1280, dTS: 160, TS Errs: in 3, out 0 +TS: 1440, dTS: 160, TS Errs: in 4, out 0 +TS: 1600, dTS: 160, TS Errs: in 5, out 0 +TS: 1760, dTS: 160, TS Errs: in 5, out 0 Output SSRC changed to 10203040 -TS: 34688, dTS: 160, TS Errs: in 5, out 5 -TS: 34848, dTS: 160, TS Errs: in 5, out 5 -TS: 35008, dTS: 160, TS Errs: in 5, out 5 -TS: 35128, dTS: 120, TS Errs: in 6, out 6 -TS: 35288, dTS: 160, TS Errs: in 7, out 7 -TS: 35448, dTS: 160, TS Errs: in 7, out 7 -TS: 35768, dTS: 160, TS Errs: in 7, out 7 -TS: 35928, dTS: 160, TS Errs: in 7, out 7 -TS: 36088, dTS: 160, TS Errs: in 8, out 8 +TS: 34728, dTS: 160, TS Errs: in 5, out 0 +TS: 34888, dTS: 160, TS Errs: in 5, out 0 +TS: 35048, dTS: 160, TS Errs: in 5, out 0 +TS: 35208, dTS: 160, TS Errs: in 6, out 0 +TS: 35368, dTS: 160, TS Errs: in 7, out 0 +TS: 35528, dTS: 160, TS Errs: in 7, out 0 +TS: 35848, dTS: 160, TS Errs: in 7, out 0 +TS: 36008, dTS: 160, TS Errs: in 7, out 0 +TS: 36008, dTS: 160, TS Errs: in 8, out 0 Testing packet error detection, patch SSRC, patch timestamps. Output SSRC changed to 11223344 TS: 0, dTS: 0, TS Errs: in 0, out 0 TS: 160, dTS: 160, TS Errs: in 0, out 0 TS: 320, dTS: 160, TS Errs: in 0, out 0 -TS: 320, dTS: 160, TS Errs: in 1, out 1 -TS: 480, dTS: 160, TS Errs: in 1, out 1 -TS: 640, dTS: 160, TS Errs: in 1, out 1 -TS: 960, dTS: 320, TS Errs: in 2, out 2 -TS: 1120, dTS: 160, TS Errs: in 3, out 3 -TS: 1280, dTS: 160, TS Errs: in 3, out 3 -TS: 1400, dTS: 120, TS Errs: in 4, out 4 -TS: 1560, dTS: 160, TS Errs: in 5, out 5 -TS: 1720, dTS: 160, TS Errs: in 5, out 5 -TS: 1880, dTS: 160, TS Errs: in 5, out 5 -TS: 2040, dTS: 160, TS Errs: in 5, out 5 -TS: 2200, dTS: 160, TS Errs: in 5, out 5 -TS: 2320, dTS: 120, TS Errs: in 6, out 6 -TS: 2480, dTS: 160, TS Errs: in 7, out 7 -TS: 2640, dTS: 160, TS Errs: in 7, out 7 -TS: 2960, dTS: 160, TS Errs: in 7, out 7 -TS: 3120, dTS: 160, TS Errs: in 7, out 7 -TS: 3280, dTS: 160, TS Errs: in 8, out 8 +TS: 480, dTS: 160, TS Errs: in 1, out 0 +TS: 640, dTS: 160, TS Errs: in 1, out 0 +TS: 800, dTS: 160, TS Errs: in 1, out 0 +TS: 960, dTS: 160, TS Errs: in 2, out 0 +TS: 1120, dTS: 160, TS Errs: in 3, out 0 +TS: 1280, dTS: 160, TS Errs: in 3, out 0 +TS: 1440, dTS: 160, TS Errs: in 4, out 0 +TS: 1600, dTS: 160, TS Errs: in 5, out 0 +TS: 1760, dTS: 160, TS Errs: in 5, out 0 +TS: 1920, dTS: 160, TS Errs: in 5, out 0 +TS: 2080, dTS: 160, TS Errs: in 5, out 0 +TS: 2240, dTS: 160, TS Errs: in 5, out 0 +TS: 2400, dTS: 160, TS Errs: in 6, out 0 +TS: 2560, dTS: 160, TS Errs: in 7, out 0 +TS: 2720, dTS: 160, TS Errs: in 7, out 0 +TS: 3040, dTS: 160, TS Errs: in 7, out 0 +TS: 3200, dTS: 160, TS Errs: in 7, out 0 +TS: 3200, dTS: 160, TS Errs: in 8, out 0 Done |