RTP Proxy: Fix RTP sequence number and timestamp in case of dropped frames

During handover, we will not send RTP frames for quite some time.  However,
the way the rtp_send code is structured, it will increment the timestamp
with a fixed amount every time we send a frame, independent how much wallclock
time has actually passed.

This code is a hack to update the sequence number and timestamp in case it
seems to be wrong.  It makes handover much more reliable.
This commit is contained in:
Harald Welte 2009-12-20 13:16:14 +01:00
parent 31981a0051
commit 392736d38b
2 changed files with 36 additions and 0 deletions

View File

@ -70,6 +70,7 @@ struct rtp_socket {
u_int16_t sequence;
u_int32_t timestamp;
u_int32_t ssrc;
struct timeval last_tv;
} transmit;
};

View File

@ -176,6 +176,21 @@ static int rtp_decode(struct msgb *msg, u_int32_t callref, struct msgb **data)
return 0;
}
/* "to - from" */
static void tv_difference(struct timeval *diff, const struct timeval *from,
const struct timeval *__to)
{
struct timeval _to = *__to, *to = &_to;
if (to->tv_usec < from->tv_usec) {
to->tv_sec -= 1;
to->tv_usec += 1000000;
}
diff->tv_usec = to->tv_usec - from->tv_usec;
diff->tv_sec = to->tv_sec - from->tv_sec;
}
/* encode and send a rtp frame */
int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame)
{
@ -211,6 +226,26 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame)
return -EINVAL;
}
{
struct timeval tv, tv_diff;
long int usec_diff, frame_diff;
gettimeofday(&tv, NULL);
tv_difference(&tv_diff, &rs->transmit.last_tv, &tv);
rs->transmit.last_tv = tv;
usec_diff = tv_diff.tv_sec * 1000000 + tv_diff.tv_usec;
frame_diff = (usec_diff / 20000);
if (abs(frame_diff) > 1) {
long int frame_diff_excess = frame_diff - 1;
DEBUGP(DMUX, "Correcting frame difference of %ld frames\n", frame_diff_excess);
rs->transmit.sequence += frame_diff_excess;
rs->transmit.timestamp += frame_diff_excess * duration;
}
}
msg = msgb_alloc(sizeof(struct rtp_hdr) + payload_len, "RTP-GSM-FULL");
if (!msg)
return -ENOMEM;