diff options
Diffstat (limited to 'openbsc/src/rtp_proxy.c')
-rw-r--r-- | openbsc/src/rtp_proxy.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/openbsc/src/rtp_proxy.c b/openbsc/src/rtp_proxy.c index 551349750..02938125a 100644 --- a/openbsc/src/rtp_proxy.c +++ b/openbsc/src/rtp_proxy.c @@ -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; |