summaryrefslogtreecommitdiff
path: root/pjmedia/include
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2008-01-04 18:19:40 +0000
committerBenny Prijono <bennylp@teluu.com>2008-01-04 18:19:40 +0000
commitc828a3b26763bdfae04032c4962098e8343b8d92 (patch)
tree51e49c3389c48e965be396d41e902a21c1fb0738 /pjmedia/include
parent16ada6b2083d10fac21bdf022fe4231dc9009421 (diff)
Ticket #438 (Workaround for frame bursts from audio devices): added delay buffer implementation in pjmedia
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1664 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia/include')
-rw-r--r--pjmedia/include/pjmedia/config.h27
-rw-r--r--pjmedia/include/pjmedia/delaybuf.h138
2 files changed, 165 insertions, 0 deletions
diff --git a/pjmedia/include/pjmedia/config.h b/pjmedia/include/pjmedia/config.h
index 4528c8fe..c39c7172 100644
--- a/pjmedia/include/pjmedia/config.h
+++ b/pjmedia/include/pjmedia/config.h
@@ -91,6 +91,30 @@
/**
+ * Specify whether delay buffer is used for sound device.
+ * When delay buffer is enabled, the sound device callback
+ * will be called one after another evenly.
+ * The delay buffer also performs the best delay calculation
+ * for the sound device, and will try to limit the delay caused
+ * by uneven callback calls to this delay.
+ */
+#ifndef PJMEDIA_SOUND_USE_DELAYBUF
+# define PJMEDIA_SOUND_USE_DELAYBUF 0
+#endif
+
+
+/**
+ * Whenever delay buffer is enabled for sound device,
+ * PJMEDIA_SOUND_BUFFER_COUNT is better to be set to 1,
+ * because sound callbacks will be called evenly thus
+ * there's no need to have this buffer.
+ */
+#if defined(PJMEDIA_SOUND_USE_DELAYBUF) && PJMEDIA_SOUND_USE_DELAYBUF!=0
+# define PJMEDIA_SOUND_BUFFER_COUNT 1
+#endif
+
+
+/**
* Specify number of sound buffers. Larger number is better for sound
* stability and to accommodate sound devices that are unable to send frames
* in timely manner, however it would probably cause more audio delay (and
@@ -100,6 +124,9 @@
* The setting here currently is used by the conference bridge, the splitter
* combiner port, and dsound.c.
*
+ * Note that when PJMEDIA_SOUND_USE_DELAYBUF is enabled, it's best to
+ * set PJMEDIA_SOUND_BUFFER_COUNT to 1 to reduce voice latency.
+ *
* Default: 6
*/
#ifndef PJMEDIA_SOUND_BUFFER_COUNT
diff --git a/pjmedia/include/pjmedia/delaybuf.h b/pjmedia/include/pjmedia/delaybuf.h
new file mode 100644
index 00000000..bdb0dd1d
--- /dev/null
+++ b/pjmedia/include/pjmedia/delaybuf.h
@@ -0,0 +1,138 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2003-2007 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __PJMEDIA_DELAYBUF_H__
+#define __PJMEDIA_DELAYBUF_H__
+
+
+/**
+ * @file delaybuf.h
+ * @brief Delay Buffer.
+ */
+
+#include <pjmedia/types.h>
+
+/**
+ * @defgroup PJMED_DELAYBUF Delay Buffer
+ * @ingroup PJMEDIA_FRAME_OP
+ * @{
+ * This section describes PJMEDIA's implementation of delay buffer.
+ * Delay buffer works quite similarly like a fixed jitter buffer, that
+ * is it will delay the frame retrieval by some interval so that caller
+ * will get continuous frame from the buffer. This can be useful when
+ * the put() and get() operations are not evenly interleaved, for example
+ * when caller performs burst of put() operations and then followed by
+ * burst of get() operations. With using this delay buffer, the buffer
+ * will put the burst frames into a buffer so that get() operations
+ * will always get a frame from the buffer (assuming that the number of
+ * get() and put() are matched).
+ *
+ * The delay buffer is mostly used by the sound port, to accommodate
+ * for the burst frames returned by the sound device.
+ *
+ * To determine the level of delay to be applied, the delay buffer
+ * has a learning period on which it calculates the level of burst of
+ * both the put() and get(), and use the maximum value of both as the
+ * delay level.
+ */
+
+PJ_BEGIN_DECL
+
+/** Opaque declaration for delay buffer. */
+typedef struct pjmedia_delay_buf pjmedia_delay_buf;
+
+/**
+ * Create the delay buffer. Once the delay buffer is created, it will
+ * enter learning state unless the delay argument is specified, which
+ * in this case it will directly enter the running state.
+ *
+ * @param pool Pool where the delay buffer will be allocated
+ * from.
+ * @param name Optional name for the buffer for log
+ * identification.
+ * @param samples_per_frame Number of samples per frame.
+ * @param max_cnt Maximum number of delay to be accommodated,
+ * in number of frames.
+ * @param delay The delay to be applied, in number of frames.
+ * If the value is -1, the delay buffer will
+ * learn about the delay automatically. If
+ * the value is greater than zero, then this
+ * value will be used and no learning will be
+ * performed.
+ * @param p_b Pointer to receive the delay buffer instance.
+ *
+ * @return PJ_SUCCESS if the delay buffer has been
+ * created successfully, otherwise the appropriate
+ * error will be returned.
+ */
+PJ_DECL(pj_status_t) pjmedia_delay_buf_create(pj_pool_t *pool,
+ const char *name,
+ unsigned samples_per_frame,
+ unsigned max_cnt,
+ int delay,
+ pjmedia_delay_buf **p_b);
+
+/**
+ * Put one frame into the buffer.
+ *
+ * @param b The delay buffer.
+ * @param frame Frame to be put into the buffer. This frame
+ * must have samples_per_frame length.
+ *
+ * @return PJ_SUCCESS if frames can be put successfully.
+ * PJ_EPENDING if the buffer is still at learning
+ * state. PJ_ETOOMANY if the number of frames
+ * will exceed maximum delay level, which in this
+ * case the new frame will overwrite the oldest
+ * frame in the buffer.
+ */
+PJ_DECL(pj_status_t) pjmedia_delay_buf_put(pjmedia_delay_buf *b,
+ pj_int16_t frame[]);
+
+/**
+ * Get one frame from the buffer.
+ *
+ * @param b The delay buffer.
+ * @param frame Buffer to receive the frame from the delay
+ * buffer.
+ *
+ * @return PJ_SUCCESS if frame has been copied successfully.
+ * PJ_EPENDING if no frame is available, either
+ * because the buffer is still at learning state or
+ * no buffer is available during running state.
+ * On non-successful return, the frame will be
+ * filled with zeroes.
+ */
+PJ_DECL(pj_status_t) pjmedia_delay_buf_get(pjmedia_delay_buf *b,
+ pj_int16_t frame[]);
+
+/**
+ * Reinitiate learning state. This will clear the buffer's content.
+ *
+ * @param b The delay buffer.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error.
+ */
+PJ_DECL(pj_status_t) pjmedia_delay_buf_learn(pjmedia_delay_buf *b);
+
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_DELAYBUF_H__ */