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