mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-07 10:28:32 +00:00
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: https://origsvn.digium.com/svn/asterisk/trunk@31052 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
220
include/asterisk/abstract_jb.h
Normal file
220
include/asterisk/abstract_jb.h
Normal file
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* abstract_jb: common implementation-independent jitterbuffer stuff
|
||||
*
|
||||
* Copyright (C) 2005, Attractel OOD
|
||||
*
|
||||
* Contributors:
|
||||
* Slav Klenov <slav@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@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_ */
|
||||
@@ -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,6 +447,9 @@ struct ast_channel {
|
||||
|
||||
/*! For easy linking */
|
||||
AST_LIST_ENTRY(ast_channel) chan_list;
|
||||
|
||||
/*! The jitterbuffer state */
|
||||
struct ast_jb jb;
|
||||
};
|
||||
|
||||
/* \defgroup chanprop Channel tech properties:
|
||||
@@ -452,6 +457,11 @@ struct ast_channel {
|
||||
/* @{ */
|
||||
#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 */
|
||||
#define AST_FLAG_DEFER_DTMF (1 << 1) /*!< if dtmf should be deferred */
|
||||
|
||||
@@ -109,6 +109,14 @@ struct ast_frame {
|
||||
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;
|
||||
};
|
||||
|
||||
/*!
|
||||
|
||||
Reference in New Issue
Block a user