aboutsummaryrefslogtreecommitdiffstats
path: root/channels/chan_iax2.c
diff options
context:
space:
mode:
authortilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2008-07-08 16:50:29 +0000
committertilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2008-07-08 16:50:29 +0000
commitbfb56b11bbc17ebcb3df012dada630ae22397c01 (patch)
tree8650dfae326050e3fa3512e73e1650edc17dc90e /channels/chan_iax2.c
parent3b5c2f2ec9a1f1b932a72c54ec99f2ade7b874e5 (diff)
Merged revisions 129048 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk ................ r129048 | tilghman | 2008-07-08 11:49:01 -0500 (Tue, 08 Jul 2008) | 15 lines Merged revisions 129047 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r129047 | tilghman | 2008-07-08 11:45:23 -0500 (Tue, 08 Jul 2008) | 7 lines Timestamp decoding for video mini-frames is bogus, because the timestamp only includes 15 bits, unlike voice frames, which contain a 16-bit timestamp. (closes issue #13013) Reported by: jpgrayson Patches: chan_iax2_unwrap_ts.patch uploaded by jpgrayson (license 492) ........ ................ git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.0@129049 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels/chan_iax2.c')
-rw-r--r--channels/chan_iax2.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index a4c977b83..fff9a2702 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -2802,25 +2802,31 @@ static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
static void unwrap_timestamp(struct iax_frame *fr)
{
- int x;
-
- if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) {
- x = fr->ts - iaxs[fr->callno]->last;
- if (x < -50000) {
+ /* Video mini frames only encode the lower 15 bits of the session
+ * timestamp, but other frame types (e.g. audio) encode 16 bits. */
+ const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
+ const int lower_mask = (1 << ts_shift) - 1;
+ const int upper_mask = ~lower_mask;
+ const int last_upper = iaxs[fr->callno]->last & upper_mask;
+
+ if ( (fr->ts & upper_mask) == last_upper ) {
+ const int x = fr->ts - iaxs[fr->callno]->last;
+ const int threshold = (ts_shift == 15) ? 25000 : 50000;
+
+ if (x < -threshold) {
/* Sudden big jump backwards in timestamp:
What likely happened here is that miniframe timestamp has circled but we haven't
gotten the update from the main packet. We'll just pretend that we did, and
update the timestamp appropriately. */
- fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF);
+ fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
if (iaxdebug)
ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
- }
- if (x > 50000) {
+ } else if (x > threshold) {
/* Sudden apparent big jump forwards in timestamp:
What's likely happened is this is an old miniframe belonging to the previous
- top-16-bit timestamp that has turned up out of order.
+ top 15 or 16-bit timestamp that has turned up out of order.
Adjust the timestamp appropriately. */
- fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF);
+ fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
if (iaxdebug)
ast_debug(1, "schedule_delivery: pushed back timestamp\n");
}