[Asterisk-bsd] MeetMe drift

David G Lawrence dg228 at dglawrence.com
Fri Jul 27 19:38:38 CDT 2007


>    Attached is a slightly improved version of my ztdummy.c that should work
> if system HZ is larger than 1000.

   I should probably also point out that while this may help your problem,
it won't completely solve it because it is only one piece of the puzzle.
The timer inaccuracy results in extra conference latency over time, but
the other problem is that delays in scheduling the Asterisk process can
cause big and sudden jumps in latency that this new ztdummy.c won't fix.
   The real problem is that Asterisk allows voice packets to back up in
its input queue, and that has an unbounded queue depth.
   Attached is a patch to Asterisk's channel.c that limits the queue
depth of voice frames to a maximum of just 2 frames (40ms) on the channel
input queue. Under certain circumstances, this may result in an occasional
dropped voice frame, but that is better in my opinion than adding extra
latency to the call.

-DG

David G. Lawrence
President
Download Technologies, Inc. - http://www.downloadtech.com - (866) 399 8500
The FreeBSD Project - http://www.freebsd.org
Pave the road of life with opportunities.
-------------- next part --------------
*** channel.c.orig	Wed Sep 27 09:54:30 2006
--- channel.c	Tue May  1 23:27:35 2007
***************
*** 611,619 ****
  int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin)
  {
  	struct ast_frame *f;
! 	struct ast_frame *prev, *cur;
  	int blah = 1;
  	int qlen = 0;
  
  	/* Build us a copy and free the original one */
  	f = ast_frdup(fin);
--- 611,620 ----
  int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin)
  {
  	struct ast_frame *f;
! 	struct ast_frame *prev, *cur, *next;
  	int blah = 1;
  	int qlen = 0;
+ 	int vqlen = 0;
  
  	/* Build us a copy and free the original one */
  	f = ast_frdup(fin);
***************
*** 622,629 ****
--- 623,668 ----
  		return -1;
  	}
  	ast_mutex_lock(&chan->lock);
+ 
+ 	/*
+ 	 * Drop any previous voice frames beyond the limit.
+ 	 */
+ 
+ 	/*
+ 	 * First count up how many voice frames that we have.
+ 	 */
+ 	prev = cur = chan->readq;
+ 	while (cur) {
+ 		next = cur->next;
+ 		if (cur->frametype == AST_FRAME_VOICE) {
+ 			vqlen++;
+ 		}
+ 		cur = next;
+ 	}
+ 	/*
+ 	 * Now drop voice frames past the limit.
+ 	 */
+ 	prev = cur = chan->readq;
+ 	while (cur && vqlen > 2) {
+ 		next = cur->next;
+ 		if (cur->frametype == AST_FRAME_VOICE) {
+ 			/* remove from queue */
+ 			if (cur == chan->readq) {
+ 				chan->readq = next;
+ 			} else {
+ 				prev->next = next;
+ 			}
+ 			ast_frfree(cur);
+ 			vqlen--;
+ 		} else {
+ 			prev = cur;
+ 		}
+ 		cur = next;
+ 	}
+ 
  	prev = NULL;
  	cur = chan->readq;
+ 
  	while(cur) {
  		if ((cur->frametype == AST_FRAME_CONTROL) && (cur->subclass == AST_CONTROL_HANGUP)) {
  			/* Don't bother actually queueing anything after a hangup */


More information about the Asterisk-BSD mailing list