From 56c4681d8374328b7e50a755e09471bfb52e6b4a Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 21 May 2013 00:28:13 +0200 Subject: osmux: replay last RTP packet seen under packet loss scenario If osmux notices a gap between two RTP packets, fill it with the last RTP packet seen. Without this patch, 10% of packet loss is enough to get garbage, with it we get glitches in the conversation with 30%, and pretty much broken conversation with 40% of it. --- src/osmux.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'src') diff --git a/src/osmux.c b/src/osmux.c index c8e8557..33ab7ad 100644 --- a/src/osmux.c +++ b/src/osmux.c @@ -305,6 +305,54 @@ static int osmux_rtp_amr_payload_len(struct msgb *msg, struct rtp_hdr *rtph) return amr_len - sizeof(struct amr_hdr); } +static void osmux_replay_lost_packets(struct batch_list_node *node, + struct rtp_hdr *cur_rtph) +{ + uint16_t diff; + struct msgb *last; + struct rtp_hdr *rtph; + int i; + + /* Have we see any RTP packet in this batch before? */ + if (llist_empty(&node->list)) + return; + + /* Get last RTP packet seen in this batch */ + last = llist_entry(node->list.prev, struct msgb, list); + rtph = osmo_rtp_get_hdr(last); + if (rtph == NULL) + return; + + diff = ntohs(cur_rtph->sequence) - ntohs(rtph->sequence); + + /* If diff between last RTP packet seen and this one is > 1, + * then we lost several RTP packets, let's replay them. + */ + for (i=1; idata_len, "RTP clone"); + if (!clone) + continue; + + memcpy(clone->data, last->data, last->len); + msgb_put(clone, last->len); + + rtph = osmo_rtp_get_hdr(clone); + if (rtph == NULL) + return; + + /* Adjust sequence number and timestamp */ + rtph->sequence = htons(ntohs(rtph->sequence) + i); + rtph->timestamp = htonl(ntohl(rtph->timestamp) + + DELTA_RTP_TIMESTAMP); + + LOGP(DLMIB, LOGL_ERROR, "adding cloned RTP\n"); + llist_add_tail(&clone->list, &node->list); + } +} + static int osmux_batch_add(struct osmux_batch *batch, struct msgb *msg, int ccid) { @@ -352,6 +400,9 @@ osmux_batch_add(struct osmux_batch *batch, struct msgb *msg, int ccid) return 0; } } + /* Handle RTP packet loss scenario */ + osmux_replay_lost_packets(node, rtph); + } else { /* This is the first message with that ssrc we've seen */ node = talloc_zero(osmux_ctx, struct batch_list_node); -- cgit v1.2.3