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:
parent
31981a0051
commit
392736d38b
|
@ -70,6 +70,7 @@ struct rtp_socket {
|
|||
u_int16_t sequence;
|
||||
u_int32_t timestamp;
|
||||
u_int32_t ssrc;
|
||||
struct timeval last_tv;
|
||||
} transmit;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue