1 /*
2 * Copyright (C) 2006 Sippy Software, Inc.
3 *
4 * This file is part of SEMS, a free SIP media server.
5 *
6 * SEMS is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version. This program is released under
10 * the GPL with the additional exemption that compiling, linking,
11 * and/or using OpenSSL is allowed.
12 *
13 * For a license to use the SEMS software under conditions
14 * other than those described here, or to purchase support for this
15 * software, please contact iptel.org by e-mail at the following addresses:
16 * info@iptel.org
17 *
18 * SEMS is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 */
27
28 #include "AmAudio.h"
29 #include "AmJitterBuffer.h"
30 #include "log.h"
31 #include "SampleArray.h"
32
33 //
34 // Warning:
35 // This jitter buffer seems to increase the buffer size, if jitter (delay variation) is
36 // present in the stream, or for example a temporary delay spike is detected,
37 // but it does not adapt the buffer to shrink again if the situation has improved.
38 // The adaptive playout buffer method usually shows much better results
39 // in minimizing the total playout delay (using more processing power though).
40 //
41
operator <(const Packet & p) const42 bool Packet::operator < (const Packet& p) const
43 {
44 return ts_less()(m_ts, p.m_ts);
45 }
46
init(const ShortSample * data,unsigned int size,unsigned int ts)47 void Packet::init(const ShortSample *data, unsigned int size, unsigned int ts)
48 {
49 size = PCM16_S2B(size);
50 if (size > sizeof(m_data))
51 size = sizeof(m_data);
52 m_size = PCM16_B2S(size);
53 memcpy(m_data, data, size);
54 m_ts = ts;
55 }
56
PacketAllocator()57 PacketAllocator::PacketAllocator()
58 {
59 m_free_packets = m_packets;
60 for (int i = 1; i < MAX_JITTER / 80; ++i) {
61 m_packets[i - 1].m_next = &m_packets[i];
62 }
63 m_packets[MAX_JITTER / 80 - 1].m_next = NULL;
64 }
65
alloc(const ShortSample * data,unsigned int size,unsigned int ts)66 Packet *PacketAllocator::alloc(const ShortSample *data, unsigned int size, unsigned int ts)
67 {
68 if (m_free_packets == NULL)
69 return NULL;
70 Packet *retval = m_free_packets;
71 m_free_packets = retval->m_next;
72
73 retval->init(data, size, ts);
74
75 retval->m_next = retval->m_prev = NULL;
76 return retval;
77 }
78
free(Packet * p)79 void PacketAllocator::free(Packet *p)
80 {
81 p->m_prev = NULL;
82 p->m_next = m_free_packets;
83 m_free_packets = p;
84 }
85
AmJitterBuffer()86 AmJitterBuffer::AmJitterBuffer()
87 : m_head(NULL), m_tail(NULL), m_tsInited(false), m_lastTs(0),
88 m_lastResyncTs(0),m_lastAudioTs(0),m_tsDelta(0),m_tsDeltaInited(false),
89 m_delayCount(0), m_jitter(INITIAL_JITTER), m_forceResync(false)
90 {
91 }
92
put(const ShortSample * data,unsigned int size,unsigned int ts,bool begin_talk)93 void AmJitterBuffer::put(const ShortSample *data, unsigned int size, unsigned int ts, bool begin_talk)
94 {
95 m_mutex.lock();
96 if (begin_talk)
97 m_forceResync = true;
98 if (m_tsInited && !m_forceResync && ts_less()(m_lastTs + m_jitter, ts))
99 {
100 unsigned int delay = ts - m_lastTs;
101 if (delay > m_jitter && m_jitter < MAX_JITTER)
102 {
103 m_jitter += (delay - m_jitter) / 2;
104 if (m_jitter > MAX_JITTER)
105 m_jitter = MAX_JITTER;
106 #ifdef DEBUG_PLAYOUTBUF
107 DBG("Jitter buffer delay increased to %u\n", m_jitter);
108 #endif
109 }
110 // Packet arrived too late to be put into buffer
111 if (ts_less()(ts + m_jitter, m_lastTs)) {
112 m_mutex.unlock();
113 return;
114 }
115 }
116 Packet *elem = m_allocator.alloc(data, size, ts);
117 if (elem == NULL) {
118 elem = m_head;
119 m_head = m_head->m_next;
120 m_head->m_prev = NULL;
121 elem->init(data, size, ts);
122 }
123 if (m_tail == NULL)
124 {
125 m_tail = m_head = elem;
126 elem->m_next = elem->m_prev = NULL;
127 }
128 else {
129 if (*m_tail < *elem) // elem is later than tail - put it in tail
130 {
131 m_tail->m_next = elem;
132 elem->m_prev = m_tail;
133 m_tail = elem;
134 elem->m_next = NULL;
135 }
136 else { // elem is out of order - place it properly
137 Packet *i;
138 for (i = m_tail; i->m_prev && *elem < *(i->m_prev); i = i->m_prev);
139 elem->m_prev = i->m_prev;
140 if (i->m_prev)
141 i->m_prev->m_next = elem;
142 else
143 m_head = elem;
144 i->m_prev = elem;
145 elem->m_next = i;
146 }
147 }
148 if (!m_tsInited) {
149 m_lastTs = ts;
150 m_tsInited = true;
151 }
152 else if (ts_less()(m_lastTs, ts) || m_forceResync) {
153 m_lastTs = ts;
154 }
155
156 m_mutex.unlock();
157 }
158
159 /**
160 * This method will return from zero to several packets.
161 * To get all the packets for the single ts the caller must call this
162 * method with the same ts till the return value will become false.
163 */
get(unsigned int ts,unsigned int ms,ShortSample * out_buf,unsigned int * out_size,unsigned int * out_ts)164 bool AmJitterBuffer::get(unsigned int ts, unsigned int ms, ShortSample *out_buf,
165 unsigned int *out_size, unsigned int *out_ts)
166 {
167 bool retval = true;
168
169 m_mutex.lock();
170 if (!m_tsInited) {
171 m_mutex.unlock();
172 return false;
173 }
174 if (!m_tsDeltaInited || m_forceResync) {
175 m_tsDelta = m_lastTs - ts + ms;
176 m_tsDeltaInited = true;
177 m_lastAudioTs = ts;
178 m_forceResync = false;
179 #ifdef DEBUG_PLAYOUTBUF
180 DBG("Jitter buffer: initialized tsDelta with %u\n", m_tsDelta);
181 m_tsDeltaStart = m_tsDelta;
182 #endif
183 }
184 else if (m_lastAudioTs != ts && m_lastResyncTs != m_lastTs) {
185 if (ts_less()(ts + m_tsDelta, m_lastTs)) {
186 /*
187 * New packet arrived earlier than expected -
188 * immediate resync required
189 */
190 m_tsDelta += m_lastTs - ts + ms;
191 #ifdef DEBUG_PLAYOUTBUF
192 DBG("Jitter buffer resynced forward (-> %d rel)\n",
193 m_tsDelta - m_tsDeltaStart);
194 #endif
195 m_delayCount = 0;
196 } else if (ts_less()(m_lastTs, ts + m_tsDelta - m_jitter / 2)) {
197 /* New packet hasn't arrived yet */
198 if (m_delayCount > RESYNC_THRESHOLD) {
199 unsigned int d = m_tsDelta -(m_lastTs - ts + ms);
200 m_tsDelta -= d / 2;
201 #ifdef DEBUG_PLAYOUTBUF
202 DBG("Jitter buffer resynced backward (-> %d rel)\n",
203 m_tsDelta - m_tsDeltaStart);
204 #endif
205 }
206 else
207 ++m_delayCount;
208 }
209 else {
210 /* New packet arrived at proper time */
211 m_delayCount = 0;
212 }
213 m_lastResyncTs = m_lastTs;
214 }
215 m_lastAudioTs = ts;
216 unsigned int get_ts = ts + m_tsDelta - m_jitter;
217 // DBG("Getting pkt at %u, res ts = %u\n", get_ts / m_frameSize, p.timestamp);
218 // First of all throw away all too old packets from the head
219 Packet *tmp;
220 for (tmp = m_head; tmp && ts_less()(tmp->ts() + tmp->size(), get_ts); )
221 {
222 m_head = tmp->m_next;
223 if (m_head == NULL)
224 m_tail = NULL;
225 else
226 m_head->m_prev = NULL;
227 m_allocator.free(tmp);
228 tmp = m_head;
229 }
230 // Get the packet from the head
231 if (m_head && ts_less()(m_head->ts(), get_ts + ms))
232 {
233 tmp = m_head;
234 m_head = tmp->m_next;
235 if (m_head == NULL)
236 m_tail = NULL;
237 else
238 m_head->m_prev = NULL;
239 memcpy(out_buf, tmp->data(), PCM16_S2B(tmp->size()));
240 // Map RTP timestamp to internal audio timestamp
241 *out_ts = tmp->ts() - m_tsDelta + m_jitter;
242 *out_size = tmp->size();
243 m_allocator.free(tmp);
244 }
245 else
246 retval = false;
247
248 m_mutex.unlock();
249 return retval;
250 }
251