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 /** @file AmJitterBuffer.h */
28 #ifndef _AmJitterBuffer_h_
29 #define _AmJitterBuffer_h_
30 
31 #include "amci/amci.h"
32 #include "AmAudio.h"
33 #include "AmThread.h"
34 #include "SampleArray.h"
35 
36 #define INITIAL_JITTER	    80 * SYSTEM_SAMPLECLOCK_RATE / 1000 // 80 miliseconds
37 #define MAX_JITTER	    2  * SYSTEM_SAMPLECLOCK_RATE // 2 seconds
38 #define RESYNC_THRESHOLD    5 // resync backward if RESYNC_THRESHOLD packets arrive late
39 
40 class Packet {
41   ShortSample m_data[AUDIO_BUFFER_SIZE * 2];
42   unsigned int m_size;
43   unsigned int m_ts;
44  public:
45   Packet *m_next;
46   Packet *m_prev;
47   void init(const ShortSample *data, unsigned int size, unsigned int ts);
48 
size()49   unsigned int size() const { return m_size; }
ts()50   unsigned int ts() const { return m_ts; }
data()51   ShortSample *data() { return m_data; }
52 
53   bool operator < (const Packet&) const;
54 };
55 
56 class PacketAllocator
57 {
58  private:
59   Packet m_packets[MAX_JITTER / 80];
60   Packet *m_free_packets;
61 
62  public:
63   PacketAllocator();
64   Packet *alloc(const ShortSample *data, unsigned int size, unsigned int ts);
65   void free(Packet *p);
66 };
67 
68 class AmJitterBuffer
69 {
70  private:
71   AmMutex m_mutex;
72   PacketAllocator m_allocator;
73   Packet *m_head;
74   Packet *m_tail;
75   bool m_tsInited;
76   unsigned int m_lastTs;
77   unsigned int m_lastResyncTs;
78   unsigned int m_lastAudioTs;
79   unsigned int m_tsDelta;
80   bool m_tsDeltaInited;
81   int m_delayCount;
82   unsigned int m_jitter;
83   //    AmRtpStream *m_owner;
84   bool m_forceResync;
85 
86 #ifdef DEBUG_PLAYOUTBUF
87   unsigned int m_tsDeltaStart;
88 #endif
89 
90  public:
91   AmJitterBuffer();
92   void put(const ShortSample *data, unsigned int size, unsigned int ts, bool begin_talk);
93   bool get(unsigned int ts, unsigned int ms, ShortSample *out, unsigned int *size, unsigned int *out_ts);
94 };
95 
96 #endif // _AmJitterBuffer_h_
97