aboutsummaryrefslogtreecommitdiffstats
path: root/channel.c
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2006-05-31 16:56:50 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2006-05-31 16:56:50 +0000
commit1264d306ef99444c139d5467f47ae6bc50a296b2 (patch)
tree24a5e287490aa56d6fad0961d8832f1ba7eea1fd /channel.c
parente625fbb2b0a0a5c31c3c18cf4ee225d54b73c2ba (diff)
Add support for using a jitterbuffer for RTP on bridged calls. This includes
a new implementation of a fixed size jitterbuffer, as well as support for the existing adaptive jitterbuffer implementation. (issue #3854, Slav Klenov) Thank you very much to Slav Klenov of Securax and all of the people involved in the testing of this feature for all of your hard work! git-svn-id: http://svn.digium.com/svn/asterisk/trunk@31052 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channel.c')
-rw-r--r--channel.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/channel.c b/channel.c
index 59789e93f..545e00231 100644
--- a/channel.c
+++ b/channel.c
@@ -1012,6 +1012,9 @@ void ast_channel_free(struct ast_channel *chan)
while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
ast_var_delete(vardata);
+ /* Destroy the jitterbuffer */
+ ast_jb_destroy(chan);
+
ast_string_field_free_all(chan);
free(chan);
AST_LIST_UNLOCK(&channels);
@@ -3303,6 +3306,9 @@ static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct
int watch_c0_dtmf;
int watch_c1_dtmf;
void *pvt0, *pvt1;
+ /* Indicates whether a frame was queued into a jitterbuffer */
+ int frame_put_in_jb = 0;
+ int jb_in_use;
int to;
cs[0] = c0;
@@ -3314,6 +3320,9 @@ static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct
watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
+ /* Check the need of a jitterbuffer for each channel */
+ jb_in_use = ast_jb_do_usecheck(c0, c1);
+
for (;;) {
struct ast_channel *who, *other;
@@ -3332,9 +3341,15 @@ static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct
}
} else
to = -1;
+ /* Calculate the appropriate max sleep interval - in general, this is the time,
+ left to the closest jb delivery moment */
+ if (jb_in_use)
+ to = ast_jb_get_when_to_wakeup(c0, c1, to);
who = ast_waitfor_n(cs, 2, &to);
if (!who) {
- ast_log(LOG_DEBUG, "Nobody there, continuing...\n");
+ /* No frame received within the specified timeout - check if we have to deliver now */
+ if (jb_in_use)
+ ast_jb_get_and_deliver(c0, c1);
if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
c0->_softhangup = 0;
@@ -3354,6 +3369,9 @@ static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct
}
other = (who == c0) ? c1 : c0; /* the 'other' channel */
+ /* Try add the frame info the who's bridged channel jitterbuff */
+ if (jb_in_use)
+ frame_put_in_jb = !ast_jb_put(other, f);
if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
int bridge_exit = 0;
@@ -3390,8 +3408,13 @@ static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct
ast_log(LOG_DEBUG, "Got DTMF on channel (%s)\n", who->name);
break;
}
- /* other frames go to the other side */
- ast_write(other, f);
+ /* Write immediately frames, not passed through jb */
+ if (!frame_put_in_jb)
+ ast_write(other, f);
+
+ /* Check if we have to deliver now */
+ if (jb_in_use)
+ ast_jb_get_and_deliver(c0, c1);
}
/* XXX do we want to pass on also frames not matched above ? */
ast_frfree(f);