--- channel.c.orig Sun Jul 29 19:53:10 2007 +++ channel.c Sun Jul 29 22:31:24 2007 @@ -895,9 +895,10 @@ int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin) { struct ast_frame *f; - struct ast_frame *cur; + struct ast_frame *prev, *cur, *next; int blah = 1; int qlen = 0; + int vqlen = 0; /* Build us a copy and free the original one */ if (!(f = ast_frdup(fin))) { @@ -905,6 +906,46 @@ return -1; } ast_channel_lock(chan); + + /* + * Drop any previous voice frames beyond the limit. + */ + + /* + * First count up how many voice frames that we have. + */ + AST_LIST_TRAVERSE(&chan->readq, cur, frame_list) { + if (cur->frametype == AST_FRAME_VOICE) { + vqlen++; + } + } + + /* + * Now drop voice frames past the limit. + */ + prev = cur = AST_LIST_FIRST(&chan->readq); + while (cur && vqlen > 2) { + next = AST_LIST_NEXT(cur, frame_list); + if (cur->frametype == AST_FRAME_VOICE) { + /* remove from queue */ + if (cur == AST_LIST_FIRST(&chan->readq)) { + AST_LIST_INSERT_TAIL(&chan->readq, next, frame_list); + } else { + /*prev->next = next;*/ + AST_LIST_INSERT_AFTER(&chan->readq, prev, next, frame_list); + } + ast_frfree(cur); + vqlen--; + } else { + prev = cur; + } + cur = next; + } + + prev = NULL; + next = NULL; + cur = AST_LIST_FIRST(&chan->readq); + /* See if the last frame on the queue is a hangup, if so don't queue anything */ if ((cur = AST_LIST_LAST(&chan->readq)) && (cur->frametype == AST_FRAME_CONTROL) && (cur->subclass == AST_CONTROL_HANGUP)) {