diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8229cbfaf..6f10699dc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -52,7 +52,6 @@ include(CheckCCompilerFlag)
option(USE_REM "Enable Librem" ON)
option(USE_BFCP "Enable BFCP" ON)
-option(USE_JBUF "Enable JBUF" ON)
option(USE_PCP "Enable PCP" ON)
option(USE_RTMP "Enable RTMP" ON)
option(USE_SIP "Enable SIP" ON)
@@ -142,7 +141,6 @@ set(HEADERS
include/re_http.h
include/re_httpauth.h
include/re_ice.h
- include/re_jbuf.h
include/re_json.h
include/re_list.h
include/re_main.h
@@ -446,13 +444,6 @@ if(USE_BFCP)
endif()
-if(USE_JBUF)
- list(APPEND SRCS
- src/jbuf/jbuf.c
- )
-endif()
-
-
if(USE_PCP)
list(APPEND SRCS
src/pcp/msg.c
diff --git a/docs/jbuf/README.md b/docs/jbuf/README.md
deleted file mode 100644
index 7413c2eac..000000000
--- a/docs/jbuf/README.md
+++ /dev/null
@@ -1,188 +0,0 @@
-This adaptive jitter buffer implementation increases the number of packets in
-the buffer during periods of high network jitter. It reduces the number of
-packets if the network condition improves.
-
-
-## Computing the jitter
-
-The network jitter is computed similar to the proposition in RFC-3550 RTP
-section A.8 and similar how wireshark does it. The jitter is a moving average
-of the difference *d* between the real time and the RTP timestamps. Or more
-concretely we compute at each `jbuf_put()` the difference
-
-*d = Dtr - Dts*,
-
-where *Dtr* is the real time elapsed from last call to
-`jbuf_put` and *Dts* is the difference of the timestamps. Then
-with a predefined speed *s* we compute the jitter *j* as moving average
-
-*j = j + s (|d| - j)*.
-
-We choose a higher value for speed *s* if *|d| > j*. Thus the jitter rises fast
-if e.g. suddenly a network jitter appears. In contrast when the network
-condition improves the jitter value slowly shrinks. The reason for different
-rising and falling speed is that we have to react fast to avoid buffer
-under-runs, whereas reducing of the latency may be done a while after the
-network condition improved.
-
-In the following sections we will describe how the computed jitter is used to
-detect situations where the buffered packets should be increased due to a high
-jitter. We call this situations **Low** situations. When the jitter shrinks
-below some specific value it is a good idea to reduce the buffer to reduce the
-audio latency. We call this situations **High** situations. Surely, the
-Low/High situations have to be decided somehow.
-
-## Reduce/Increase buffered packets
-
-When a Low situation is detected we increase the number of packets in jbuf by
-holding back a packet during one call to function `jbuf_get()`. While when
-a High situation is detected we reduce the number of packets by telling baresip
-to immediately call `jbuf_get()` a second time. For this purpose `jbuf_get()`
-returns EAGAIN. Then baresip decodes two RTP packets and thus the audio buffer
-increases by one frame. By means of a silence detection baresip is able to drop
-frames that are not important for the speech quality. This reduces the audio
-latency down to the value before the High situation.
-
-
-## Computing a smooth latency
-
-The RTP packets that are buffered at a concrete point in time in the jbuf lead
-to a temporary latency value lc. Let *p0, ...,
-pm* be the RTP packets currently stored in the jbuf. Then
-
-*lc = tm - t0 + tp*,
-
-where *ti* is the RTP timestamp of packet *pi* and
-*tp* is the packet time (`ptime` in jbuf.c). The packet time is a
-constant that is specified at the beginning of a call. In baresip it is
-specified in the account file.
-
-The temporary latency *lc* is discontinuous over time and not
-adequate for deciding or detecting Low or High situations. Therefore we again
-use a moving average to smooth *lc*. Let *s* be an adequate moving
-average speed, then the smoothed latency
-
-*l = l + s (lc - l)*.
-
-Low/High situations are decided when the smoothed latency *l* runs out of some
-boundaries that are computed from the jitter.
-
-## Deciding Low/High situations
-
-During each iteration (each `jbuf_put()`) the jitter and the latency are
-computed. Additionally we compute the bottom boundary *lb* and the
-top boundary *lt* with
-
-*lb = 1.25 j* and
-
-*lt = 2.2 j*.
-
-Since we want to respect also the parameter `min` of function `jbuf_alloc()` we
-extend these formulas. Let *mm* be the parameter `min`. Then
-
-*lb = max(mm 2 tp / 3, 1.25 j)* and
-
-*lt = max(mm 11 tp / 3, 2.2 j)*,
-
-where *tp* is the `ptime` as defined already. Finally we have
-everything for deciding Low and High situations. That is if *l* moves out of
-the boundaries
-
-*lb < l < lt*
-
-then we fire a Low/High.
-
-## Early adjustment of the latency
-
-Finally, if we detect a Low/High situation we increase/reduce the number of
-packets. Now we immediately increment/decrement the smoothed latency *l* by
-one packet time. So early adjustment for a Low situation is
-
-*l = l + lp* and for a High situation
-*l = l - lp*.
-
-
-This avoids multiple Low/High detections in a row.
-
-
-## Silence detection
-
-It is preferable to hold back an RTP packet in `jbuf_get()` only during a
-period of silence. But deciding if there is currently silence in the RTP stream
-can only be done by investigating the audio frames after decoding the RTP
-packet. Decoding is done in baresip. Thus we add a function `jbuf_silence()`
-that sets the flag `silence`. This function has to be called by baresip.
-
-
-## Math symbols vs. C-variables
-
-In order to avoid float computation we use a constant factor
-```JBUF_JITTER_PERIOD``` for all time based variables in jbuf.c. Apart from
-that the symbols used here are mapped to the C-variables like this table shows:
-
-
-Symbol|Variable
-------|--------
-*d* | `d`
-*j* | `jitter`
-*l* | `avbuftime`
-*lc* | `buftime`
-*lb* | `bufmin`
-*lt* | `bufmax`
-*tp* | `ptime`
-
-
-## Wish size
-
-We introduce also the parameter `wish` and a setter function `jbuf_set_wish()`.
-The wish size is the number of packets that will be collected at the beginning
-of an RTP stream before `jbuf_get()` will return the first packet. If the user
-passes `wish=0` then it is set internally to `min`. If the user knows that the
-network contains jitter he may set the wish size to some adequate value. This
-avoids underflows at the beginning of the stream. The `min` parameter can be
-left at some lower value. When the network situation improves, the buffer is
-reduced down to `min`. Thus the latency is reduced to the specified minimum.
-
-
-## How to test jbuf
-
-- In jbuf.c set DEBUG\_LEVEL to 6, build and install libre again!
-
-- Add bridge interface linked to your Ethernet/WiFi interface! Suppose baresip
-is connected to the network interface *eth0*. Replace *eth0* with your physical
-network interface! See the man pages of "ip" and "tc" for further details!
-
-```
-sudo ip link add ifb1 type ifb || :
-sudo ip link set ifb1 up
-sudo tc qdisc add dev eth0 handle ffff: ingress
-sudo tc filter add dev eth0 parent ffff: u32 match u32 0 0 action mirred egress redirect dev ifb1
-```
-
-This redirects the incoming eth0 traffic to a new ifb interface.
-
-- How to activate the jitter. Here we set the delay to 100ms ± 50ms.
-```
-sudo tc qdisc add dev ifb1 root netem delay 100ms 50ms
-```
-
-- How to deactivate the jitter.
-```
-sudo tc qdisc del dev ifb1 root
-```
-
-- See/Use jbuf.plot to generate a plot!
-
-Note:
-- Activate and deactivate the network jitter during a call to see how the
-adaptive jitter buffer algorithm works!
-- You need a very new kernel or at least some patches for the sch_netem kernel
-module. There was a problem which lead to many reordered and very late RTP
-packets. Be sure that you have this commit in the kernel:
-```
-commit eadd1befdd778a1eca57fad058782bd22b4db804
-Author: Aleksandr Nogikh
-Date: Wed Oct 28 17:07:31 2020 +0000
-
- netem: fix zero division in tabledist
-```
diff --git a/docs/jbuf/jbuf.plot b/docs/jbuf/jbuf.plot
deleted file mode 100755
index 5d681456d..000000000
--- a/docs/jbuf/jbuf.plot
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/gnuplot
-#
-# How to generate a plot
-# ======================
-# This gnuplot script plots DEBUG_LEVEL 6 output of jbuf.c. You have to
-# increment the DEBUG_LEVEL in jbuf.c if you want to get the table for
-# jbuf.dat. Then call baresip like this:
-#
-# ./baresip 2>&1 | grep -Eo "plot_stat.*" jbuf.log > jbuf.dat
-#
-# Call this script. Then compare the plot legend with the variables in jbuf.c!
-#
-#
-# Description of the plot
-# =======================
-# The plot is a time based diagram. The values avbuftime should lie between
-# bufmin and bufmax. If it runs somewhere out of these boundaries (and stays
-# outside for a while) a "Low" / "High" situation is detected.
-#
-# "Good" means: The number of packets in the jitter buffer is ok.
-#
-# "Low" means: The number is too low. Then the packets are incremented by
-# holding one packet back in jbuf_get().
-#
-# "High" means: The number is to high. Then packets are decremented by dropping
-# one packet in jbuf_put(). This reduces the audio delay.
-#
-# The number of "Low"/"High" situations should be low while buffer under-runs
-# should be avoided completely.
-
-# On the x-axes of the plot there is the time in milliseconds. See function
-# jbuf_jitter_calc()! We note the variables in jbuf.c here in parentheses.
-# E.g. (var jitter).
-#
-# - The orange line is the computed network jitter (var jitter). This is a
-# moving average of the difference (var d) between the real time diff
-# (var tr - var tr0) and the RTP timestamps diff (var ts - var ts0).
-# See RFC-3550 RTP - A.8!
-# We suggest a fast rise of the moving average and a slow shrink. Thus
-# avoiding buffer under-runs have a higher priority than reducing the audio
-# delay.
-#
-# - The buftime (var buftime) is the difference of the timestamps between the
-# last RTP packet and the first RTP packet stored in the jbuf plus one packet
-# time (var ptime) for the last packet.
-# The buftime (light-grey) changes very fast during periods of jitter. To be
-# applicable for detecting "Low" or "High" situations it has to be smoothed.
-# The blue line avbuftime (var avbuftime) is a moving average of the buftime
-# and is used to detect "Low"/"High". Thus the jbuf algorithm tries to keep
-# the avbuftime between the following boundaries.
-#
-# - The green lines bufmin and bufmax (var bufmin, bufmax) are boundaries for
-# avbuftime.They are computed by constant factors (> 1.) from the jitter.
-#
-#
-# Copyright (C) 2020 commend.com - Christian Spielberger, Michael Peitler
-
-
-# Choose your preferred gnuplot terminal or use e.g. evince to view the
-# jbuf.eps!
-
-#set terminal x11
-set terminal postscript eps size 15,10 enhanced color
-set output 'jbuf.eps'
-#set terminal png size 1280,480
-#set output 'jbuf.png'
-set datafile separator ","
-set key outside
-plot \
-'jbuf.dat' using 2:4 title 'jitter' with linespoints linecolor "orange", \
-'jbuf.dat' using 2:6 title 'avbuftime' with linespoints linecolor "skyblue", \
-'jbuf.dat' using 2:7 title 'bufmin' with linespoints linecolor "sea-green", \
-'jbuf.dat' using 2:8 title 'bufmax' with linespoints linecolor "sea-green", \
-'jbuf.dat' using 2:($9*10) title 'Good/Empty/Low/High' linecolor "red", \
-'jbuf.dat' using 2:5 title 'buftime' linecolor "light-grey", \
-10 title "Empty=10" linecolor "red", \
-20 title "Low=20" linecolor "red", \
-30 title "High=30" linecolor "red"
-
diff --git a/include/re.h b/include/re.h
index 83e352b31..2167f9bba 100644
--- a/include/re.h
+++ b/include/re.h
@@ -34,7 +34,6 @@ extern "C" {
#include "re_http.h"
#include "re_httpauth.h"
#include "re_ice.h"
-#include "re_jbuf.h"
#include "re_net.h"
#include "re_main.h"
#include "re_md5.h"
diff --git a/include/re_jbuf.h b/include/re_jbuf.h
deleted file mode 100644
index f9698b485..000000000
--- a/include/re_jbuf.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * @file re_jbuf.h Interface to Jitter Buffer
- *
- * Copyright (C) 2010 Creytiv.com
- */
-struct jbuf;
-struct rtp_header;
-
-/** Jitter buffer statistics */
-struct jbuf_stat {
- uint32_t n_put; /**< Number of frames put into jitter buffer */
- uint32_t n_get; /**< Number of frames got from jitter buffer */
- uint32_t n_oos; /**< Number of out-of-sequence frames */
- uint32_t n_dups; /**< Number of duplicate frames detected */
- uint32_t n_late; /**< Number of frames arriving too late */
- uint32_t n_lost; /**< Number of lost frames */
- uint32_t n_overflow; /**< Number of overflows */
- uint32_t n_underflow; /**< Number of underflows */
- uint32_t n_flush; /**< Number of times jitter buffer flushed */
-};
-
-
-/** Jitter buffer type */
-enum jbuf_type {
- JBUF_OFF,
- JBUF_FIXED,
- JBUF_ADAPTIVE
-};
-
-
-int jbuf_alloc(struct jbuf **jbp, uint32_t min, uint32_t max);
-int jbuf_set_type(struct jbuf *jb, enum jbuf_type jbtype);
-int jbuf_put(struct jbuf *jb, const struct rtp_header *hdr, void *mem);
-int jbuf_get(struct jbuf *jb, struct rtp_header *hdr, void **mem);
-int jbuf_drain(struct jbuf *jb, struct rtp_header *hdr, void **mem);
-void jbuf_flush(struct jbuf *jb);
-int jbuf_stats(const struct jbuf *jb, struct jbuf_stat *jstat);
-int jbuf_debug(struct re_printf *pf, const struct jbuf *jb);
-uint32_t jbuf_frames(const struct jbuf *jb);
-uint32_t jbuf_packets(const struct jbuf *jb);
diff --git a/src/jbuf/jbuf.c b/src/jbuf/jbuf.c
deleted file mode 100644
index d2a32dc56..000000000
--- a/src/jbuf/jbuf.c
+++ /dev/null
@@ -1,802 +0,0 @@
-/**
- * @file jbuf.c Jitter Buffer implementation
- *
- * This is an adaptive jitter buffer implementation. See doc/jbuf for further
- * details!
- *
- * Copyright (C) 2010 Creytiv.com
- */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-
-#define DEBUG_MODULE "jbuf"
-#define DEBUG_LEVEL 5
-#include
-
-
-#ifndef RELEASE
-#define JBUF_STAT 1 /**< Jitter buffer statistics */
-#endif
-
-
-#if JBUF_STAT
-#define STAT_ADD(var, value) (jb->stat.var) += (value) /**< Stats add */
-#define STAT_INC(var) ++(jb->stat.var) /**< Stats inc */
-#else
-#define STAT_ADD(var, value)
-#define STAT_INC(var)
-#endif
-
-enum {
- JBUF_RDIFF_EMA_COEFF = 1024,
- JBUF_RDIFF_UP_SPEED = 512,
- JBUF_PUT_TIMEOUT = 400,
-};
-
-
-/** Defines a packet frame */
-struct packet {
- struct le le; /**< Linked list element */
- struct rtp_header hdr; /**< RTP Header */
- void *mem; /**< Reference counted pointer */
-};
-
-
-/**
- * Defines a jitter buffer
- *
- * The jitter buffer is for incoming RTP packets, which are sorted by
- * sequence number.
- */
-struct jbuf {
- struct list pooll; /**< List of free packets in pool */
- struct list packetl; /**< List of buffered packets */
- uint32_t n; /**< [# packets] Current # of packets in buffer */
- uint32_t nf; /**< [# frames] Current # of frames in buffer */
- uint32_t min; /**< [# frames] Minimum # of frames to buffer */
- uint32_t max; /**< [# frames] Maximum # of frames to buffer */
- uint32_t wish; /**< [# frames] Wish size for adaptive mode */
- uint16_t seq_put; /**< Sequence number for last jbuf_put() */
- uint16_t seq_get; /**< Sequence number of last played frame */
- uint32_t ssrc; /**< Previous ssrc */
- uint64_t tr; /**< Time of previous jbuf_put() */
- int pt; /**< Payload type */
- bool running; /**< Jitter buffer is running */
- int32_t rdiff; /**< Average out of order reverse diff */
- struct tmr tmr; /**< Rdiff down timer */
-
- mtx_t *lock; /**< Makes jitter buffer thread safe */
- enum jbuf_type jbtype; /**< Jitter buffer type */
-#if JBUF_STAT
- struct jbuf_stat stat; /**< Jitter buffer Statistics */
-#endif
-#ifdef RE_JBUF_TRACE
- uint64_t tr00; /**< Arrival of first packet */
- char buf[136]; /**< Buffer for trace */
-#endif
-};
-
-
-/** Is x less than y? */
-static inline bool seq_less(uint16_t x, uint16_t y)
-{
- return ((int16_t)(x - y)) < 0;
-}
-
-
-#ifdef RE_JBUF_TRACE
-static void plot_jbuf(struct jbuf *jb, uint64_t tr)
-{
- uint32_t treal;
- uint32_t rdiff = (uint32_t)(jb->rdiff / (float)JBUF_RDIFF_EMA_COEFF);
-
- if (!jb->tr00)
- jb->tr00 = tr;
-
- treal = (uint32_t) (tr - jb->tr00);
- re_snprintf(jb->buf, sizeof(jb->buf),
- "%s, 0x%p, %u, %u, %u, %u, %u",
- __func__, /* row 1 - grep */
- jb, /* row 2 - grep optional */
- treal, /* row 3 - plot x-axis */
- rdiff, /* row 4 - plot */
- jb->wish, /* row 5 - plot */
- jb->n, /* row 6 - plot */
- jb->nf); /* row 7 - plot */
- re_trace_event("jbuf", "plot", 'P', NULL, 0, RE_TRACE_ARG_STRING_COPY,
- "line", jb->buf);
-}
-
-
-static void plot_jbuf_event(struct jbuf *jb, char ph)
-{
- uint32_t treal;
- uint64_t tr;
-
- tr = tmr_jiffies();
- if (!jb->tr00)
- jb->tr00 = tr;
-
- treal = (uint32_t) (tr - jb->tr00);
- re_snprintf(jb->buf, sizeof(jb->buf), "%s, 0x%p, %u, %i",
- __func__, /* row 1 - grep */
- jb, /* row 2 - grep optional */
- treal, /* row 3 - plot x-axis */
- 1); /* row 4 - plot */
- re_trace_event("jbuf", "plot", ph, NULL, 0, RE_TRACE_ARG_STRING_COPY,
- "line", jb->buf);
-}
-#else
-static void plot_jbuf_event(struct jbuf *jb, char ph)
-{
- (void)jb;
- (void)ph;
-}
-#endif
-
-
-/**
- * Get a frame from the pool
- */
-static void packet_alloc(struct jbuf *jb, struct packet **f)
-{
- struct le *le;
-
- le = jb->pooll.head;
- if (le) {
- list_unlink(le);
- ++jb->n;
- }
- else {
- struct packet *f0;
-
- /* Steal an old frame */
- le = jb->packetl.head;
- f0 = le->data;
-
-#if JBUF_STAT
- STAT_INC(n_overflow);
- DEBUG_WARNING("drop 1 old frame seq=%u (total dropped %u)\n",
- f0->hdr.seq, jb->stat.n_overflow);
-#else
- DEBUG_WARNING("drop 1 old frame seq=%u\n", f0->hdr.seq);
-#endif
-
- plot_jbuf_event(jb, 'O');
- f0->mem = mem_deref(f0->mem);
- list_unlink(le);
- }
-
- *f = le->data;
-}
-
-
-/**
- * Release a packet, put it back in the pool
- */
-static void packet_deref(struct jbuf *jb, struct packet *f)
-{
- f->mem = mem_deref(f->mem);
- list_unlink(&f->le);
- list_append(&jb->pooll, &f->le, f);
- --jb->n;
-}
-
-
-static void jbuf_destructor(void *data)
-{
- struct jbuf *jb = data;
-
- tmr_cancel(&jb->tmr);
- jbuf_flush(jb);
-
- /* Free all packets in the pool list */
- list_flush(&jb->pooll);
- mem_deref(jb->lock);
-}
-
-
-/**
- * Allocate a new jitter buffer
- *
- * @param jbp Pointer to returned jitter buffer
- * @param min Minimum delay in [frames]
- * @param max Maximum delay in [packets]
- *
- * @return 0 if success, otherwise errorcode
- */
-int jbuf_alloc(struct jbuf **jbp, uint32_t min, uint32_t max)
-{
- struct jbuf *jb;
- uint32_t i;
- int err = 0;
-
- if (!jbp || ( min > max))
- return EINVAL;
-
- /* self-test: x < y (also handle wrap around) */
- if (!seq_less(10, 20) || seq_less(20, 10) || !seq_less(65535, 0)) {
- DEBUG_WARNING("seq_less() is broken\n");
- return ENOSYS;
- }
-
- jb = mem_zalloc(sizeof(*jb), NULL);
- if (!jb)
- return ENOMEM;
-
- list_init(&jb->pooll);
- list_init(&jb->packetl);
-
- jb->jbtype = JBUF_FIXED;
- jb->min = min;
- jb->max = max;
- jb->wish = min;
- tmr_init(&jb->tmr);
-
- DEBUG_INFO("alloc: delay=%u-%u frames/packets\n", min, max);
-
- jb->pt = -1;
- err = mutex_alloc(&jb->lock);
- if (err)
- goto out;
-
- mem_destructor(jb, jbuf_destructor);
-
- /* Allocate all packets now */
- for (i=0; imax; i++) {
- struct packet *f = mem_zalloc(sizeof(*f), NULL);
- if (!f) {
- err = ENOMEM;
- break;
- }
-
- list_append(&jb->pooll, &f->le, f);
- DEBUG_INFO("alloc: adding to pool list %u\n", i);
- }
-
-out:
- if (err)
- mem_deref(jb);
- else
- *jbp = jb;
-
- return err;
-}
-
-
-/**
- * Set jitter buffer type.
- *
- * @param jb The jitter buffer.
- * @param jbtype The jitter buffer type.
- *
- * @return 0 if success, otherwise errorcode
- */
-int jbuf_set_type(struct jbuf *jb, enum jbuf_type jbtype)
-{
- if (!jb)
- return EINVAL;
-
- jb->jbtype = jbtype;
-
- return 0;
-}
-
-
-static void wish_down(void *arg)
-{
- struct jbuf *jb = arg;
-
- if (jb->wish > jb->min) {
- DEBUG_INFO("wish size changed %u --> %u\n", jb->wish,
- jb->wish - 1);
- --jb->wish;
- }
-}
-
-
-static void calc_rdiff(struct jbuf *jb, uint16_t seq)
-{
- int32_t rdiff;
- int32_t adiff;
- int32_t s; /**< EMA coefficient */
- float ratio = 1.0; /**< Frame packet ratio */
- uint32_t wish;
- uint32_t max = jb->max;
- bool down = false;
-
- if (jb->jbtype != JBUF_ADAPTIVE)
- return;
-
- if (!jb->seq_get)
- return;
-
- if (jb->nf) {
- ratio = (float)jb->n / (float)jb->nf;
- max = (uint32_t)(max / ratio);
- }
-
- rdiff = (int16_t)(jb->seq_put + 1 - seq);
- adiff = abs(rdiff * JBUF_RDIFF_EMA_COEFF);
- s = adiff > jb->rdiff ? JBUF_RDIFF_UP_SPEED :
- jb->wish > 2 ? 1 :
- jb->wish > 1 ? 2 : 3;
- jb->rdiff += (adiff - jb->rdiff) * s / JBUF_RDIFF_EMA_COEFF;
-
- wish = (uint32_t)(jb->rdiff / (float)JBUF_RDIFF_EMA_COEFF / ratio);
- if (wish < jb->min)
- wish = jb->min;
-
- if (max && wish >= max)
- wish = max - 1;
-
- if (wish > jb->wish) {
- DEBUG_INFO("wish size changed %u --> %u\n", jb->wish, wish);
- jb->wish = wish;
- }
- else if (wish < jb->wish) {
- uint32_t dt = wish + 1 == jb->wish ? 6000 : 1000;
- if (!tmr_isrunning(&jb->tmr) || tmr_get_expire(&jb->tmr) > dt)
- tmr_start(&jb->tmr, dt, wish_down, jb);
-
- down = true;
- }
-
- if (!down && tmr_isrunning(&jb->tmr))
- tmr_cancel(&jb->tmr);
-}
-
-
-/**
- * Put one packet into the jitter buffer
- *
- * @param jb Jitter buffer
- * @param hdr RTP Header
- * @param mem Memory pointer - will be referenced
- *
- * @return 0 if success, otherwise errorcode
- */
-int jbuf_put(struct jbuf *jb, const struct rtp_header *hdr, void *mem)
-{
- struct packet *f;
- struct packet *fc;
- struct le *le, *tail;
- uint16_t seq;
- uint64_t tr, dt;
- bool equal;
- int err = 0;
-
- if (!jb || !hdr)
- return EINVAL;
-
- seq = hdr->seq;
- if (jb->pt == -1)
- jb->pt = hdr->pt;
-
- if (jb->ssrc && jb->ssrc != hdr->ssrc) {
- DEBUG_INFO("ssrc changed %u %u\n", jb->ssrc, hdr->ssrc);
- jbuf_flush(jb);
- }
-
- tr = tmr_jiffies();
- dt = tr - jb->tr;
- if (jb->tr && dt > JBUF_PUT_TIMEOUT) {
- DEBUG_INFO("put timeout %lu ms, marker %d\n", dt, hdr->m);
- if (hdr->m)
- jbuf_flush(jb);
- }
-
- jb->tr = tr;
-
- mtx_lock(jb->lock);
- jb->ssrc = hdr->ssrc;
-
- if (jb->running) {
-
- if (jb->jbtype == JBUF_ADAPTIVE)
- calc_rdiff(jb, seq);
-
- /* Packet arrived too late to be put into buffer */
- if (jb->seq_get && seq_less(seq, jb->seq_get + 1)) {
- STAT_INC(n_late);
- plot_jbuf_event(jb, 'L');
- DEBUG_INFO("packet too late: seq=%u "
- "(seq_put=%u seq_get=%u)\n",
- seq, jb->seq_put, jb->seq_get);
- err = ETIMEDOUT;
- goto out;
- }
-
- }
-
- STAT_INC(n_put);
-
- packet_alloc(jb, &f);
-
- tail = jb->packetl.tail;
-
- /* If buffer is empty -> append to tail
- Frame is later than tail -> append to tail
- */
- if (!tail || seq_less(((struct packet *)tail->data)->hdr.seq, seq)) {
- list_append(&jb->packetl, &f->le, f);
- goto success;
- }
-
- /* Out-of-sequence, find right position */
- for (le = tail; le; le = le->prev) {
- const uint16_t seq_le = ((struct packet *)le->data)->hdr.seq;
-
- if (seq_less(seq_le, seq)) { /* most likely */
- DEBUG_PRINTF("put: out-of-sequence"
- " - inserting after seq=%u (seq=%u)\n",
- seq_le, seq);
- list_insert_after(&jb->packetl, le, &f->le, f);
- break;
- }
- else if (seq == seq_le) { /* less likely */
- /* Detect duplicates */
- DEBUG_INFO("duplicate: seq=%u\n", seq);
- STAT_INC(n_dups);
- plot_jbuf_event(jb, 'D');
- list_insert_after(&jb->packetl, le, &f->le, f);
- packet_deref(jb, f);
- err = EALREADY;
- goto out;
- }
-
- /* sequence number less than current seq, continue */
- }
-
- /* no earlier sequence found, put in head */
- if (!le) {
- DEBUG_PRINTF("put: out-of-sequence"
- " - put in head (seq=%u)\n", seq);
- list_prepend(&jb->packetl, &f->le, f);
- }
-
- STAT_INC(n_oos);
- plot_jbuf_event(jb, 'S');
-
-success:
- /* Update last sequence */
- jb->running = true;
- jb->seq_put = seq;
-
- /* Success */
- f->hdr = *hdr;
- f->mem = mem_ref(mem);
-
- equal = false;
- if (f->le.prev) {
- fc = f->le.prev->data;
- equal = (fc->hdr.ts == f->hdr.ts);
- }
-
- if (!equal && f->le.next) {
- fc = f->le.next->data;
- equal = (fc->hdr.ts == f->hdr.ts);
- }
-
- if (!equal)
- ++jb->nf;
-
-out:
-#ifdef RE_JBUF_TRACE
- plot_jbuf(jb, tr);
-#endif
- mtx_unlock(jb->lock);
- return err;
-}
-
-
-/**
- * Get one packet from the jitter buffer
- *
- * @param jb Jitter buffer
- * @param hdr Returned RTP Header
- * @param mem Pointer to memory object storage - referenced on success
- *
- * @return 0 if success, EAGAIN if it should be called again in order to avoid
- * a jitter buffer overflow, otherwise errorcode
- */
-int jbuf_get(struct jbuf *jb, struct rtp_header *hdr, void **mem)
-{
- struct packet *f;
- int err = 0;
-
- if (!jb || !hdr || !mem)
- return EINVAL;
-
- mtx_lock(jb->lock);
- STAT_INC(n_get);
-
- if (jb->nf <= jb->wish || !jb->packetl.head) {
- DEBUG_INFO("not enough buffer packets - wait.. "
- "(n=%u wish=%u)\n", jb->n, jb->wish);
- STAT_INC(n_underflow);
- plot_jbuf_event(jb, 'U');
- err = ENOENT;
- goto out;
- }
-
- /* When we get one packet P[i], check that the next packet P[i+1]
- is present and have a seq no. of seq[i] + 1.
- If not, we should consider that packet lost. */
-
- f = jb->packetl.head->data;
-
-#if JBUF_STAT
- /* Check sequence of previously played packet */
- if (jb->seq_get) {
- const int16_t seq_diff = f->hdr.seq - jb->seq_get;
- if (seq_less(f->hdr.seq, jb->seq_get)) {
- DEBUG_WARNING("get: seq=%u too late\n", f->hdr.seq);
- }
- else if (seq_diff > 1) {
- STAT_ADD(n_lost, 1);
- plot_jbuf_event(jb, 'T');
- DEBUG_INFO("get: n_lost: diff=%d,seq=%u,seq_get=%u\n",
- seq_diff, f->hdr.seq, jb->seq_get);
- }
- }
-#endif
-
- /* Update sequence number for 'get' */
- jb->seq_get = f->hdr.seq;
-
- *hdr = f->hdr;
- *mem = mem_ref(f->mem);
-
- /* decrease not equal frames */
- if (f->le.next) {
- struct packet *next_f = f->le.next->data;
-
- if (f->hdr.ts != next_f->hdr.ts)
- --jb->nf;
- }
- else {
- --jb->nf;
- }
-
- packet_deref(jb, f);
-
- if (jb->nf > jb->wish) {
- DEBUG_INFO("reducing jitter buffer "
- "(nf=%u min=%u wish=%u max=%u)\n",
- jb->nf, jb->min, jb->wish, jb->max);
- err = EAGAIN;
- }
-
-out:
- mtx_unlock(jb->lock);
- return err;
-}
-
-/**
- * Get one packet from the jitter buffer, even if it becomes depleted
- *
- * @param jb Jitter buffer
- * @param hdr Returned RTP Header
- * @param mem Pointer to memory object storage - referenced on success
- *
- * @return 0 if success, otherwise errorcode
- */
-int jbuf_drain(struct jbuf *jb, struct rtp_header *hdr, void **mem)
-{
- struct packet *f;
- int err = 0;
-
- if (!jb || !hdr || !mem)
- return EINVAL;
-
- mtx_lock(jb->lock);
-
- if (jb->n <= 0 || !jb->packetl.head) {
- err = ENOENT;
- goto out;
- }
-
- /* When we get one packet P[i], check that the next packet P[i+1]
- is present and have a seq no. of seq[i] + 1.
- If not, we should consider that packet lost. */
-
- f = jb->packetl.head->data;
-
- /* Update sequence number for 'get' */
- jb->seq_get = f->hdr.seq;
-
- *hdr = f->hdr;
- *mem = mem_ref(f->mem);
-
- /* decrease not equal frames */
- if (f->le.next) {
- struct packet *next_f = f->le.next->data;
-
- if (f->hdr.ts != next_f->hdr.ts)
- --jb->nf;
- }
- else {
- --jb->nf;
- }
-
- packet_deref(jb, f);
-
-out:
- mtx_unlock(jb->lock);
- return err;
-}
-
-/**
- * Flush all frames in the jitter buffer
- *
- * @param jb Jitter buffer
- */
-void jbuf_flush(struct jbuf *jb)
-{
- struct le *le;
-#if JBUF_STAT
- uint32_t n_flush;
-#endif
-
- if (!jb)
- return;
-
- mtx_lock(jb->lock);
- if (jb->packetl.head) {
- DEBUG_INFO("flush: %u frames\n", jb->n);
- }
-
- /* put all buffered frames back in free list */
- for (le = jb->packetl.head; le; le = jb->packetl.head) {
- DEBUG_INFO(" flush frame: seq=%u\n",
- ((struct packet *)(le->data))->hdr.seq);
-
- packet_deref(jb, le->data);
- }
-
- jb->n = 0;
- jb->nf = 0;
- jb->running = false;
-
- jb->seq_get = 0;
-#if JBUF_STAT
- n_flush = STAT_INC(n_flush);
- memset(&jb->stat, 0, sizeof(jb->stat));
- jb->stat.n_flush = n_flush;
- plot_jbuf_event(jb, 'F');
-#endif
- mtx_unlock(jb->lock);
-}
-
-
-/**
- * Get number of current packets
- *
- * @param jb Jitter buffer
- *
- * @return number of packets
- */
-uint32_t jbuf_packets(const struct jbuf *jb)
-{
- if (!jb)
- return 0;
-
- mtx_lock(jb->lock);
- uint32_t n = jb->n;
- mtx_unlock(jb->lock);
-
- return n;
-}
-
-
-/**
- * Get number of current frames
- *
- * @param jb Jitter buffer
- *
- * @return number of frames
- */
-uint32_t jbuf_frames(const struct jbuf *jb)
-{
- if (!jb)
- return 0;
-
- mtx_lock(jb->lock);
- uint32_t n = jb->nf;
- mtx_unlock(jb->lock);
-
- return n;
-}
-
-
-/**
- * Get jitter buffer statistics
- *
- * @param jb Jitter buffer
- * @param jstat Pointer to statistics storage
- *
- * @return 0 if success, otherwise errorcode
- */
-int jbuf_stats(const struct jbuf *jb, struct jbuf_stat *jstat)
-{
- if (!jb || !jstat)
- return EINVAL;
-
-#if JBUF_STAT
- mtx_lock(jb->lock);
- *jstat = jb->stat;
- mtx_unlock(jb->lock);
-
- return 0;
-#else
- return ENOSYS;
-#endif
-}
-
-
-/**
- * Debug the jitter buffer. This function is thread safe with short blocking
- *
- * @param pf Print handler
- * @param jb Jitter buffer
- *
- * @return 0 if success, otherwise errorcode
- */
-int jbuf_debug(struct re_printf *pf, const struct jbuf *jb)
-{
- int err = 0;
- struct mbuf *mb = mbuf_alloc(512);
-
- if (!jb)
- return 0;
-
- err |= mbuf_printf(mb, "--- jitter buffer debug---\n");
-
- mtx_lock(jb->lock);
- err |= mbuf_printf(mb, " running=%d", jb->running);
- err |= mbuf_printf(mb, " min=%u cur=%u/%u max=%u [frames/packets]\n",
- jb->min, jb->nf, jb->n, jb->max);
- err |= mbuf_printf(mb, " seq_put=%u\n", jb->seq_put);
-
-#if JBUF_STAT
- err |= mbuf_printf(mb, " Stat: put=%u", jb->stat.n_put);
- err |= mbuf_printf(mb, " get=%u", jb->stat.n_get);
- err |= mbuf_printf(mb, " oos=%u", jb->stat.n_oos);
- err |= mbuf_printf(mb, " dup=%u", jb->stat.n_dups);
- err |= mbuf_printf(mb, " late=%u", jb->stat.n_late);
- err |= mbuf_printf(mb, " or=%u", jb->stat.n_overflow);
- err |= mbuf_printf(mb, " ur=%u", jb->stat.n_underflow);
- err |= mbuf_printf(mb, " flush=%u", jb->stat.n_flush);
- err |= mbuf_printf(mb, " put/get_ratio=%u%%", jb->stat.n_get ?
- 100*jb->stat.n_put/jb->stat.n_get : 0);
- err |= mbuf_printf(mb, " lost=%u (%u.%02u%%)\n",
- jb->stat.n_lost,
- jb->stat.n_put ?
- 100*jb->stat.n_lost/jb->stat.n_put : 0,
- jb->stat.n_put ?
- 10000*jb->stat.n_lost/jb->stat.n_put%100 : 0);
-#endif
- mtx_unlock(jb->lock);
-
- if (err)
- goto out;
-
- err = re_hprintf(pf, "%b", mb->buf, mb->pos);
-
-out:
- mem_deref(mb);
- return err;
-}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 3c13531e8..c61cfbb96 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -91,7 +91,6 @@ set(SRCS
http.c
httpauth.c
ice.c
- jbuf.c
json.c
list.c
main.c
diff --git a/test/jbuf.c b/test/jbuf.c
deleted file mode 100644
index e7d3dad12..000000000
--- a/test/jbuf.c
+++ /dev/null
@@ -1,400 +0,0 @@
-/**
- * @file jbuf.c Jitterbuffer Testcode
- *
- * Copyright (C) 2010 Creytiv.com
- */
-#include
-#include
-#include "test.h"
-
-
-#define DEBUG_MODULE "test jbuf"
-#define DEBUG_LEVEL 5
-#include
-
-int test_jbuf(void)
-{
- struct rtp_header hdr, hdr2;
- struct jbuf *jb;
- char *frv[3];
- uint32_t i;
- void *mem = NULL;
- int err;
-
- memset(frv, 0, sizeof(frv));
-
- err = jbuf_alloc(&jb, 0, 10);
- if (err)
- return err;
-
- for (i=0; i min reached, read first frame\n");
- err = jbuf_get(jb, &hdr2, &mem);
- TEST_ERR(err);
- TEST_EQUALS(160, hdr2.seq);
- TEST_EQUALS(mem, frv[0]);
- mem = mem_deref(mem);
-
- DEBUG_INFO("n <= min, leads to ENOENT\n");
- TEST_EQUALS(ENOENT, jbuf_get(jb, &hdr2, &mem));
-
- /* Four frames */
- DEBUG_INFO("test frame: Four frames\n");
- jbuf_flush(jb);
- hdr.seq = 1;
- hdr.ts = 100;
- err = jbuf_put(jb, &hdr, frv[0]);
- TEST_ERR(err);
-
- hdr.seq = 2;
- hdr.ts = 200;
- err = jbuf_put(jb, &hdr, frv[1]);
- TEST_ERR(err);
-
- hdr.seq = 3;
- hdr.ts = 300;
- err = jbuf_put(jb, &hdr, frv[2]);
- TEST_ERR(err);
-
- hdr.seq = 4;
- hdr.ts = 400;
- err = jbuf_put(jb, &hdr, frv[3]);
- TEST_ERR(err);
-
- err = jbuf_get(jb, &hdr2, &mem);
- TEST_EQUALS(EAGAIN, err);
- TEST_EQUALS(1, hdr2.seq);
- TEST_EQUALS(mem, frv[0]);
- mem = mem_deref(mem);
-
- err = jbuf_get(jb, &hdr2, &mem);
- TEST_EQUALS(EAGAIN, err);
- TEST_EQUALS(2, hdr2.seq);
- TEST_EQUALS(mem, frv[1]);
- mem = mem_deref(mem);
-
- err = jbuf_get(jb, &hdr2, &mem);
- TEST_EQUALS(0, err);
- TEST_EQUALS(3, hdr2.seq);
- TEST_EQUALS(mem, frv[2]);
- mem = mem_deref(mem);
-
- err = jbuf_get(jb, &hdr2, &mem);
- TEST_EQUALS(ENOENT, err);
-
- err = 0;
-
- out:
- mem_deref(jb);
- mem_deref(mem);
- for (i=0; i