1 /* Copyright (C) 2002 Jean-Marc Valin
2    File: speex_jitter.h
3 
4    Adaptive jitter buffer for Speex
5 
6    Redistribution and use in source and binary forms, with or without
7    modification, are permitted provided that the following conditions
8    are met:
9 
10    - Redistributions of source code must retain the above copyright
11    notice, this list of conditions and the following disclaimer.
12 
13    - Redistributions in binary form must reproduce the above copyright
14    notice, this list of conditions and the following disclaimer in the
15    documentation and/or other materials provided with the distribution.
16 
17    - Neither the name of the Xiph.org Foundation nor the names of its
18    contributors may be used to endorse or promote products derived from
19    this software without specific prior written permission.
20 
21    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
25    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 
33 */
34 
35 #ifdef HAVE_CONFIG_H
36 #include "config.h"
37 #endif
38 
39 #ifndef NULL
40 #define NULL 0
41 #endif
42 
43 #include "misc.h"
44 #include "speex.h"
45 #include "speex_bits.h"
46 #include <speex_jitter.h>
47 #include <stdio.h>
48 
49 #define LATE_BINS 4
50 
speex_jitter_init(SpeexJitter * jitter,void * decoder,int sampling_rate)51 void speex_jitter_init(SpeexJitter *jitter, void *decoder, int sampling_rate)
52 {
53    int i;
54    for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
55    {
56       jitter->len[i]=-1;
57       jitter->timestamp[i]=-1;
58    }
59 
60    jitter->dec = decoder;
61    speex_decoder_ctl(decoder, SPEEX_GET_FRAME_SIZE, &jitter->frame_size);
62    jitter->frame_time = jitter->frame_size;
63 
64    speex_bits_init(&jitter->current_packet);
65    jitter->valid_bits = 0;
66 
67    jitter->buffer_size = 4;
68 
69    jitter->pointer_timestamp = -jitter->frame_time * jitter->buffer_size;
70    jitter->reset_state = 1;
71    jitter->lost_count = 0;
72    jitter->loss_rate = 0;
73 }
74 
speex_jitter_destroy(SpeexJitter * jitter)75 void speex_jitter_destroy(SpeexJitter *jitter)
76 {
77    speex_bits_destroy(&jitter->current_packet);
78 }
79 
80 
speex_jitter_put(SpeexJitter * jitter,char * packet,int len,int timestamp)81 void speex_jitter_put(SpeexJitter *jitter, char *packet, int len, int timestamp)
82 {
83    int i,j;
84    int arrival_margin;
85 
86    if (jitter->reset_state)
87    {
88       jitter->reset_state=0;
89       jitter->pointer_timestamp = timestamp-jitter->frame_time * jitter->buffer_size;
90       for (i=0;i<MAX_MARGIN;i++)
91       {
92          jitter->shortterm_margin[i] = 0;
93          jitter->longterm_margin[i] = 0;
94       }
95       for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
96       {
97          jitter->len[i]=-1;
98          jitter->timestamp[i]=-1;
99       }
100       fprintf(stderr, "reset to %d\n", timestamp);
101    }
102 
103    /* Cleanup buffer (remove old packets that weren't played) */
104    for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
105    {
106       if (jitter->timestamp[i]<jitter->pointer_timestamp)
107       {
108          jitter->len[i]=-1;
109          /*if (jitter->timestamp[i] != -1)
110             fprintf (stderr, "discarding %d %d\n", jitter->timestamp[i], jitter->pointer_timestamp);*/
111       }
112    }
113 
114    /*Find an empty slot in the buffer*/
115    for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
116    {
117       if (jitter->len[i]==-1)
118          break;
119    }
120 
121    /*fprintf(stderr, "%d %d %f\n", timestamp, jitter->pointer_timestamp, jitter->drift_average);*/
122    if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
123    {
124       int earliest=jitter->timestamp[0];
125       i=0;
126       for (j=1;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++)
127       {
128          if (jitter->timestamp[j]<earliest)
129          {
130             earliest = jitter->timestamp[j];
131             i=j;
132          }
133       }
134       /*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp);*/
135       /*No place left in the buffer*/
136 
137       /*skip some frame(s) */
138       /*return;*/
139    }
140 
141    /* Copy packet in buffer */
142    if (len>SPEEX_JITTER_MAX_PACKET_SIZE)
143       len=SPEEX_JITTER_MAX_PACKET_SIZE;
144    for (j=0;j<len/BYTES_PER_CHAR;j++)
145       jitter->buf[i][j]=packet[j];
146    jitter->timestamp[i]=timestamp;
147    jitter->len[i]=len;
148 
149    /* Don't count late packets when adjusting the synchro (we're taking care of them elsewhere) */
150    /*if (timestamp <= jitter->pointer_timestamp)
151    {
152       fprintf (stderr, "frame for timestamp %d arrived too late (at time %d)\n", timestamp, jitter->pointer_timestamp);
153    }*/
154 
155    /* Adjust the buffer size depending on network conditions */
156    arrival_margin = (timestamp - jitter->pointer_timestamp - jitter->frame_time);
157 
158    if (arrival_margin >= -LATE_BINS*jitter->frame_time)
159    {
160       int int_margin;
161       for (i=0;i<MAX_MARGIN;i++)
162       {
163          jitter->shortterm_margin[i] *= .98;
164          jitter->longterm_margin[i] *= .995;
165       }
166       int_margin = (arrival_margin + LATE_BINS*jitter->frame_time)/jitter->frame_time;
167       if (int_margin>MAX_MARGIN-1)
168          int_margin = MAX_MARGIN-1;
169       if (int_margin>=0)
170       {
171          jitter->shortterm_margin[int_margin] += .02;
172          jitter->longterm_margin[int_margin] += .005;
173       }
174    }
175 
176    /*fprintf (stderr, "margin : %d %d %f %f %f %f\n", arrival_margin, jitter->buffer_size, 100*jitter->loss_rate, 100*jitter->late_ratio, 100*jitter->ontime_ratio, 100*jitter->early_ratio);*/
177 }
178 
speex_jitter_get(SpeexJitter * jitter,short * out,int * current_timestamp)179 void speex_jitter_get(SpeexJitter *jitter, short *out, int *current_timestamp)
180 {
181    int i;
182    int ret;
183    float late_ratio_short;
184    float late_ratio_long;
185    float ontime_ratio_short;
186    float ontime_ratio_long;
187    float early_ratio_short;
188    float early_ratio_long;
189 
190    late_ratio_short = 0;
191    late_ratio_long = 0;
192    for (i=0;i<LATE_BINS;i++)
193    {
194       late_ratio_short += jitter->shortterm_margin[i];
195       late_ratio_long += jitter->longterm_margin[i];
196    }
197    ontime_ratio_short = jitter->shortterm_margin[LATE_BINS];
198    ontime_ratio_long = jitter->longterm_margin[LATE_BINS];
199    early_ratio_short = early_ratio_long = 0;
200    for (i=LATE_BINS+1;i<MAX_MARGIN;i++)
201    {
202       early_ratio_short += jitter->shortterm_margin[i];
203       early_ratio_long += jitter->longterm_margin[i];
204    }
205    if (0&&jitter->pointer_timestamp%1000==0)
206    {
207       fprintf (stderr, "%f %f %f %f %f %f\n", early_ratio_short, early_ratio_long, ontime_ratio_short, ontime_ratio_long, late_ratio_short, late_ratio_long);
208       /*fprintf (stderr, "%f %f\n", early_ratio_short + ontime_ratio_short + late_ratio_short, early_ratio_long + ontime_ratio_long + late_ratio_long);*/
209    }
210 
211    if (late_ratio_short > .1 || late_ratio_long > .03)
212    {
213       jitter->shortterm_margin[MAX_MARGIN-1] += jitter->shortterm_margin[MAX_MARGIN-2];
214       jitter->longterm_margin[MAX_MARGIN-1] += jitter->longterm_margin[MAX_MARGIN-2];
215       for (i=MAX_MARGIN-2;i>=0;i--)
216       {
217          jitter->shortterm_margin[i+1] = jitter->shortterm_margin[i];
218          jitter->longterm_margin[i+1] = jitter->longterm_margin[i];
219       }
220       jitter->shortterm_margin[0] = 0;
221       jitter->longterm_margin[0] = 0;
222       /*fprintf (stderr, "interpolate frame\n");*/
223       speex_decode_int(jitter->dec, NULL, out);
224       if (current_timestamp)
225          *current_timestamp = jitter->pointer_timestamp;
226       return;
227    }
228 
229    /* Increment timestamp */
230    jitter->pointer_timestamp += jitter->frame_time;
231 
232    if (late_ratio_short + ontime_ratio_short < .005 && late_ratio_long + ontime_ratio_long < .01 && early_ratio_short > .8)
233    {
234       jitter->shortterm_margin[0] += jitter->shortterm_margin[1];
235       jitter->longterm_margin[0] += jitter->longterm_margin[1];
236       for (i=1;i<MAX_MARGIN-1;i++)
237       {
238          jitter->shortterm_margin[i] = jitter->shortterm_margin[i+1];
239          jitter->longterm_margin[i] = jitter->longterm_margin[i+1];
240       }
241       jitter->shortterm_margin[MAX_MARGIN-1] = 0;
242       jitter->longterm_margin[MAX_MARGIN-1] = 0;
243       /*fprintf (stderr, "drop frame\n");*/
244       jitter->pointer_timestamp += jitter->frame_time;
245    }
246 
247    if (current_timestamp)
248       *current_timestamp = jitter->pointer_timestamp;
249 
250    /* Send zeros while we fill in the buffer */
251    if (jitter->pointer_timestamp<0)
252    {
253       for (i=0;i<jitter->frame_size;i++)
254          out[i]=0;
255       return;
256    }
257 
258    /* Search the buffer for a packet with the right timestamp */
259    for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
260    {
261       if (jitter->len[i]!=-1 && jitter->timestamp[i]==jitter->pointer_timestamp)
262          break;
263    }
264 
265    if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
266    {
267       /* No packet found */
268       if (jitter->valid_bits)
269       {
270          /* Try decoding last received packet */
271          ret = speex_decode_int(jitter->dec, &jitter->current_packet, out);
272          if (ret == 0)
273          {
274             jitter->lost_count = 0;
275             return;
276          } else {
277             jitter->valid_bits = 0;
278          }
279       }
280 
281       /*fprintf (stderr, "lost/late frame %d\n", jitter->pointer_timestamp);*/
282       /*Packet is late or lost*/
283       speex_decode_int(jitter->dec, NULL, out);
284       jitter->lost_count++;
285       if (jitter->lost_count>=25)
286       {
287          jitter->lost_count = 0;
288          jitter->reset_state = 1;
289          speex_decoder_ctl(jitter->dec, SPEEX_RESET_STATE, NULL);
290       }
291       jitter->loss_rate = .999*jitter->loss_rate + .001;
292    } else {
293       jitter->lost_count = 0;
294       /* Found the right packet */
295       speex_bits_read_from(&jitter->current_packet, jitter->buf[i], jitter->len[i]);
296       jitter->len[i]=-1;
297       /* Decode packet */
298       ret = speex_decode_int(jitter->dec, &jitter->current_packet, out);
299       if (ret == 0)
300       {
301          jitter->valid_bits = 1;
302       } else {
303          /* Error while decoding */
304          for (i=0;i<jitter->frame_size;i++)
305             out[i]=0;
306       }
307       jitter->loss_rate = .999*jitter->loss_rate;
308    }
309 
310 
311 }
312 
speex_jitter_get_pointer_timestamp(SpeexJitter * jitter)313 int speex_jitter_get_pointer_timestamp(SpeexJitter *jitter)
314 {
315    return jitter->pointer_timestamp;
316 }
317