- add slav, zoa, and royk to the CREDITS for the generic jitterbuffer
- change references to the "scx" jitterbuffer to be called "fixed" and change references to the "stevek" jitterbuffer to be called "adaptive", instead git-svn-id: http://svn.digium.com/svn/asterisk/trunk@31356 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
parent
f6aed90150
commit
024161b89b
36
CREDITS
36
CREDITS
|
@ -30,58 +30,94 @@ PhoneJack and Linejack card to the project. (http://www.quicknet.net)
|
|||
=== MISCELLANEOUS PATCHES ===
|
||||
Jim Dixon - Zapata Telephony and app_rpt
|
||||
http://www.zapatatelephony.org/app_rpt.html
|
||||
|
||||
Russell Bryant - Asterisk 1.0 maintainer and misc. enhancements
|
||||
russelb@clemson.edu
|
||||
|
||||
Anthony Minessale II - Countless big and small fixes, and relentless forward push
|
||||
anthmct@yahoo.com http://www.asterlink.com
|
||||
|
||||
James Golovich - Innumerable contributions
|
||||
You can find him and asterisk-perl at http://asterisk.gnuinter.net
|
||||
|
||||
Andre Bierwirth - Extension hints and status
|
||||
|
||||
Oliver Daudey - ISDN4Linux fixes
|
||||
|
||||
Pauline Middelink - ISDN4Linux patches and some general patches.
|
||||
She can be found at http://www.polyware.nl/~middelink/En/
|
||||
|
||||
Jean-Denis Girard - Various contributions from the South Pacific Islands
|
||||
jd-girard@esoft.pf http://www.esoft.pf
|
||||
|
||||
William Jordan / Vonage - MySQL enhancements to Voicemail
|
||||
wjordan@vonage.com
|
||||
|
||||
Jac Kersing - Various fixes
|
||||
|
||||
Steven Critchfield - Seek and Trunc functions for playback and recording
|
||||
critch@basesys.com
|
||||
|
||||
Jefferson Noxon - app_lookupcidname, app_db, and various other contributions
|
||||
|
||||
Klaus-Peter Junghanns - in-band DTMF on SIP and MGCP
|
||||
|
||||
Ross Finlayson - Dynamic RTP payload support
|
||||
|
||||
Mahmut Fettahlioglu - Audio recording, music-on-hold changes, alaw file
|
||||
format, and various fixes. Can be contacted at mahmut@oa.com.au
|
||||
|
||||
James Dennis - Cisco SIP compatibility patches to work with SIP service
|
||||
providers. Can be contacted at asterisk@jdennis.net
|
||||
|
||||
Tilghman Lesher - ast_localtime(); ast_say_date_with_format();
|
||||
GotoIfTime, Random, SayUnixTime, HasNewVoicemail applications;
|
||||
CUT, SORT, EVAL, CURL, FIELDQTY, STRFTIME, QUEUEAGENT* functions;
|
||||
and other innumerable bug fixes. http://asterisk.drunkcoder.com/
|
||||
|
||||
Jayson Vantuyl - Manager protocol changes, various other bugs.
|
||||
jvantuyl@computingedge.net
|
||||
|
||||
Thorsten Lockert - OpenBSD, FreeBSD ports, making MacOS X port run on 10.3,
|
||||
dialplan include verification, route lookup on OpenBSD, SNMP agent
|
||||
support (res_snmp), various other bugs. tholo@sigmasoft.com
|
||||
|
||||
Brian West - ODBC support and Bug Marshaling
|
||||
|
||||
Josh Roberson - chan_zap reload support, Advanced Voicemail Features, other misc. patches,
|
||||
and Bug Marshalling. - josh@asteriasgi.com, http://www.asteriasgi.com
|
||||
|
||||
William Waites - syslog support, SIP NAT traversal for SIP-UA. ww@styx.org
|
||||
|
||||
Rich Murphey - Porting to FreeBSD, NetBSD, OpenBSD, and Darwin.
|
||||
rich@whiteoaklabs.com http://whiteoaklabs.com
|
||||
|
||||
Simon Lockhart - Porting to Solaris (based on work of Logan ???)
|
||||
simon@slimey.org
|
||||
|
||||
Olle E. Johansson - SIP RFC compliance, documentation and testing, testing, testing
|
||||
oej@edvina.net, http://edvina.net
|
||||
|
||||
Steve Kann - new jitter buffer for IAX2
|
||||
stevek@stevek.com
|
||||
|
||||
Constantine Filin - major contributions to the Asterisk Realtime Architecture
|
||||
|
||||
Steve Murphy - privacy support, $[ ] parser upgrade, AEL2 parser upgrade
|
||||
|
||||
Claude Patry - bug fixes, feature enhancements, and bug marshalling
|
||||
cpatry@gmail.com
|
||||
|
||||
Miroslav Nachev, miro@space-comm.com COSMOS Software Enterprises, Ltd.
|
||||
- for Variable for No Answer Timeout for Attended Transfer
|
||||
|
||||
Slav Klenov & Vanheuverzwijn Joachim - development of the generic jitterbuffer
|
||||
Securax Ltd. info@securax.be
|
||||
|
||||
Roy Sigurd Karlsbakk - providing funding for generic jitterbuffer development
|
||||
roy@karlsbakk.net, Briiz Telecom AS
|
||||
|
||||
|
||||
=== OTHER CONTRIBUTIONS ===
|
||||
John Todd - Monkey sounds and associated teletorture prompt
|
||||
Michael Jerris - bug marshaling
|
||||
|
|
2
Makefile
2
Makefile
|
@ -282,7 +282,7 @@ OBJS=io.o sched.o logger.o frame.o loader.o config.o channel.o \
|
|||
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 scx_jitterbuf.o abstract_jb.o
|
||||
cryptostub.o sha1.o http.o fixedjitterbuf.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
|
||||
|
|
194
abstract_jb.c
194
abstract_jb.c
|
@ -42,7 +42,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|||
#include "asterisk/utils.h"
|
||||
|
||||
#include "asterisk/abstract_jb.h"
|
||||
#include "scx_jitterbuf.h"
|
||||
#include "fixedjitterbuf.h"
|
||||
#include "jitterbuf.h"
|
||||
|
||||
/*! Internal jb flags */
|
||||
|
@ -89,49 +89,49 @@ struct ast_jb_impl
|
|||
};
|
||||
|
||||
/* Implementation functions */
|
||||
/* scx */
|
||||
static void * jb_create_scx(struct ast_jb_conf *general_config, long resynch_threshold);
|
||||
static void jb_destroy_scx(void *jb);
|
||||
static int jb_put_first_scx(void *jb, struct ast_frame *fin, long now);
|
||||
static int jb_put_scx(void *jb, struct ast_frame *fin, long now);
|
||||
static int jb_get_scx(void *jb, struct ast_frame **fout, long now, long interpl);
|
||||
static long jb_next_scx(void *jb);
|
||||
static int jb_remove_scx(void *jb, struct ast_frame **fout);
|
||||
static void jb_force_resynch_scx(void *jb);
|
||||
/* stevek */
|
||||
static void * jb_create_stevek(struct ast_jb_conf *general_config, long resynch_threshold);
|
||||
static void jb_destroy_stevek(void *jb);
|
||||
static int jb_put_first_stevek(void *jb, struct ast_frame *fin, long now);
|
||||
static int jb_put_stevek(void *jb, struct ast_frame *fin, long now);
|
||||
static int jb_get_stevek(void *jb, struct ast_frame **fout, long now, long interpl);
|
||||
static long jb_next_stevek(void *jb);
|
||||
static int jb_remove_stevek(void *jb, struct ast_frame **fout);
|
||||
static void jb_force_resynch_stevek(void *jb);
|
||||
/* fixed */
|
||||
static void * jb_create_fixed(struct ast_jb_conf *general_config, long resynch_threshold);
|
||||
static void jb_destroy_fixed(void *jb);
|
||||
static int jb_put_first_fixed(void *jb, struct ast_frame *fin, long now);
|
||||
static int jb_put_fixed(void *jb, struct ast_frame *fin, long now);
|
||||
static int jb_get_fixed(void *jb, struct ast_frame **fout, long now, long interpl);
|
||||
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);
|
||||
/* adaptive */
|
||||
static void * jb_create_adaptive(struct ast_jb_conf *general_config, long resynch_threshold);
|
||||
static void jb_destroy_adaptive(void *jb);
|
||||
static int jb_put_first_adaptive(void *jb, struct ast_frame *fin, long now);
|
||||
static int jb_put_adaptive(void *jb, struct ast_frame *fin, long now);
|
||||
static int jb_get_adaptive(void *jb, struct ast_frame **fout, long now, long interpl);
|
||||
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);
|
||||
|
||||
/* Available jb implementations */
|
||||
static struct ast_jb_impl avail_impl[] =
|
||||
{
|
||||
{
|
||||
.name = "fixed",
|
||||
.create = jb_create_scx,
|
||||
.destroy = jb_destroy_scx,
|
||||
.put_first = jb_put_first_scx,
|
||||
.put = jb_put_scx,
|
||||
.get = jb_get_scx,
|
||||
.next = jb_next_scx,
|
||||
.remove = jb_remove_scx,
|
||||
.force_resync = jb_force_resynch_scx
|
||||
.create = jb_create_fixed,
|
||||
.destroy = jb_destroy_fixed,
|
||||
.put_first = jb_put_first_fixed,
|
||||
.put = jb_put_fixed,
|
||||
.get = jb_get_fixed,
|
||||
.next = jb_next_fixed,
|
||||
.remove = jb_remove_fixed,
|
||||
.force_resync = jb_force_resynch_fixed
|
||||
},
|
||||
{
|
||||
.name = "adaptive",
|
||||
.create = jb_create_stevek,
|
||||
.destroy = jb_destroy_stevek,
|
||||
.put_first = jb_put_first_stevek,
|
||||
.put = jb_put_stevek,
|
||||
.get = jb_get_stevek,
|
||||
.next = jb_next_stevek,
|
||||
.remove = jb_remove_stevek,
|
||||
.force_resync = jb_force_resynch_stevek
|
||||
.create = jb_create_adaptive,
|
||||
.destroy = jb_destroy_adaptive,
|
||||
.put_first = jb_put_first_adaptive,
|
||||
.put = jb_put_adaptive,
|
||||
.get = jb_get_adaptive,
|
||||
.next = jb_next_adaptive,
|
||||
.remove = jb_remove_adaptive,
|
||||
.force_resync = jb_force_resynch_adaptive
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -147,9 +147,9 @@ enum {
|
|||
};
|
||||
|
||||
/* Translations between impl and abstract return codes */
|
||||
static int scx_to_abstract_code[] =
|
||||
static int fixed_to_abstract_code[] =
|
||||
{JB_IMPL_OK, JB_IMPL_DROP, JB_IMPL_INTERP, JB_IMPL_NOFRAME};
|
||||
static int stevek_to_abstract_code[] =
|
||||
static int adaptive_to_abstract_code[] =
|
||||
{JB_IMPL_OK, JB_IMPL_NOFRAME, JB_IMPL_NOFRAME, JB_IMPL_INTERP, JB_IMPL_DROP, JB_IMPL_OK};
|
||||
|
||||
/* JB_GET actions (used only for the frames log) */
|
||||
|
@ -467,7 +467,7 @@ static int create_jb(struct ast_channel *chan, struct ast_frame *frr)
|
|||
res = jbimpl->put_first(jbobj, frr, now);
|
||||
|
||||
/* The result of putting the first frame should not differ from OK. However, its possible
|
||||
some implementations (i.e. stevek's when resynch_threshold is specified) to drop it. */
|
||||
some implementations (i.e. adaptive's when resynch_threshold is specified) to drop it. */
|
||||
if (res != JB_IMPL_OK) {
|
||||
ast_log(LOG_WARNING, "Failed to put first frame in the jitterbuffer on channel '%s'\n", chan->name);
|
||||
/*
|
||||
|
@ -615,170 +615,170 @@ void ast_jb_get_config(const struct ast_channel *chan, struct ast_jb_conf *conf)
|
|||
|
||||
/* Implementation functions */
|
||||
|
||||
/* scx */
|
||||
/* fixed */
|
||||
|
||||
static void * jb_create_scx(struct ast_jb_conf *general_config, long resynch_threshold)
|
||||
static void * jb_create_fixed(struct ast_jb_conf *general_config, long resynch_threshold)
|
||||
{
|
||||
struct scx_jb_conf conf;
|
||||
struct fixed_jb_conf conf;
|
||||
|
||||
conf.jbsize = general_config->max_size;
|
||||
conf.resync_threshold = resynch_threshold;
|
||||
|
||||
return scx_jb_new(&conf);
|
||||
return fixed_jb_new(&conf);
|
||||
}
|
||||
|
||||
|
||||
static void jb_destroy_scx(void *jb)
|
||||
static void jb_destroy_fixed(void *jb)
|
||||
{
|
||||
struct scx_jb *scxjb = (struct scx_jb *) jb;
|
||||
struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
|
||||
|
||||
/* destroy the jb */
|
||||
scx_jb_destroy(scxjb);
|
||||
fixed_jb_destroy(fixedjb);
|
||||
}
|
||||
|
||||
|
||||
static int jb_put_first_scx(void *jb, struct ast_frame *fin, long now)
|
||||
static int jb_put_first_fixed(void *jb, struct ast_frame *fin, long now)
|
||||
{
|
||||
struct scx_jb *scxjb = (struct scx_jb *) jb;
|
||||
struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
|
||||
int res;
|
||||
|
||||
res = scx_jb_put_first(scxjb, fin, fin->len, fin->ts, now);
|
||||
res = fixed_jb_put_first(fixedjb, fin, fin->len, fin->ts, now);
|
||||
|
||||
return scx_to_abstract_code[res];
|
||||
return fixed_to_abstract_code[res];
|
||||
}
|
||||
|
||||
|
||||
static int jb_put_scx(void *jb, struct ast_frame *fin, long now)
|
||||
static int jb_put_fixed(void *jb, struct ast_frame *fin, long now)
|
||||
{
|
||||
struct scx_jb *scxjb = (struct scx_jb *) jb;
|
||||
struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
|
||||
int res;
|
||||
|
||||
res = scx_jb_put(scxjb, fin, fin->len, fin->ts, now);
|
||||
res = fixed_jb_put(fixedjb, fin, fin->len, fin->ts, now);
|
||||
|
||||
return scx_to_abstract_code[res];
|
||||
return fixed_to_abstract_code[res];
|
||||
}
|
||||
|
||||
|
||||
static int jb_get_scx(void *jb, struct ast_frame **fout, long now, long interpl)
|
||||
static int jb_get_fixed(void *jb, struct ast_frame **fout, long now, long interpl)
|
||||
{
|
||||
struct scx_jb *scxjb = (struct scx_jb *) jb;
|
||||
struct scx_jb_frame frame;
|
||||
struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
|
||||
struct fixed_jb_frame frame;
|
||||
int res;
|
||||
|
||||
res = scx_jb_get(scxjb, &frame, now, interpl);
|
||||
res = fixed_jb_get(fixedjb, &frame, now, interpl);
|
||||
*fout = frame.data;
|
||||
|
||||
return scx_to_abstract_code[res];
|
||||
return fixed_to_abstract_code[res];
|
||||
}
|
||||
|
||||
|
||||
static long jb_next_scx(void *jb)
|
||||
static long jb_next_fixed(void *jb)
|
||||
{
|
||||
struct scx_jb *scxjb = (struct scx_jb *) jb;
|
||||
struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
|
||||
|
||||
return scx_jb_next(scxjb);
|
||||
return fixed_jb_next(fixedjb);
|
||||
}
|
||||
|
||||
|
||||
static int jb_remove_scx(void *jb, struct ast_frame **fout)
|
||||
static int jb_remove_fixed(void *jb, struct ast_frame **fout)
|
||||
{
|
||||
struct scx_jb *scxjb = (struct scx_jb *) jb;
|
||||
struct scx_jb_frame frame;
|
||||
struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
|
||||
struct fixed_jb_frame frame;
|
||||
int res;
|
||||
|
||||
res = scx_jb_remove(scxjb, &frame);
|
||||
res = fixed_jb_remove(fixedjb, &frame);
|
||||
*fout = frame.data;
|
||||
|
||||
return scx_to_abstract_code[res];
|
||||
return fixed_to_abstract_code[res];
|
||||
}
|
||||
|
||||
|
||||
static void jb_force_resynch_scx(void *jb)
|
||||
static void jb_force_resynch_fixed(void *jb)
|
||||
{
|
||||
struct scx_jb *scxjb = (struct scx_jb *) jb;
|
||||
struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
|
||||
|
||||
scx_jb_set_force_resynch(scxjb);
|
||||
fixed_jb_set_force_resynch(fixedjb);
|
||||
}
|
||||
|
||||
|
||||
/* stevek */
|
||||
/* adaptive */
|
||||
|
||||
static void *jb_create_stevek(struct ast_jb_conf *general_config, long resynch_threshold)
|
||||
static void *jb_create_adaptive(struct ast_jb_conf *general_config, long resynch_threshold)
|
||||
{
|
||||
jb_conf jbconf;
|
||||
jitterbuf *stevekjb;
|
||||
jitterbuf *adaptivejb;
|
||||
|
||||
stevekjb = jb_new();
|
||||
if (stevekjb) {
|
||||
adaptivejb = jb_new();
|
||||
if (adaptivejb) {
|
||||
jbconf.max_jitterbuf = general_config->max_size;
|
||||
jbconf.resync_threshold = general_config->resync_threshold;
|
||||
jbconf.max_contig_interp = 10;
|
||||
jb_setconf(stevekjb, &jbconf);
|
||||
jb_setconf(adaptivejb, &jbconf);
|
||||
}
|
||||
|
||||
return stevekjb;
|
||||
return adaptivejb;
|
||||
}
|
||||
|
||||
|
||||
static void jb_destroy_stevek(void *jb)
|
||||
static void jb_destroy_adaptive(void *jb)
|
||||
{
|
||||
jitterbuf *stevekjb = (jitterbuf *) jb;
|
||||
jitterbuf *adaptivejb = (jitterbuf *) jb;
|
||||
|
||||
jb_destroy(stevekjb);
|
||||
jb_destroy(adaptivejb);
|
||||
}
|
||||
|
||||
|
||||
static int jb_put_first_stevek(void *jb, struct ast_frame *fin, long now)
|
||||
static int jb_put_first_adaptive(void *jb, struct ast_frame *fin, long now)
|
||||
{
|
||||
return jb_put_stevek(jb, fin, now);
|
||||
return jb_put_adaptive(jb, fin, now);
|
||||
}
|
||||
|
||||
|
||||
static int jb_put_stevek(void *jb, struct ast_frame *fin, long now)
|
||||
static int jb_put_adaptive(void *jb, struct ast_frame *fin, long now)
|
||||
{
|
||||
jitterbuf *stevekjb = (jitterbuf *) jb;
|
||||
jitterbuf *adaptivejb = (jitterbuf *) jb;
|
||||
int res;
|
||||
|
||||
res = jb_put(stevekjb, fin, JB_TYPE_VOICE, fin->len, fin->ts, now);
|
||||
res = jb_put(adaptivejb, fin, JB_TYPE_VOICE, fin->len, fin->ts, now);
|
||||
|
||||
return stevek_to_abstract_code[res];
|
||||
return adaptive_to_abstract_code[res];
|
||||
}
|
||||
|
||||
|
||||
static int jb_get_stevek(void *jb, struct ast_frame **fout, long now, long interpl)
|
||||
static int jb_get_adaptive(void *jb, struct ast_frame **fout, long now, long interpl)
|
||||
{
|
||||
jitterbuf *stevekjb = (jitterbuf *) jb;
|
||||
jitterbuf *adaptivejb = (jitterbuf *) jb;
|
||||
jb_frame frame;
|
||||
int res;
|
||||
|
||||
res = jb_get(stevekjb, &frame, now, interpl);
|
||||
res = jb_get(adaptivejb, &frame, now, interpl);
|
||||
*fout = frame.data;
|
||||
|
||||
return stevek_to_abstract_code[res];
|
||||
return adaptive_to_abstract_code[res];
|
||||
}
|
||||
|
||||
|
||||
static long jb_next_stevek(void *jb)
|
||||
static long jb_next_adaptive(void *jb)
|
||||
{
|
||||
jitterbuf *stevekjb = (jitterbuf *) jb;
|
||||
jitterbuf *adaptivejb = (jitterbuf *) jb;
|
||||
|
||||
return jb_next(stevekjb);
|
||||
return jb_next(adaptivejb);
|
||||
}
|
||||
|
||||
|
||||
static int jb_remove_stevek(void *jb, struct ast_frame **fout)
|
||||
static int jb_remove_adaptive(void *jb, struct ast_frame **fout)
|
||||
{
|
||||
jitterbuf *stevekjb = (jitterbuf *) jb;
|
||||
jitterbuf *adaptivejb = (jitterbuf *) jb;
|
||||
jb_frame frame;
|
||||
int res;
|
||||
|
||||
res = jb_getall(stevekjb, &frame);
|
||||
res = jb_getall(adaptivejb, &frame);
|
||||
*fout = frame.data;
|
||||
|
||||
return stevek_to_abstract_code[res];
|
||||
return adaptive_to_abstract_code[res];
|
||||
}
|
||||
|
||||
|
||||
static void jb_force_resynch_stevek(void *jb)
|
||||
static void jb_force_resynch_adaptive(void *jb)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* scx_jitterbuf: jitterbuffering algorithm
|
||||
*
|
||||
* Copyright (C) 2005, Attractel OOD
|
||||
*
|
||||
* Contributors:
|
||||
|
@ -36,22 +34,22 @@
|
|||
ASTERISK_FILE_VERSION(__FILE__, "$Revision $")
|
||||
|
||||
#include "asterisk/utils.h"
|
||||
#include "scx_jitterbuf.h"
|
||||
#include "fixedjitterbuf.h"
|
||||
|
||||
#undef SCX_JB_DEBUG
|
||||
#undef FIXED_JB_DEBUG
|
||||
|
||||
#ifdef SCX_JB_DEBUG
|
||||
#ifdef FIXED_JB_DEBUG
|
||||
#define ASSERT(a)
|
||||
#else
|
||||
#define ASSERT(a) assert(a)
|
||||
#endif
|
||||
|
||||
/*! \brief private scx_jb structure */
|
||||
struct scx_jb
|
||||
/*! \brief private fixed_jb structure */
|
||||
struct fixed_jb
|
||||
{
|
||||
struct scx_jb_frame *frames;
|
||||
struct scx_jb_frame *tail;
|
||||
struct scx_jb_conf conf;
|
||||
struct fixed_jb_frame *frames;
|
||||
struct fixed_jb_frame *tail;
|
||||
struct fixed_jb_conf conf;
|
||||
long rxcore;
|
||||
long delay;
|
||||
long next_delivery;
|
||||
|
@ -59,24 +57,24 @@ struct scx_jb
|
|||
};
|
||||
|
||||
|
||||
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 struct fixed_jb_frame *alloc_jb_frame(struct fixed_jb *jb);
|
||||
static void release_jb_frame(struct fixed_jb *jb, struct fixed_jb_frame *frame);
|
||||
static void get_jb_head(struct fixed_jb *jb, struct fixed_jb_frame *frame);
|
||||
static int resynch_jb(struct fixed_jb *jb, void *data, long ms, long ts, long now);
|
||||
|
||||
static inline struct scx_jb_frame *alloc_jb_frame(struct scx_jb *jb)
|
||||
static inline struct fixed_jb_frame *alloc_jb_frame(struct fixed_jb *jb)
|
||||
{
|
||||
return ast_calloc(1, sizeof(struct scx_jb_frame));
|
||||
return ast_calloc(1, sizeof(struct fixed_jb_frame));
|
||||
}
|
||||
|
||||
static inline void release_jb_frame(struct scx_jb *jb, struct scx_jb_frame *frame)
|
||||
static inline void release_jb_frame(struct fixed_jb *jb, struct fixed_jb_frame *frame)
|
||||
{
|
||||
free(frame);
|
||||
}
|
||||
|
||||
static void get_jb_head(struct scx_jb *jb, struct scx_jb_frame *frame)
|
||||
static void get_jb_head(struct fixed_jb *jb, struct fixed_jb_frame *frame)
|
||||
{
|
||||
struct scx_jb_frame *fr;
|
||||
struct fixed_jb_frame *fr;
|
||||
|
||||
/* unlink the frame */
|
||||
fr = jb->frames;
|
||||
|
@ -92,32 +90,32 @@ static void get_jb_head(struct scx_jb *jb, struct scx_jb_frame *frame)
|
|||
jb->next_delivery = fr->delivery + fr->ms;
|
||||
|
||||
/* copy the destination */
|
||||
memcpy(frame, fr, sizeof(struct scx_jb_frame));
|
||||
memcpy(frame, fr, sizeof(struct fixed_jb_frame));
|
||||
|
||||
/* and release the frame */
|
||||
release_jb_frame(jb, fr);
|
||||
}
|
||||
|
||||
|
||||
struct scx_jb *scx_jb_new(struct scx_jb_conf *conf)
|
||||
struct fixed_jb *fixed_jb_new(struct fixed_jb_conf *conf)
|
||||
{
|
||||
struct scx_jb *jb;
|
||||
struct fixed_jb *jb;
|
||||
|
||||
if (!(jb = ast_calloc(1, sizeof(*jb))))
|
||||
return NULL;
|
||||
|
||||
/* First copy our config */
|
||||
memcpy(&jb->conf, conf, sizeof(struct scx_jb_conf));
|
||||
memcpy(&jb->conf, conf, sizeof(struct fixed_jb_conf));
|
||||
|
||||
/* we dont need the passed config anymore - continue working with the saved one */
|
||||
conf = &jb->conf;
|
||||
|
||||
/* validate the configuration */
|
||||
if (conf->jbsize < 1)
|
||||
conf->jbsize = SCX_JB_SIZE_DEFAULT;
|
||||
conf->jbsize = FIXED_JB_SIZE_DEFAULT;
|
||||
|
||||
if (conf->resync_threshold < 1)
|
||||
conf->resync_threshold = SCX_JB_RESYNCH_THRESHOLD_DEFAULT;
|
||||
conf->resync_threshold = FIXED_JB_RESYNCH_THRESHOLD_DEFAULT;
|
||||
|
||||
/* Set the constant delay to the jitterbuf */
|
||||
jb->delay = conf->jbsize;
|
||||
|
@ -126,7 +124,7 @@ struct scx_jb *scx_jb_new(struct scx_jb_conf *conf)
|
|||
}
|
||||
|
||||
|
||||
void scx_jb_destroy(struct scx_jb *jb)
|
||||
void fixed_jb_destroy(struct fixed_jb *jb)
|
||||
{
|
||||
/* jitterbuf MUST be empty before it can be destroyed */
|
||||
ASSERT(jb->frames == NULL);
|
||||
|
@ -135,17 +133,17 @@ void scx_jb_destroy(struct scx_jb *jb)
|
|||
}
|
||||
|
||||
|
||||
static int resynch_jb(struct scx_jb *jb, void *data, long ms, long ts, long now)
|
||||
static int resynch_jb(struct fixed_jb *jb, void *data, long ms, long ts, long now)
|
||||
{
|
||||
long diff, offset;
|
||||
struct scx_jb_frame *frame;
|
||||
struct fixed_jb_frame *frame;
|
||||
|
||||
/* If jb is empty, just reinitialize the jb */
|
||||
if (!jb->frames) {
|
||||
/* debug check: tail should also be NULL */
|
||||
ASSERT(jb->tail == NULL);
|
||||
|
||||
return scx_jb_put_first(jb, data, ms, ts, now);
|
||||
return fixed_jb_put_first(jb, data, ms, ts, now);
|
||||
}
|
||||
|
||||
/* Adjust all jb state just as the new frame is with delivery = the delivery of the last
|
||||
|
@ -160,7 +158,7 @@ static int resynch_jb(struct scx_jb *jb, void *data, long ms, long ts, long now)
|
|||
|
||||
/* Do we really need to resynch, or this is just a frame for dropping? */
|
||||
if (!jb->force_resynch && (offset < jb->conf.resync_threshold && offset > -jb->conf.resync_threshold))
|
||||
return SCX_JB_DROP;
|
||||
return FIXED_JB_DROP;
|
||||
|
||||
/* Reset the force resynch flag */
|
||||
jb->force_resynch = 0;
|
||||
|
@ -174,17 +172,17 @@ static int resynch_jb(struct scx_jb *jb, void *data, long ms, long ts, long now)
|
|||
}
|
||||
|
||||
/* now jb_put() should add the frame at a last position */
|
||||
return scx_jb_put(jb, data, ms, ts, now);
|
||||
return fixed_jb_put(jb, data, ms, ts, now);
|
||||
}
|
||||
|
||||
|
||||
void scx_jb_set_force_resynch(struct scx_jb *jb)
|
||||
void fixed_jb_set_force_resynch(struct fixed_jb *jb)
|
||||
{
|
||||
jb->force_resynch = 1;
|
||||
}
|
||||
|
||||
|
||||
int scx_jb_put_first(struct scx_jb *jb, void *data, long ms, long ts, long now)
|
||||
int fixed_jb_put_first(struct fixed_jb *jb, void *data, long ms, long ts, long now)
|
||||
{
|
||||
/* this is our first frame - set the base of the receivers time */
|
||||
jb->rxcore = now - ts;
|
||||
|
@ -193,13 +191,13 @@ int scx_jb_put_first(struct scx_jb *jb, void *data, long ms, long ts, long now)
|
|||
jb->next_delivery = now + jb->delay;
|
||||
|
||||
/* put the frame */
|
||||
return scx_jb_put(jb, data, ms, ts, now);
|
||||
return fixed_jb_put(jb, data, ms, ts, now);
|
||||
}
|
||||
|
||||
|
||||
int scx_jb_put(struct scx_jb *jb, void *data, long ms, long ts, long now)
|
||||
int fixed_jb_put(struct fixed_jb *jb, void *data, long ms, long ts, long now)
|
||||
{
|
||||
struct scx_jb_frame *frame, *next, *newframe;
|
||||
struct fixed_jb_frame *frame, *next, *newframe;
|
||||
long delivery;
|
||||
|
||||
/* debug check the validity of the input params */
|
||||
|
@ -269,7 +267,7 @@ int scx_jb_put(struct scx_jb *jb, void *data, long ms, long ts, long now)
|
|||
}
|
||||
newframe->prev = frame;
|
||||
|
||||
return SCX_JB_OK;
|
||||
return FIXED_JB_OK;
|
||||
} else if (!jb->frames) {
|
||||
/* the frame list is empty or thats just the first frame ever */
|
||||
/* tail should also be NULL is that case */
|
||||
|
@ -278,7 +276,7 @@ int scx_jb_put(struct scx_jb *jb, void *data, long ms, long ts, long now)
|
|||
newframe->next = NULL;
|
||||
newframe->prev = NULL;
|
||||
|
||||
return SCX_JB_OK;
|
||||
return FIXED_JB_OK;
|
||||
} else {
|
||||
/* insert on a first position - should update frames head */
|
||||
newframe->next = jb->frames;
|
||||
|
@ -286,19 +284,19 @@ int scx_jb_put(struct scx_jb *jb, void *data, long ms, long ts, long now)
|
|||
jb->frames->prev = newframe;
|
||||
jb->frames = newframe;
|
||||
|
||||
return SCX_JB_OK;
|
||||
return FIXED_JB_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int scx_jb_get(struct scx_jb *jb, struct scx_jb_frame *frame, long now, long interpl)
|
||||
int fixed_jb_get(struct fixed_jb *jb, struct fixed_jb_frame *frame, long now, long interpl)
|
||||
{
|
||||
ASSERT(now >= 0);
|
||||
ASSERT(interpl >= 2);
|
||||
|
||||
if (now < jb->next_delivery) {
|
||||
/* too early for the next frame */
|
||||
return SCX_JB_NOFRAME;
|
||||
return FIXED_JB_NOFRAME;
|
||||
}
|
||||
|
||||
/* Is the jb empty? */
|
||||
|
@ -307,7 +305,7 @@ int scx_jb_get(struct scx_jb *jb, struct scx_jb_frame *frame, long now, long int
|
|||
/* update next */
|
||||
jb->next_delivery += interpl;
|
||||
|
||||
return SCX_JB_INTERP;
|
||||
return FIXED_JB_INTERP;
|
||||
}
|
||||
|
||||
/* Isn't it too late for the first frame available in the jb? */
|
||||
|
@ -315,7 +313,7 @@ int scx_jb_get(struct scx_jb *jb, struct scx_jb_frame *frame, long now, long int
|
|||
/* yes - should drop this frame and update next to point the next frame (get_jb_head() does it) */
|
||||
get_jb_head(jb, frame);
|
||||
|
||||
return SCX_JB_DROP;
|
||||
return FIXED_JB_DROP;
|
||||
}
|
||||
|
||||
/* isn't it too early to play the first frame available? */
|
||||
|
@ -324,28 +322,28 @@ int scx_jb_get(struct scx_jb *jb, struct scx_jb_frame *frame, long now, long int
|
|||
/* update next */
|
||||
jb->next_delivery += interpl;
|
||||
|
||||
return SCX_JB_INTERP;
|
||||
return FIXED_JB_INTERP;
|
||||
}
|
||||
|
||||
/* we have a frame for playing now (get_jb_head() updates next) */
|
||||
get_jb_head(jb, frame);
|
||||
|
||||
return SCX_JB_OK;
|
||||
return FIXED_JB_OK;
|
||||
}
|
||||
|
||||
|
||||
long scx_jb_next(struct scx_jb *jb)
|
||||
long fixed_jb_next(struct fixed_jb *jb)
|
||||
{
|
||||
return jb->next_delivery;
|
||||
}
|
||||
|
||||
|
||||
int scx_jb_remove(struct scx_jb *jb, struct scx_jb_frame *frameout)
|
||||
int fixed_jb_remove(struct fixed_jb *jb, struct fixed_jb_frame *frameout)
|
||||
{
|
||||
if (!jb->frames)
|
||||
return SCX_JB_NOFRAME;
|
||||
return FIXED_JB_NOFRAME;
|
||||
|
||||
get_jb_head(jb, frameout);
|
||||
|
||||
return SCX_JB_OK;
|
||||
return FIXED_JB_OK;
|
||||
}
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* scx_jitterbuf: jitterbuffering algorithm
|
||||
*
|
||||
* Copyright (C) 2005, Attractel OOD
|
||||
*
|
||||
* Contributors:
|
||||
|
@ -25,8 +23,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef _SCX_JITTERBUF_H_
|
||||
#define _SCX_JITTERBUF_H_
|
||||
#ifndef _FIXEDJITTERBUF_H_
|
||||
#define _FIXEDJITTERBUF_H_
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
|
@ -35,61 +33,61 @@ extern "C" {
|
|||
|
||||
/* return codes */
|
||||
enum {
|
||||
SCX_JB_OK,
|
||||
SCX_JB_DROP,
|
||||
SCX_JB_INTERP,
|
||||
SCX_JB_NOFRAME
|
||||
FIXED_JB_OK,
|
||||
FIXED_JB_DROP,
|
||||
FIXED_JB_INTERP,
|
||||
FIXED_JB_NOFRAME
|
||||
};
|
||||
|
||||
|
||||
/* defaults */
|
||||
#define SCX_JB_SIZE_DEFAULT 200
|
||||
#define SCX_JB_RESYNCH_THRESHOLD_DEFAULT 1000
|
||||
#define FIXED_JB_SIZE_DEFAULT 200
|
||||
#define FIXED_JB_RESYNCH_THRESHOLD_DEFAULT 1000
|
||||
|
||||
|
||||
/* jb configuration properties */
|
||||
struct scx_jb_conf
|
||||
struct fixed_jb_conf
|
||||
{
|
||||
long jbsize;
|
||||
long resync_threshold;
|
||||
};
|
||||
|
||||
|
||||
struct scx_jb_frame
|
||||
struct fixed_jb_frame
|
||||
{
|
||||
void *data;
|
||||
long ts;
|
||||
long ms;
|
||||
long delivery;
|
||||
struct scx_jb_frame *next;
|
||||
struct scx_jb_frame *prev;
|
||||
struct fixed_jb_frame *next;
|
||||
struct fixed_jb_frame *prev;
|
||||
};
|
||||
|
||||
|
||||
struct scx_jb;
|
||||
struct fixed_jb;
|
||||
|
||||
|
||||
/* jb interface */
|
||||
|
||||
struct scx_jb * scx_jb_new(struct scx_jb_conf *conf);
|
||||
struct fixed_jb * fixed_jb_new(struct fixed_jb_conf *conf);
|
||||
|
||||
void scx_jb_destroy(struct scx_jb *jb);
|
||||
void fixed_jb_destroy(struct fixed_jb *jb);
|
||||
|
||||
int scx_jb_put_first(struct scx_jb *jb, void *data, long ms, long ts, long now);
|
||||
int fixed_jb_put_first(struct fixed_jb *jb, void *data, long ms, long ts, long now);
|
||||
|
||||
int scx_jb_put(struct scx_jb *jb, void *data, long ms, long ts, long now);
|
||||
int fixed_jb_put(struct fixed_jb *jb, void *data, long ms, long ts, long now);
|
||||
|
||||
int scx_jb_get(struct scx_jb *jb, struct scx_jb_frame *frame, long now, long interpl);
|
||||
int fixed_jb_get(struct fixed_jb *jb, struct fixed_jb_frame *frame, long now, long interpl);
|
||||
|
||||
long scx_jb_next(struct scx_jb *jb);
|
||||
long fixed_jb_next(struct fixed_jb *jb);
|
||||
|
||||
int scx_jb_remove(struct scx_jb *jb, struct scx_jb_frame *frameout);
|
||||
int fixed_jb_remove(struct fixed_jb *jb, struct fixed_jb_frame *frameout);
|
||||
|
||||
void scx_jb_set_force_resynch(struct scx_jb *jb);
|
||||
void fixed_jb_set_force_resynch(struct fixed_jb *jb);
|
||||
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SCX_JITTERBUF_H_ */
|
||||
#endif /* _FIXEDJITTERBUF_H_ */
|
Reference in New Issue