aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libmgcp
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2013-11-25 15:23:35 +0100
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2013-11-25 18:30:50 +0100
commit72c309021a386a0ecc91784cc262892b6d2561e8 (patch)
tree08673913a4e6ae3c007f16c380aed08530822330 /openbsc/src/libmgcp
parentd62419b574f7002b1c857d9e2df72a95daca36f1 (diff)
mgcp/rtp: Fix timestamp offset when patching RTP packets
The current implementation increments the seqno but does not increment the RTP timestamp, leading to two identical timestamps following one after the other. This patch fixes this by adding the computed tsdelta when the offset is calulated. In the unlikely case, that a tsdelta hasn't been computed yet when the SSRC changes, a tsdelta is computed based on the RTP rate and a RTP packet duration of 20ms (one speech frame per channel and packet). If the RTP rate is not known, a rate of 8000 is assumed. Note that this approach presumes, that the per RTP packet duration (in samples) is the same for the last two packets of the stream being replaced (the first one). Sponsored-by: On-Waves ehf
Diffstat (limited to 'openbsc/src/libmgcp')
-rw-r--r--openbsc/src/libmgcp/mgcp_network.c23
-rw-r--r--openbsc/src/libmgcp/mgcp_protocol.c12
2 files changed, 31 insertions, 4 deletions
diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c
index 72d0a5c32..75d39c195 100644
--- a/openbsc/src/libmgcp/mgcp_network.c
+++ b/openbsc/src/libmgcp/mgcp_network.c
@@ -238,15 +238,30 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta
state->transit = arrival_time - timestamp;
state->out_stream = state->in_stream;
} else if (state->in_stream.ssrc != rtp_hdr->ssrc) {
+ int32_t tsdelta = state->out_stream.last_tsdelta;
+ if (tsdelta == 0) {
+ tsdelta = rtp_end->rate * rtp_end->frames_per_packet *
+ rtp_end->frame_duration_num /
+ rtp_end->frame_duration_den;
+ LOGP(DMGCP, LOGL_NOTICE,
+ "Computed timestamp delta %d based on "
+ "rate %d, num frames %d, frame duration %d/%d\n",
+ tsdelta, rtp_end->rate, rtp_end->frames_per_packet,
+ rtp_end->frame_duration_num,
+ rtp_end->frame_duration_den);
+ }
state->in_stream.ssrc = rtp_hdr->ssrc;
state->seq_offset = (state->out_stream.last_seq + 1) - seq;
- state->timestamp_offset = state->out_stream.last_timestamp - timestamp;
+ state->timestamp_offset =
+ (state->out_stream.last_timestamp + tsdelta) - timestamp;
state->patch = endp->allow_patch;
LOGP(DMGCP, LOGL_NOTICE,
- "The SSRC changed on 0x%x SSRC: %u offset: %d from %s:%d in %d\n",
+ "The SSRC changed on 0x%x SSRC: %u offset: %d tsdelta: %d "
+ "from %s:%d in %d\n",
ENDPOINT_NUMBER(endp), state->in_stream.ssrc,
- state->seq_offset, inet_ntoa(addr->sin_addr),
- ntohs(addr->sin_port), endp->conn_mode);
+ state->seq_offset, tsdelta,
+ inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
+ endp->conn_mode);
state->in_stream.last_tsdelta = 0;
} else {
diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c
index aec2cb0a4..70964958a 100644
--- a/openbsc/src/libmgcp/mgcp_protocol.c
+++ b/openbsc/src/libmgcp/mgcp_protocol.c
@@ -40,6 +40,12 @@
for (line = strtok_r(NULL, "\r\n", &save); line;\
line = strtok_r(NULL, "\r\n", &save))
+/* Assume audio frame length of 20ms */
+#define DEFAULT_RTP_AUDIO_FRAME_DUR_NUM 20
+#define DEFAULT_RTP_AUDIO_FRAME_DUR_DEN 1000
+#define DEFAULT_RTP_AUDIO_FRAMES_PER_PACKET 1
+#define DEFAULT_RTP_AUDIO_DEFAULT_RATE 8000
+
static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end);
struct mgcp_parse_data {
@@ -965,6 +971,12 @@ static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end)
end->local_alloc = -1;
talloc_free(end->fmtp_extra);
end->fmtp_extra = NULL;
+
+ /* Set default values */
+ end->frame_duration_num = DEFAULT_RTP_AUDIO_FRAME_DUR_NUM;
+ end->frame_duration_den = DEFAULT_RTP_AUDIO_FRAME_DUR_DEN;
+ end->frames_per_packet = DEFAULT_RTP_AUDIO_FRAMES_PER_PACKET;
+ end->rate = DEFAULT_RTP_AUDIO_DEFAULT_RATE;
}
static void mgcp_rtp_end_init(struct mgcp_rtp_end *end)