[asterisk-commits] trunk r31052 - in /trunk: ./ channels/ configs/
include/asterisk/
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Wed May 31 09:56:51 MST 2006
Author: russell
Date: Wed May 31 11:56:50 2006
New Revision: 31052
URL: http://svn.digium.com/view/asterisk?rev=31052&view=rev
Log:
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!
Added:
trunk/include/asterisk/abstract_jb.h (with props)
trunk/scx_jitterbuf.c (with props)
trunk/scx_jitterbuf.h (with props)
Modified:
trunk/.cleancount
trunk/Makefile
trunk/channel.c
trunk/channels/chan_alsa.c
trunk/channels/chan_iax2.c
trunk/channels/chan_oss.c
trunk/channels/chan_sip.c
trunk/channels/chan_zap.c
trunk/configs/alsa.conf.sample
trunk/configs/oss.conf.sample
trunk/configs/sip.conf.sample
trunk/configs/zapata.conf.sample
trunk/frame.c
trunk/include/asterisk/channel.h
trunk/include/asterisk/frame.h
trunk/rtp.c
trunk/translate.c
Modified: trunk/.cleancount
URL: http://svn.digium.com/view/asterisk/trunk/.cleancount?rev=31052&r1=31051&r2=31052&view=diff
==============================================================================
--- trunk/.cleancount (original)
+++ trunk/.cleancount Wed May 31 11:56:50 2006
@@ -1,1 +1,1 @@
-17
+18
Modified: trunk/Makefile
URL: http://svn.digium.com/view/asterisk/trunk/Makefile?rev=31052&r1=31051&r2=31052&view=diff
==============================================================================
--- trunk/Makefile (original)
+++ trunk/Makefile Wed May 31 11:56:50 2006
@@ -282,7 +282,7 @@
astmm.o enum.o srv.o dns.o aescrypt.o aestab.o aeskey.o \
utils.o plc.o jitterbuf.o dnsmgr.o devicestate.o \
netsock.o slinfactory.o ast_expr2.o ast_expr2f.o \
- cryptostub.o sha1.o http.o
+ cryptostub.o sha1.o http.o scx_jitterbuf.o abstract_jb.o
# we need to link in the objects statically, not as a library, because
# otherwise modules will not have them available if none of the static
Modified: trunk/channel.c
URL: http://svn.digium.com/view/asterisk/trunk/channel.c?rev=31052&r1=31051&r2=31052&view=diff
==============================================================================
--- trunk/channel.c (original)
+++ trunk/channel.c Wed May 31 11:56:50 2006
@@ -1011,6 +1011,9 @@
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);
@@ -3303,6 +3306,9 @@
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 @@
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 @@
}
} 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 @@
}
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 @@
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);
Modified: trunk/channels/chan_alsa.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_alsa.c?rev=31052&r1=31051&r2=31052&view=diff
==============================================================================
--- trunk/channels/chan_alsa.c (original)
+++ trunk/channels/chan_alsa.c Wed May 31 11:56:50 2006
@@ -69,6 +69,17 @@
#ifdef ALSA_MONITOR
#include "alsa-monitor.h"
#endif
+
+#include "asterisk/abstract_jb.h"
+/* Global jitterbuffer configuration - by default, jb is disabled */
+static struct ast_jb_conf default_jbconf =
+{
+ .flags = 0,
+ .max_size = -1,
+ .resync_threshold = -1,
+ .impl = ""
+};
+static struct ast_jb_conf global_jbconf;
#define DEBUG 0
/* Which device to use */
@@ -812,6 +823,8 @@
tmp = NULL;
}
}
+ if (tmp)
+ ast_jb_configure(tmp, &global_jbconf);
}
return tmp;
}
@@ -1051,9 +1064,18 @@
int x;
struct ast_config *cfg;
struct ast_variable *v;
+
+ /* Copy the default jb config over global_jbconf */
+ memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
+
if ((cfg = ast_config_load(config))) {
v = ast_variable_browse(cfg, "general");
while(v) {
+ /* handle jb conf */
+ if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) {
+ v = v->next;
+ continue;
+ }
if (!strcasecmp(v->name, "autoanswer"))
autoanswer = ast_true(v->value);
else if (!strcasecmp(v->name, "silencesuppression"))
Modified: trunk/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_iax2.c?rev=31052&r1=31051&r2=31052&view=diff
==============================================================================
--- trunk/channels/chan_iax2.c (original)
+++ trunk/channels/chan_iax2.c Wed May 31 11:56:50 2006
@@ -1543,6 +1543,7 @@
the IAX thread with the iaxsl lock held. */
struct iax_frame *fr = data;
fr->retrans = -1;
+ fr->af.has_timing_info = 0;
if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
iax2_queue_frame(fr->callno, &fr->af);
/* Free our iax frame */
Modified: trunk/channels/chan_oss.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_oss.c?rev=31052&r1=31051&r2=31052&view=diff
==============================================================================
--- trunk/channels/chan_oss.c (original)
+++ trunk/channels/chan_oss.c Wed May 31 11:56:50 2006
@@ -82,6 +82,17 @@
#include "ring10.h"
#include "answer.h"
+#include "asterisk/abstract_jb.h"
+/* Global jitterbuffer configuration - by default, jb is disabled */
+static struct ast_jb_conf default_jbconf =
+{
+ .flags = 0,
+ .max_size = -1,
+ .resync_threshold = -1,
+ .impl = ""
+};
+static struct ast_jb_conf global_jbconf;
+
/*
* Basic mode of operation:
*
@@ -140,6 +151,33 @@
; unless you know what you are doing.
; queuesize = 10 ; frames in device driver
; frags = 8 ; argument to SETFRAGMENT
+
+ ;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
+ ; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of an
+ ; OSS channel. Defaults to "no". An enabled jitterbuffer will
+ ; be used only if the sending side can create and the receiving
+ ; side can not accept jitter. The ZAP channel can't accept jitter,
+ ; thus an enabled jitterbuffer on the receive ZAP side will always
+ ; be used if the sending side can create jitter or if ZAP jb is
+ ; forced.
+
+ ; jbforce = no ; Forces the use of a jitterbuffer on the receive side of a ZAP
+ ; channel. Defaults to "no".
+
+ ; jbmaxsize = 200 ; Max length of the jitterbuffer in milliseconds.
+
+ ; jbresyncthreshold = 1000 ; Jump in the frame timestamps over which the jitterbuffer is
+ ; resynchronized. Useful to improve the quality of the voice, with
+ ; big jumps in/broken timestamps, usualy sent from exotic devices
+ ; and programs. Defaults to 1000.
+
+ ; jbimpl = fixed ; Jitterbuffer implementation, used on the receiving side of a SIP
+ ; channel. Two implementation are currenlty available - "fixed"
+ ; (with size always equals to jbmax-size) and "adaptive" (with
+ ; variable size, actually the new jb of IAX2). Defaults to fixed.
+
+ ; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
+ ;-----------------------------------------------------------------------------------
[card1]
; device = /dev/dsp1 ; alternate device
@@ -981,6 +1019,9 @@
/* XXX what about usecnt ? */
}
}
+ if (c)
+ ast_jb_configure(c, &global_jbconf);
+
return c;
}
@@ -1407,6 +1448,10 @@
for (v = ast_variable_browse(cfg, ctg);v; v=v->next) {
M_START(v->name, v->value);
+ /* handle jb conf */
+ if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
+ continue;
+
M_BOOL("autoanswer", o->autoanswer)
M_BOOL("autohangup", o->autohangup)
M_BOOL("overridecontext", o->overridecontext)
@@ -1472,6 +1517,9 @@
int i;
struct ast_config *cfg;
+ /* Copy the default jb config over global_jbconf */
+ memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
+
/* load config file */
cfg = ast_config_load(config);
if (cfg != NULL) {
Modified: trunk/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_sip.c?rev=31052&r1=31051&r2=31052&view=diff
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Wed May 31 11:56:50 2006
@@ -201,6 +201,17 @@
#define SIP_MAX_PACKET 4096 /*!< Also from RFC 3261 (2543), should sub headers tho */
#define INITIAL_CSEQ 101 /*!< our initial sip sequence number */
+
+#include "asterisk/abstract_jb.h"
+/* Global jitterbuffer configuration - by default, jb is disabled */
+static struct ast_jb_conf default_jbconf =
+{
+ .flags = 0,
+ .max_size = -1,
+ .resync_threshold = -1,
+ .impl = ""
+};
+static struct ast_jb_conf global_jbconf;
static const char tdesc[] = "Session Initiation Protocol (SIP)";
static const char config[] = "sip.conf";
@@ -850,6 +861,7 @@
struct ast_variable *chanvars; /*!< Channel variables to set for inbound call */
struct sip_pvt *next; /*!< Next dialog in chain */
struct sip_invite_param *options; /*!< Options for INVITE */
+ struct ast_jb_conf jbconf;
} *iflist = NULL;
#define FLAG_RESPONSE (1 << 0)
@@ -1256,7 +1268,7 @@
.type = "SIP",
.description = "Session Initiation Protocol (SIP)",
.capabilities = ((AST_FORMAT_MAX_AUDIO << 1) - 1),
- .properties = AST_CHAN_TP_WANTSJITTER,
+ .properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
.requester = sip_request_call,
.devicestate = sip_devicestate,
.call = sip_call,
@@ -3312,7 +3324,11 @@
if (recordhistory)
append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid);
-
+
+ /* Configure the new channel jb */
+ if (tmp && i && i->rtp)
+ ast_jb_configure(tmp, &i->jbconf);
+
return tmp;
}
@@ -3646,6 +3662,9 @@
(ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
p->noncodeccapability |= AST_RTP_DTMF;
ast_string_field_set(p, context, default_context);
+
+ /* Assign default jb conf to the new sip_pvt */
+ memcpy(&p->jbconf, &global_jbconf, sizeof(struct ast_jb_conf));
/* Add to active dialog list */
ast_mutex_lock(&iflock);
@@ -13247,7 +13266,6 @@
for (; v; v = v->next) {
if (handle_common_options(&peerflags[0], &mask[0], v))
continue;
-
if (realtime && !strcasecmp(v->name, "regseconds")) {
ast_get_time_t(v->value, ®seconds, 0, NULL);
} else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) {
@@ -13540,11 +13558,18 @@
global_relaxdtmf = FALSE;
global_callevents = FALSE;
global_t1min = DEFAULT_T1MIN;
+
+ /* Copy the default jb config over global_jbconf */
+ memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
+
ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT);
/* Read the [general] config section of sip.conf (or from realtime config) */
for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
if (handle_common_options(&global_flags[0], &dummy[0], v))
+ continue;
+ /* handle jb conf */
+ if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
continue;
/* Create the interface list */
Modified: trunk/channels/chan_zap.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_zap.c?rev=31052&r1=31051&r2=31052&view=diff
==============================================================================
--- trunk/channels/chan_zap.c (original)
+++ trunk/channels/chan_zap.c Wed May 31 11:56:50 2006
@@ -108,6 +108,17 @@
#include "asterisk/astobj.h"
#define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
#endif
+
+#include "asterisk/abstract_jb.h"
+/* Global jitterbuffer configuration - by default, jb is disabled */
+static struct ast_jb_conf default_jbconf =
+{
+ .flags = 0,
+ .max_size = -1,
+ .resync_threshold = -1,
+ .impl = ""
+};
+static struct ast_jb_conf global_jbconf;
#if !defined(ZT_SIG_EM_E1) || (defined(HAVE_LIBPRI) && !defined(ZT_SIG_HARDHDLC))
#error "Your zaptel is too old. please update"
@@ -684,6 +695,7 @@
#endif
int polarity;
int dsp_features;
+ struct ast_jb_conf jbconf;
} *iflist = NULL, *ifend = NULL;
@@ -5195,6 +5207,9 @@
}
} else
ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
+ /* Configure the new channel jb */
+ if (tmp && i)
+ ast_jb_configure(tmp, &i->jbconf);
return tmp;
}
@@ -6988,6 +7003,8 @@
for (x=0;x<3;x++)
tmp->subs[x].zfd = -1;
tmp->channel = channel;
+ /* Assign default jb conf to the new zt_pvt */
+ memcpy(&tmp->jbconf, &global_jbconf, sizeof(struct ast_jb_conf));
}
if (tmp) {
@@ -10200,6 +10217,7 @@
{
struct ast_config *cfg;
struct ast_variable *v;
+ struct ast_variable *vjb;
struct zt_pvt *tmp;
char *chan;
char *c;
@@ -10289,6 +10307,11 @@
}
#endif
v = ast_variable_browse(cfg, "channels");
+ /* Copy the default jb config over global_jbconf */
+ memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
+ /* Traverse all variables to handle jb conf */
+ for (vjb = v; vjb; vjb = vjb->next)
+ ast_jb_read_conf(&global_jbconf, vjb->name, vjb->value);
while(v) {
/* Create the interface list */
if (!strcasecmp(v->name, "channel")
Modified: trunk/configs/alsa.conf.sample
URL: http://svn.digium.com/view/asterisk/trunk/configs/alsa.conf.sample?rev=31052&r1=31051&r2=31052&view=diff
==============================================================================
--- trunk/configs/alsa.conf.sample (original)
+++ trunk/configs/alsa.conf.sample Wed May 31 11:56:50 2006
@@ -29,3 +29,31 @@
; To set which ALSA device to use, change this parameter
;input_device=hw:0,0
;output_device=hw:0,0
+
+;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
+; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of an
+ ; ALSA channel. Defaults to "no". An enabled jitterbuffer will
+ ; be used only if the sending side can create and the receiving
+ ; side can not accept jitter. The ZAP channel can't accept jitter,
+ ; thus an enabled jitterbuffer on the receive ZAP side will always
+ ; be used if the sending side can create jitter or if ZAP jb is
+ ; forced.
+
+; jbforce = no ; Forces the use of a jitterbuffer on the receive side of a ZAP
+ ; channel. Defaults to "no".
+
+; jbmaxsize = 200 ; Max length of the jitterbuffer in milliseconds.
+
+; jbresyncthreshold = 1000 ; Jump in the frame timestamps over which the jitterbuffer is
+ ; resynchronized. Useful to improve the quality of the voice, with
+ ; big jumps in/broken timestamps, usualy sent from exotic devices
+ ; and programs. Defaults to 1000.
+
+; jbimpl = fixed ; Jitterbuffer implementation, used on the receiving side of a SIP
+ ; channel. Two implementation are currenlty available - "fixed"
+ ; (with size always equals to jbmax-size) and "adaptive" (with
+ ; variable size, actually the new jb of IAX2). Defaults to fixed.
+
+; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
+;-----------------------------------------------------------------------------------
+
Modified: trunk/configs/oss.conf.sample
URL: http://svn.digium.com/view/asterisk/trunk/configs/oss.conf.sample?rev=31052&r1=31051&r2=31052&view=diff
==============================================================================
--- trunk/configs/oss.conf.sample (original)
+++ trunk/configs/oss.conf.sample Wed May 31 11:56:50 2006
@@ -46,6 +46,34 @@
; queuesize = 10 ; frames in device driver
; frags = 8 ; argument to SETFRAGMENT
+ ;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
+ ; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of an
+ ; OSS channel. Defaults to "no". An enabled jitterbuffer will
+ ; be used only if the sending side can create and the receiving
+ ; side can not accept jitter. The ZAP channel can't accept jitter,
+ ; thus an enabled jitterbuffer on the receive ZAP side will always
+ ; be used if the sending side can create jitter or if ZAP jb is
+ ; forced.
+
+ ; jbforce = no ; Forces the use of a jitterbuffer on the receive side of a ZAP
+ ; channel. Defaults to "no".
+
+ ; jbmaxsize = 200 ; Max length of the jitterbuffer in milliseconds.
+
+ ; jbresyncthreshold = 1000 ; Jump in the frame timestamps over which the jitterbuffer is
+ ; resynchronized. Useful to improve the quality of the voice, with
+ ; big jumps in/broken timestamps, usualy sent from exotic devices
+ ; and programs. Defaults to 1000.
+
+ ; jbimpl = fixed ; Jitterbuffer implementation, used on the receiving side of a SIP
+ ; channel. Two implementation are currenlty available - "fixed"
+ ; (with size always equals to jbmax-size) and "adaptive" (with
+ ; variable size, actually the new jb of IAX2). Defaults to fixed.
+
+ ; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
+ ;-----------------------------------------------------------------------------------
+
+
[card1]
; device = /dev/dsp1 ; alternate device
Modified: trunk/configs/sip.conf.sample
URL: http://svn.digium.com/view/asterisk/trunk/configs/sip.conf.sample?rev=31052&r1=31051&r2=31052&view=diff
==============================================================================
--- trunk/configs/sip.conf.sample (original)
+++ trunk/configs/sip.conf.sample Wed May 31 11:56:50 2006
@@ -301,6 +301,32 @@
; it may be a mandatory requirement for some
; destinations which do not have a prior
; account relationship with your server.
+
+;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
+; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of a
+ ; SIP channel. Defaults to "no". An enabled jitterbuffer will
+ ; be used only if the sending side can create and the receiving
+ ; side can not accept jitter. The SIP channel can accept jitter,
+ ; thus a jitterbuffer on the receive SIP side will be used only
+ ; if it is forced and enabled.
+
+; jbforce = no ; Forces the use of a jitterbuffer on the receive side of a SIP
+ ; channel. Defaults to "no".
+
+; jbmaxsize = 200 ; Max length of the jitterbuffer in milliseconds.
+
+; jbresyncthreshold = 1000 ; Jump in the frame timestamps over which the jitterbuffer is
+ ; resynchronized. Useful to improve the quality of the voice, with
+ ; big jumps in/broken timestamps, usualy sent from exotic devices
+ ; and programs. Defaults to 1000.
+
+; jbimpl = fixed ; Jitterbuffer implementation, used on the receiving side of a SIP
+ ; channel. Two implementation are currenlty available - "fixed"
+ ; (with size always equals to jbmaxsize) and "adaptive" (with
+ ; variable size, actually the new jb of IAX2). Defaults to fixed.
+
+; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
+;-----------------------------------------------------------------------------------
[authentication]
; Global credentials for outbound calls, i.e. when a proxy challenges your
Modified: trunk/configs/zapata.conf.sample
URL: http://svn.digium.com/view/asterisk/trunk/configs/zapata.conf.sample?rev=31052&r1=31051&r2=31052&view=diff
==============================================================================
--- trunk/configs/zapata.conf.sample (original)
+++ trunk/configs/zapata.conf.sample Wed May 31 11:56:50 2006
@@ -495,6 +495,33 @@
;
;jitterbuffers=4
;
+;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
+; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of a
+ ; ZAP channel. Defaults to "no". An enabled jitterbuffer will
+ ; be used only if the sending side can create and the receiving
+ ; side can not accept jitter. The ZAP channel can't accept jitter,
+ ; thus an enabled jitterbuffer on the receive ZAP side will always
+ ; be used if the sending side can create jitter or if ZAP jb is
+ ; forced.
+
+; jbforce = no ; Forces the use of a jitterbuffer on the receive side of a ZAP
+ ; channel. Defaults to "no".
+
+; jbmaxsize = 200 ; Max length of the jitterbuffer in milliseconds.
+
+; jbresyncthreshold = 1000 ; Jump in the frame timestamps over which the jitterbuffer is
+ ; resynchronized. Useful to improve the quality of the voice, with
+ ; big jumps in/broken timestamps, usualy sent from exotic devices
+ ; and programs. Defaults to 1000.
+
+; jbimpl = fixed ; Jitterbuffer implementation, used on the receiving side of a SIP
+ ; channel. Two implementation are currenlty available - "fixed"
+ ; (with size always equals to jbmax-size) and "adaptive" (with
+ ; variable size, actually the new jb of IAX2). Defaults to fixed.
+
+; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
+;-----------------------------------------------------------------------------------
+;
; You can define your own custom ring cadences here. You can define up to 8
; pairs. If the silence is negative, it indicates where the callerid spill is
; to be placed. Also, if you define any custom cadences, the default cadences
Modified: trunk/frame.c
URL: http://svn.digium.com/view/asterisk/trunk/frame.c?rev=31052&r1=31051&r2=31052&view=diff
==============================================================================
--- trunk/frame.c (original)
+++ trunk/frame.c Wed May 31 11:56:50 2006
@@ -316,6 +316,13 @@
out->samples = fr->samples;
out->offset = fr->offset;
out->data = fr->data;
+ /* Copy the timing data */
+ out->has_timing_info = fr->has_timing_info;
+ if (fr->has_timing_info) {
+ out->ts = fr->ts;
+ out->len = fr->len;
+ out->seqno = fr->seqno;
+ }
} else
out = fr;
@@ -380,6 +387,12 @@
out->prev = NULL;
out->next = NULL;
memcpy(out->data, f->data, out->datalen);
+ out->has_timing_info = f->has_timing_info;
+ if (f->has_timing_info) {
+ out->ts = f->ts;
+ out->len = f->len;
+ out->seqno = f->seqno;
+ }
return out;
}
Added: trunk/include/asterisk/abstract_jb.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/abstract_jb.h?rev=31052&view=auto
==============================================================================
--- trunk/include/asterisk/abstract_jb.h (added)
+++ trunk/include/asterisk/abstract_jb.h Wed May 31 11:56:50 2006
@@ -1,0 +1,220 @@
+/*
+ * abstract_jb: common implementation-independent jitterbuffer stuff
+ *
+ * Copyright (C) 2005, Attractel OOD
+ *
+ * Contributors:
+ * Slav Klenov <slav at securax.org>
+ *
+ * Copyright on this file is disclaimed to Digium for inclusion in Asterisk
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief Common implementation-independent jitterbuffer stuff.
+ *
+ * \author Slav Klenov <slav at securax.org>
+ */
+
+#ifndef _ABSTRACT_JB_H_
+#define _ABSTRACT_JB_H_
+
+#include <stdio.h>
+#include <sys/time.h>
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+struct ast_channel;
+struct ast_frame;
+
+
+/* Configuration flags */
+enum {
+ AST_JB_ENABLED = (1 << 0),
+ AST_JB_FORCED = (1 << 1),
+ AST_JB_LOG = (1 << 2)
+};
+
+#define AST_JB_IMPL_NAME_SIZE 12
+
+/*!
+ * \brief General jitterbuffer configuration.
+ */
+struct ast_jb_conf
+{
+ /*! \brief Combination of the AST_JB_ENABLED, AST_JB_FORCED and AST_JB_LOG flags. */
+ unsigned int flags;
+ /*! \brief Max size of the jitterbuffer implementation. */
+ long max_size;
+ /*! \brief Resynchronization threshold of the jitterbuffer implementation. */
+ long resync_threshold;
+ /*! \brief Name of the jitterbuffer implementation to be used. */
+ char impl[AST_JB_IMPL_NAME_SIZE];
+};
+
+
+/* Jitterbuffer configuration property names */
+#define AST_JB_CONF_PREFIX "jb"
+#define AST_JB_CONF_ENABLE "enable"
+#define AST_JB_CONF_FORCE "force"
+#define AST_JB_CONF_MAX_SIZE "maxsize"
+#define AST_JB_CONF_RESYNCH_THRESHOLD "resyncthreshold"
+#define AST_JB_CONF_IMPL "impl"
+#define AST_JB_CONF_LOG "log"
+
+
+struct ast_jb_impl;
+
+
+/*!
+ * \brief General jitterbuffer state.
+ */
+struct ast_jb
+{
+ /*! \brief Jitterbuffer configuration. */
+ struct ast_jb_conf conf;
+ /*! \brief Jitterbuffer implementation to be used. */
+ struct ast_jb_impl *impl;
+ /*! \brief Jitterbuffer object, passed to the implementation. */
+ void *jbobj;
+ /*! \brief The time the jitterbuffer was created. */
+ struct timeval timebase;
+ /*! \brief The time the next frame should be played. */
+ long next;
+ /*! \brief Voice format of the last frame in. */
+ int last_format;
+ /*! \brief File for frame timestamp tracing. */
+ FILE *logfile;
+ /*! \brief Jitterbuffer internal state flags. */
+ unsigned int flags;
+};
+
+
+/*!
+ * \brief Checks the need of a jb use in a generic bridge.
+ * \param c0 first bridged channel.
+ * \param c1 second bridged channel.
+ *
+ * Called from ast_generic_bridge() when two channels are entering in a bridge.
+ * The function checks the need of a jitterbuffer, depending on both channel's
+ * configuration and technology properties. As a result, this function sets
+ * appropriate internal jb flags to the channels, determining further behaviour
+ * of the bridged jitterbuffers.
+ *
+ * \return zero if there are no jitter buffers in use, non-zero if there are
+ */
+int ast_jb_do_usecheck(struct ast_channel *c0, struct ast_channel *c1);
+
+
+/*!
+ * \brief Calculates the time, left to the closest delivery moment in a bridge.
+ * \param c0 first bridged channel.
+ * \param c1 second bridged channel.
+ * \param time_left bridge time limit, or -1 if not set.
+ *
+ * Called from ast_generic_bridge() to determine the maximum time to wait for
+ * activity in ast_waitfor_n() call. If neihter of the channels is using jb,
+ * this function returns the time limit passed.
+ *
+ * \return maximum time to wait.
+ */
+int ast_jb_get_when_to_wakeup(struct ast_channel *c0, struct ast_channel *c1, int time_left);
+
+
+/*!
+ * \brief Puts a frame into a channel jitterbuffer.
+ * \param chan channel.
+ * \param frame frame.
+ *
+ * Called from ast_generic_bridge() to put a frame into a channel's jitterbuffer.
+ * The function will successfuly enqueue a frame if and only if:
+ * 1. the channel is using a jitterbuffer (as determined by ast_jb_do_usecheck()),
+ * 2. the frame's type is AST_FRAME_VOICE,
+ * 3. the frame has timing info set and has length >= 2 ms,
+ * 4. there is no some internal error happened (like failed memory allocation).
+ * Frames, successfuly queued, should be delivered by the channel's jitterbuffer,
+ * when their delivery time has came.
+ * Frames, not successfuly queued, should be delivered immediately.
+ * Dropped by the jb implementation frames are considered successfuly enqueued as
+ * far as they should not be delivered at all.
+ *
+ * \return zero if the frame was queued, -1 if not.
+ */
+int ast_jb_put(struct ast_channel *chan, struct ast_frame *f);
+
+
+/*!
+ * \brief Deliver the queued frames that should be delivered now for both channels.
+ * \param c0 first bridged channel.
+ * \param c1 second bridged channel.
+ *
+ * Called from ast_generic_bridge() to deliver any frames, that should be delivered
+ * for the moment of invocation. Does nothing if neihter of the channels is using jb
+ * or has any frames currently queued in. The function delivers frames usig ast_write()
+ * each of the channels.
+ */
+void ast_jb_get_and_deliver(struct ast_channel *c0, struct ast_channel *c1);
+
+
+/*!
+ * \brief Destroys jitterbuffer on a channel.
+ * \param chan channel.
+ *
+ * Called from ast_channel_free() when a channel is destroyed.
+ */
+void ast_jb_destroy(struct ast_channel *chan);
+
+
+/*!
+ * \brief Sets jitterbuffer configuration property.
+ * \param conf configuration to store the property in.
+ * \param varname property name.
+ * \param value property value.
+ *
+ * Called from a channel driver to build a jitterbuffer configuration tipically when
+ * reading a configuration file. It is not neccessary for a channel driver to know
+ * each of the jb configuration property names. The jitterbuffer itself knows them.
+ * The channel driver can pass each config var it reads through this function. It will
+ * return 0 if the variable was consumed from the jb conf.
+ *
+ * \return zero if the property was set to the configuration, -1 if not.
+ */
+int ast_jb_read_conf(struct ast_jb_conf *conf, char *varname, char *value);
+
+
+/*!
+ * \brief Configures a jitterbuffer on a channel.
+ * \param chan channel to configure.
+ * \param conf configuration to apply.
+ *
+ * Called from a channel driver when a channel is created and its jitterbuffer needs
+ * to be configured.
+ */
+void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf);
+
+
+/*!
+ * \brief Copies a channel's jitterbuffer configuration.
+ * \param chan channel.
+ * \param conf destination.
+ */
+void ast_jb_get_config(const struct ast_channel *chan, struct ast_jb_conf *conf);
+
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ABSTRACT_JB_H_ */
Propchange: trunk/include/asterisk/abstract_jb.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: trunk/include/asterisk/abstract_jb.h
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: trunk/include/asterisk/abstract_jb.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: trunk/include/asterisk/channel.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/channel.h?rev=31052&r1=31051&r2=31052&view=diff
==============================================================================
--- trunk/include/asterisk/channel.h (original)
+++ trunk/include/asterisk/channel.h Wed May 31 11:56:50 2006
@@ -86,6 +86,8 @@
#ifndef _ASTERISK_CHANNEL_H
#define _ASTERISK_CHANNEL_H
+#include "asterisk/abstract_jb.h"
+
#include <unistd.h>
#ifdef POLLCOMPAT
#include "asterisk/poll-compat.h"
@@ -445,12 +447,20 @@
/*! For easy linking */
AST_LIST_ENTRY(ast_channel) chan_list;
+
+ /*! The jitterbuffer state */
+ struct ast_jb jb;
};
/* \defgroup chanprop Channel tech properties:
\brief Channels have this property if they can accept input with jitter; i.e. most VoIP channels */
/* @{ */
#define AST_CHAN_TP_WANTSJITTER (1 << 0)
+
+/* \defgroup chanprop Channel tech properties:
+ \brief Channels have this property if they can create jitter; i.e. most VoIP channels */
+/* @{ */
+#define AST_CHAN_TP_CREATESJITTER (1 << 1)
/* This flag has been deprecated by the transfercapbilty data member in struct ast_channel */
/* #define AST_FLAG_DIGITAL (1 << 0) */ /* if the call is a digital ISDN call */
Modified: trunk/include/asterisk/frame.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/frame.h?rev=31052&r1=31051&r2=31052&view=diff
==============================================================================
--- trunk/include/asterisk/frame.h (original)
+++ trunk/include/asterisk/frame.h Wed May 31 11:56:50 2006
@@ -109,6 +109,14 @@
struct ast_frame *prev;
/*! Next/Prev for linking stand alone frames */
struct ast_frame *next;
+ /*! Timing data flag */
+ int has_timing_info;
+ /*! Timestamp in milliseconds */
+ long ts;
+ /*! Length in milliseconds */
+ long len;
+ /*! Sequence number */
+ int seqno;
};
/*!
Modified: trunk/rtp.c
URL: http://svn.digium.com/view/asterisk/trunk/rtp.c?rev=31052&r1=31051&r2=31052&view=diff
==============================================================================
--- trunk/rtp.c (original)
+++ trunk/rtp.c Wed May 31 11:56:50 2006
@@ -696,7 +696,6 @@
int padding;
int mark;
int ext;
- int x;
char iabuf[INET_ADDRSTRLEN];
unsigned int ssrc;
unsigned int timestamp;
@@ -835,17 +834,6 @@
if (!rtp->lastrxts)
rtp->lastrxts = timestamp;
- if (rtp->rxseqno) {
- for (x=rtp->rxseqno + 1; x < seqno; x++) {
- /* Queue empty frames */
- rtp->f.mallocd = 0;
- rtp->f.datalen = 0;
- rtp->f.data = NULL;
- rtp->f.offset = 0;
- rtp->f.samples = 0;
- rtp->f.src = "RTPMissedFrame";
- }
- }
rtp->rxseqno = seqno;
if (rtp->dtmfcount) {
@@ -877,6 +865,11 @@
if (rtp->f.subclass == AST_FORMAT_SLINEAR)
ast_frame_byteswap_be(&rtp->f);
calc_rxstamp(&rtp->f.delivery, rtp, timestamp, mark);
+ /* Add timing data to let ast_generic_bridge() put the frame into a jitterbuf */
+ rtp->f.has_timing_info = 1;
+ rtp->f.ts = timestamp / 8;
+ rtp->f.len = rtp->f.samples / 8;
+ rtp->f.seqno = seqno;
} else {
/* Video -- samples is # of samples vs. 90000 */
if (!rtp->lastividtimestamp)
@@ -1700,6 +1693,9 @@
*/
if (rtp->lastts > rtp->lastdigitts)
rtp->lastdigitts = rtp->lastts;
+
+ if (f->has_timing_info)
+ rtp->lastts = f->ts * 8;
/* Get a pointer to the header */
rtpheader = (unsigned char *)(f->data - hdrlen);
Added: trunk/scx_jitterbuf.c
URL: http://svn.digium.com/view/asterisk/trunk/scx_jitterbuf.c?rev=31052&view=auto
==============================================================================
--- trunk/scx_jitterbuf.c (added)
+++ trunk/scx_jitterbuf.c Wed May 31 11:56:50 2006
@@ -1,0 +1,351 @@
+/*
+ * scx_jitterbuf: jitterbuffering algorithm
+ *
+ * Copyright (C) 2005, Attractel OOD
+ *
+ * Contributors:
+ * Slav Klenov <slav at securax.org>
+ *
+ * Copyright on this file is disclaimed to Digium for inclusion in Asterisk
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief Jitterbuffering algorithm.
+ *
+ * \author Slav Klenov <slav at securax.org>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "asterisk.h"
+ASTERISK_FILE_VERSION(__FILE__, "$Revision $")
+
+#include "asterisk/utils.h"
+#include "scx_jitterbuf.h"
+
+#undef SCX_JB_DEBUG
+
+#ifdef SCX_JB_DEBUG
+#define ASSERT(a)
+#else
+#define ASSERT(a) assert(a)
+#endif
+
+/*! \brief private scx_jb structure */
+struct scx_jb
+{
+ struct scx_jb_frame *frames;
+ struct scx_jb_frame *tail;
+ struct scx_jb_conf conf;
+ long rxcore;
+ long delay;
+ long next_delivery;
+ int force_resynch;
+};
+
+
+static struct scx_jb_frame *alloc_jb_frame(struct scx_jb *jb);
+static void release_jb_frame(struct scx_jb *jb, struct scx_jb_frame *frame);
+static void get_jb_head(struct scx_jb *jb, struct scx_jb_frame *frame);
+static int resynch_jb(struct scx_jb *jb, void *data, long ms, long ts, long now);
+
+static inline struct scx_jb_frame *alloc_jb_frame(struct scx_jb *jb)
+{
+ return ast_calloc(1, sizeof(struct scx_jb_frame));
+}
+
+static inline void release_jb_frame(struct scx_jb *jb, struct scx_jb_frame *frame)
+{
+ free(frame);
+}
+
+static void get_jb_head(struct scx_jb *jb, struct scx_jb_frame *frame)
+{
+ struct scx_jb_frame *fr;
+
+ /* unlink the frame */
+ fr = jb->frames;
+ jb->frames = fr->next;
+ if (jb->frames) {
+ jb->frames->prev = NULL;
+ } else {
+ /* the jb is empty - update tail */
+ jb->tail = NULL;
+ }
+
+ /* update next */
+ jb->next_delivery = fr->delivery + fr->ms;
+
+ /* copy the destination */
+ memcpy(frame, fr, sizeof(struct scx_jb_frame));
+
+ /* and release the frame */
+ release_jb_frame(jb, fr);
+}
+
+
[... 423 lines stripped ...]
More information about the asterisk-commits
mailing list