summaryrefslogtreecommitdiff
path: root/main/channel.c
diff options
context:
space:
mode:
authorKevin Harwell <kharwell@digium.com>2017-01-12 15:58:43 -0600
committerKevin Harwell <kharwell@digium.com>2017-01-17 17:08:53 -0600
commit283c16c6b6136dfdb13b4fa6b524126e7aab1dfc (patch)
tree7d10831c547c294f629e7691295f244e8049bacf /main/channel.c
parentf4e77a5678ac8babeff853988941bf821b5d23cf (diff)
abstract/fixed/adpative jitter buffer: disallow frame re-inserts
It was possible for a frame to be re-inserted into a jitter buffer after it had been removed from it. A case when this happened was if a frame was read out of the jitterbuffer, passed to the translation core, and then multiple frames were returned from said translation core. Upon multiple frames being returned the first is passed on, but sebsequently "chained" frames are put back into the read queue. Thus it was possible for a frame to go back into the jitter buffer where this would cause problems. This patch adds a flag to frames that are inserted into the channel's read queue after translation. The abstract jitter buffer code then checks for this flag and ignores any frames marked as such. Change-Id: I276c44edc9dcff61e606242f71274265c7779587
Diffstat (limited to 'main/channel.c')
-rw-r--r--main/channel.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/main/channel.c b/main/channel.c
index 00cfa31aa..4f8471743 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -4333,12 +4333,19 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
* at the end of the queue.
*/
if (AST_LIST_NEXT(f, frame_list)) {
+ struct ast_frame *cur, *multi_frame = AST_LIST_NEXT(f, frame_list);
+
+ /* Mark these frames as being re-queued */
+ for (cur = multi_frame; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
+ ast_set_flag(cur, AST_FRFLAG_REQUEUED);
+ }
+
if (!readq_tail) {
- ast_queue_frame_head(chan, AST_LIST_NEXT(f, frame_list));
+ ast_queue_frame_head(chan, multi_frame);
} else {
- __ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list), 0, readq_tail);
+ __ast_queue_frame(chan, multi_frame, 0, readq_tail);
}
- ast_frfree(AST_LIST_NEXT(f, frame_list));
+ ast_frfree(multi_frame);
AST_LIST_NEXT(f, frame_list) = NULL;
}