summaryrefslogtreecommitdiff
path: root/main/abstract_jb.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/abstract_jb.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/abstract_jb.c')
-rw-r--r--main/abstract_jb.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/main/abstract_jb.c b/main/abstract_jb.c
index 264ee97e6..0f0e6613f 100644
--- a/main/abstract_jb.c
+++ b/main/abstract_jb.c
@@ -65,6 +65,7 @@ static long jb_next_fixed(void *jb);
static int jb_remove_fixed(void *jb, struct ast_frame **fout);
static void jb_force_resynch_fixed(void *jb);
static void jb_empty_and_reset_fixed(void *jb);
+static int jb_is_late_fixed(void *jb, long ts);
/* adaptive */
static void * jb_create_adaptive(struct ast_jb_conf *general_config);
static void jb_destroy_adaptive(void *jb);
@@ -75,6 +76,7 @@ static long jb_next_adaptive(void *jb);
static int jb_remove_adaptive(void *jb, struct ast_frame **fout);
static void jb_force_resynch_adaptive(void *jb);
static void jb_empty_and_reset_adaptive(void *jb);
+static int jb_is_late_adaptive(void *jb, long ts);
/* Available jb implementations */
static const struct ast_jb_impl avail_impl[] = {
@@ -90,6 +92,7 @@ static const struct ast_jb_impl avail_impl[] = {
.remove = jb_remove_fixed,
.force_resync = jb_force_resynch_fixed,
.empty_and_reset = jb_empty_and_reset_fixed,
+ .is_late = jb_is_late_fixed,
},
{
.name = "adaptive",
@@ -103,6 +106,7 @@ static const struct ast_jb_impl avail_impl[] = {
.remove = jb_remove_adaptive,
.force_resync = jb_force_resynch_adaptive,
.empty_and_reset = jb_empty_and_reset_adaptive,
+ .is_late = jb_is_late_adaptive,
}
};
@@ -704,6 +708,11 @@ static void jb_empty_and_reset_fixed(void *jb)
}
}
+static int jb_is_late_fixed(void *jb, long ts)
+{
+ return fixed_jb_is_late(jb, ts);
+}
+
/* adaptive */
static void *jb_create_adaptive(struct ast_jb_conf *general_config)
@@ -810,6 +819,11 @@ const struct ast_jb_impl *ast_jb_get_impl(enum ast_jb_type type)
return NULL;
}
+static int jb_is_late_adaptive(void *jb, long ts)
+{
+ return jb_is_late(jb, ts);
+}
+
#define DEFAULT_TIMER_INTERVAL 20
#define DEFAULT_SIZE 200
#define DEFAULT_TARGET_EXTRA 40
@@ -893,7 +907,22 @@ static struct ast_frame *hook_event_cb(struct ast_channel *chan, struct ast_fram
}
}
- if (!frame) {
+ /*
+ * If the frame has been requeued (for instance when the translate core returns
+ * more than one frame) then if the frame is late we want to immediately return
+ * it. Otherwise attempt to insert it into the jitterbuffer.
+ *
+ * If the frame is requeued and late then in all likely hood it's a frame that
+ * that was previously retrieved from the jitterbuffer, passed to the translate
+ * core, and then put back into the channel read queue. Even if it had not been
+ * in the jitterbuffer prior to now it needs to be the next frame "out".
+ *
+ * However late arriving frames that have not been requeued (i.e. regular frames)
+ * need to be passed to the jitterbuffer so they can be appropriately dropped. As
+ * well any requeued frames that are not late should be put into the jitterbuffer.
+ */
+ if (!frame || (ast_test_flag(frame, AST_FRFLAG_REQUEUED) &&
+ framedata->jb_impl->is_late(framedata->jb_obj, frame->ts))) {
return frame;
}