~ubuntu-branches/ubuntu/vivid/linphone/vivid

« back to all changes in this revision

Viewing changes to speex/libspeex/jitter.c

  • Committer: Bazaar Package Importer
  • Author(s): Samuel Mimram
  • Date: 2006-11-15 10:34:50 UTC
  • mfrom: (1.2.1 upstream) (2.1.8 feisty)
  • Revision ID: james.westby@ubuntu.com-20061115103450-qgafwcks2lkhctlj
* New upstream release.
* Enable video support.
* Fix mismatched #endif in mscommon.h, closes: #398307.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
#ifndef NULL
36
 
#define NULL 0
37
 
#endif
38
 
 
39
 
#include "speex.h"
40
 
#include "speex_bits.h"
41
 
#include "speex_jitter.h"
42
 
 
43
 
void speex_jitter_init(SpeexJitter *jitter, void *decoder, int sampling_rate)
44
 
{
45
 
   int i;
46
 
   for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
47
 
   {
48
 
      jitter->len[i]=-1;
49
 
      jitter->timestamp[i]=-1;
50
 
   }
51
 
 
52
 
   jitter->dec = decoder;
53
 
   speex_decoder_ctl(decoder, SPEEX_GET_FRAME_SIZE, &jitter->frame_size);
54
 
   jitter->frame_time = 1000*jitter->frame_size / sampling_rate;
55
 
 
56
 
   speex_bits_init(&jitter->current_packet);
57
 
   jitter->valid_bits = 0;
58
 
 
59
 
   jitter->buffer_size = 10;
60
 
 
61
 
   jitter->pointer_timestamp = -jitter->frame_time * jitter->buffer_size;
62
 
   
63
 
   jitter->underflow_count = 0;
64
 
   jitter->drop_frame = 0;
65
 
   jitter->interp_frame = 0;
66
 
}
67
 
 
68
 
void speex_jitter_destroy(SpeexJitter *jitter)
69
 
{
70
 
}
71
 
 
72
 
 
73
 
void speex_jitter_put(SpeexJitter *jitter, char *packet, int len, int timestamp)
74
 
{
75
 
   int i,j;
76
 
 
77
 
   /* Cleanup buffer (remove old packets that weren't played) */
78
 
   for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
79
 
   {
80
 
      if (jitter->timestamp[i]<jitter->pointer_timestamp)
81
 
         jitter->len[i]=-1;
82
 
   }
83
 
 
84
 
   /*Find an empty slot in the buffer*/
85
 
   for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
86
 
   {
87
 
      if (jitter->len[i]==-1)
88
 
         break;
89
 
   }
90
 
 
91
 
   if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
92
 
   {
93
 
      /*No place left in the buffer*/
94
 
      
95
 
      /*skip some frame(s) */
96
 
      return;
97
 
   }
98
 
   
99
 
   /* Copy packet in buffer */
100
 
   if (len>SPEEX_JITTER_MAX_PACKET_SIZE)
101
 
      len=SPEEX_JITTER_MAX_PACKET_SIZE;
102
 
   for (j=0;j<len;j++)
103
 
      jitter->buf[i][j]=packet[j];
104
 
   jitter->timestamp[i]=timestamp;
105
 
   jitter->len[i]=len;
106
 
   
107
 
   /* Detect when it's time to drop frames (too much stuff in buffer) */
108
 
   if (timestamp-jitter->pointer_timestamp > (jitter->buffer_size+3)*jitter->frame_time)
109
 
      jitter->drop_frame = 1;
110
 
 
111
 
   /*Detect when it's time to interpolate a frame (not wnough stuff in buffer) */
112
 
   if (timestamp-jitter->pointer_timestamp < (jitter->buffer_size-3)*jitter->frame_time)
113
 
      jitter->underflow_count++;
114
 
   else
115
 
      jitter->underflow_count=0;
116
 
   if (jitter->underflow_count > 10)
117
 
   {
118
 
      jitter->underflow_count=0;
119
 
      jitter->interp_frame = 1;
120
 
   }
121
 
 
122
 
   /* Adjust the buffer size depending on network conditions */
123
 
}
124
 
 
125
 
void speex_jitter_get(SpeexJitter *jitter, short *out)
126
 
{
127
 
   int i;
128
 
   int ret;
129
 
   
130
 
   /* Handle frame interpolation (receiving too fast) */
131
 
   if (jitter->interp_frame)
132
 
   {
133
 
      speex_decode(jitter->dec, NULL, out);
134
 
      jitter->interp_frame = 0;
135
 
      return;
136
 
   }
137
 
 
138
 
   /* Increment timestamp */
139
 
   jitter->pointer_timestamp += jitter->frame_time;
140
 
 
141
 
   /* Handle frame dropping (receiving too fast) */
142
 
   if (jitter->drop_frame)
143
 
   {
144
 
      jitter->pointer_timestamp += jitter->frame_time;
145
 
      jitter->drop_frame = 0;
146
 
   }
147
 
 
148
 
   /* Send zeros while we fill in the buffer */
149
 
   if (jitter->pointer_timestamp<0)
150
 
   {
151
 
      for (i=0;i<jitter->frame_size;i++)
152
 
         out[i]=0;
153
 
      return;
154
 
   }
155
 
   
156
 
   /* Search the buffer for a packet with the right timestamp */
157
 
   for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
158
 
   {
159
 
      if (jitter->len[i]!=-1 && jitter->timestamp[i]==jitter->pointer_timestamp)
160
 
         break;
161
 
   }
162
 
   
163
 
   if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
164
 
   {
165
 
      /* No packet found */
166
 
      if (jitter->valid_bits)
167
 
      {
168
 
         /* Try decoding last received packet */
169
 
         ret = speex_decode(jitter->dec, &jitter->current_packet, out);
170
 
         if (ret == 0)
171
 
            return;
172
 
         else
173
 
            jitter->valid_bits = 0;
174
 
      }
175
 
 
176
 
      /*Packet is late or lost*/
177
 
      speex_decode(jitter->dec, NULL, out);
178
 
   } else {
179
 
      /* Found the right packet */
180
 
      speex_bits_read_from(&jitter->current_packet, jitter->buf[i], jitter->len[i]);
181
 
      jitter->len[i]=-1;
182
 
      /* Decode packet */
183
 
      ret = speex_decode(jitter->dec, &jitter->current_packet, out);
184
 
      if (ret == 0)
185
 
      {
186
 
         jitter->valid_bits = 1;
187
 
      } else {
188
 
         /* Error while decoding */
189
 
         for (i=0;i<jitter->frame_size;i++)
190
 
            out[i]=0;
191
 
      }
192
 
   }
193
 
 
194
 
 
195
 
}
196