aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libmgcp/mgcp_network.c
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2013-11-29 11:20:06 +0100
committerJacob Erlbeck <jerlbeck@sysmocom.de>2013-12-10 11:17:44 +0100
commit58340e5b5bfa37b09a61d544904330c1932ccfec (patch)
treef98ce03291a86ceb5e1d418569c8ed115a44b519 /openbsc/src/libmgcp/mgcp_network.c
parente2292f3aa1e9ae1faf5521a9cb108775f1ac0540 (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
Diffstat (limited to 'openbsc/src/libmgcp/mgcp_network.c')
-rw-r--r--openbsc/src/libmgcp/mgcp_network.c40
1 files changed, 31 insertions, 9 deletions
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,