diff options
Diffstat (limited to 'lib/rbcodec/codecs/libspeex/jitter.c')
-rw-r--r-- | lib/rbcodec/codecs/libspeex/jitter.c | 192 |
1 files changed, 97 insertions, 95 deletions
diff --git a/lib/rbcodec/codecs/libspeex/jitter.c b/lib/rbcodec/codecs/libspeex/jitter.c index d9f6c67b86..f4e3bc2be1 100644 --- a/lib/rbcodec/codecs/libspeex/jitter.c +++ b/lib/rbcodec/codecs/libspeex/jitter.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* Copyright (C) 2002 Jean-Marc Valin | 1 | /* Copyright (C) 2002 Jean-Marc Valin |
2 | File: speex_jitter.h | 2 | File: speex_jitter.h |
3 | 3 | ||
4 | Adaptive jitter buffer for Speex | 4 | Adaptive jitter buffer for Speex |
@@ -6,18 +6,18 @@ | |||
6 | Redistribution and use in source and binary forms, with or without | 6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions | 7 | modification, are permitted provided that the following conditions |
8 | are met: | 8 | are met: |
9 | 9 | ||
10 | - Redistributions of source code must retain the above copyright | 10 | - Redistributions of source code must retain the above copyright |
11 | notice, this list of conditions and the following disclaimer. | 11 | notice, this list of conditions and the following disclaimer. |
12 | 12 | ||
13 | - Redistributions in binary form must reproduce the above copyright | 13 | - Redistributions in binary form must reproduce the above copyright |
14 | notice, this list of conditions and the following disclaimer in the | 14 | notice, this list of conditions and the following disclaimer in the |
15 | documentation and/or other materials provided with the distribution. | 15 | documentation and/or other materials provided with the distribution. |
16 | 16 | ||
17 | - Neither the name of the Xiph.org Foundation nor the names of its | 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 | 18 | contributors may be used to endorse or promote products derived from |
19 | this software without specific prior written permission. | 19 | this software without specific prior written permission. |
20 | 20 | ||
21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
22 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 22 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
23 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 23 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
@@ -73,17 +73,17 @@ TODO: | |||
73 | #define LT32(a,b) (((spx_int32_t)((a)-(b)))<0) | 73 | #define LT32(a,b) (((spx_int32_t)((a)-(b)))<0) |
74 | #define LE32(a,b) (((spx_int32_t)((a)-(b)))<=0) | 74 | #define LE32(a,b) (((spx_int32_t)((a)-(b)))<=0) |
75 | 75 | ||
76 | #define ROUND_DOWN(x, step) ((x)<0 ? ((x)-(step)+1)/(step)*(step) : (x)/(step)*(step)) | 76 | #define ROUND_DOWN(x, step) ((x)<0 ? ((x)-(step)+1)/(step)*(step) : (x)/(step)*(step)) |
77 | 77 | ||
78 | #define MAX_TIMINGS 20 | 78 | #define MAX_TIMINGS 40 |
79 | #define MAX_BUFFERS 3 | 79 | #define MAX_BUFFERS 3 |
80 | #define TOP_DELAY 20 | 80 | #define TOP_DELAY 40 |
81 | 81 | ||
82 | /** Buffer that keeps the time of arrival of the latest packets */ | 82 | /** Buffer that keeps the time of arrival of the latest packets */ |
83 | struct TimingBuffer { | 83 | struct TimingBuffer { |
84 | int filled; /**< Number of entries occupied in "timing" and "counts"*/ | 84 | int filled; /**< Number of entries occupied in "timing" and "counts"*/ |
85 | int curr_count; /**< Number of packet timings we got (including those we discarded) */ | 85 | int curr_count; /**< Number of packet timings we got (including those we discarded) */ |
86 | spx_int16_t timing[MAX_TIMINGS]; /**< Sorted list of all timings ("latest" packets first) */ | 86 | spx_int32_t timing[MAX_TIMINGS]; /**< Sorted list of all timings ("latest" packets first) */ |
87 | spx_int16_t counts[MAX_TIMINGS]; /**< Order the packets were put in (will be used for short-term estimate) */ | 87 | spx_int16_t counts[MAX_TIMINGS]; /**< Order the packets were put in (will be used for short-term estimate) */ |
88 | }; | 88 | }; |
89 | 89 | ||
@@ -103,7 +103,7 @@ static void tb_add(struct TimingBuffer *tb, spx_int16_t timing) | |||
103 | tb->curr_count++; | 103 | tb->curr_count++; |
104 | return; | 104 | return; |
105 | } | 105 | } |
106 | 106 | ||
107 | /* Find where the timing info goes in the sorted list */ | 107 | /* Find where the timing info goes in the sorted list */ |
108 | pos = 0; | 108 | pos = 0; |
109 | /* FIXME: Do bisection instead of linear search */ | 109 | /* FIXME: Do bisection instead of linear search */ |
@@ -111,9 +111,9 @@ static void tb_add(struct TimingBuffer *tb, spx_int16_t timing) | |||
111 | { | 111 | { |
112 | pos++; | 112 | pos++; |
113 | } | 113 | } |
114 | 114 | ||
115 | speex_assert(pos <= tb->filled && pos < MAX_TIMINGS); | 115 | speex_assert(pos <= tb->filled && pos < MAX_TIMINGS); |
116 | 116 | ||
117 | /* Shift everything so we can perform the insertion */ | 117 | /* Shift everything so we can perform the insertion */ |
118 | if (pos < tb->filled) | 118 | if (pos < tb->filled) |
119 | { | 119 | { |
@@ -126,7 +126,7 @@ static void tb_add(struct TimingBuffer *tb, spx_int16_t timing) | |||
126 | /* Insert */ | 126 | /* Insert */ |
127 | tb->timing[pos] = timing; | 127 | tb->timing[pos] = timing; |
128 | tb->counts[pos] = tb->curr_count; | 128 | tb->counts[pos] = tb->curr_count; |
129 | 129 | ||
130 | tb->curr_count++; | 130 | tb->curr_count++; |
131 | if (tb->filled<MAX_TIMINGS) | 131 | if (tb->filled<MAX_TIMINGS) |
132 | tb->filled++; | 132 | tb->filled++; |
@@ -139,12 +139,12 @@ struct JitterBuffer_ { | |||
139 | spx_uint32_t pointer_timestamp; /**< Timestamp of what we will *get* next */ | 139 | spx_uint32_t pointer_timestamp; /**< Timestamp of what we will *get* next */ |
140 | spx_uint32_t last_returned_timestamp; /**< Useful for getting the next packet with the same timestamp (for fragmented media) */ | 140 | spx_uint32_t last_returned_timestamp; /**< Useful for getting the next packet with the same timestamp (for fragmented media) */ |
141 | spx_uint32_t next_stop; /**< Estimated time the next get() will be called */ | 141 | spx_uint32_t next_stop; /**< Estimated time the next get() will be called */ |
142 | 142 | ||
143 | spx_int32_t buffered; /**< Amount of data we think is still buffered by the application (timestamp units)*/ | 143 | spx_int32_t buffered; /**< Amount of data we think is still buffered by the application (timestamp units)*/ |
144 | 144 | ||
145 | JitterBufferPacket packets[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packets stored in the buffer */ | 145 | JitterBufferPacket packets[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packets stored in the buffer */ |
146 | spx_uint32_t arrival[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packet arrival time (0 means it was late, even though it's a valid timestamp) */ | 146 | spx_uint32_t arrival[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packet arrival time (0 means it was late, even though it's a valid timestamp) */ |
147 | 147 | ||
148 | void (*destroy) (void *); /**< Callback for destroying a packet */ | 148 | void (*destroy) (void *); /**< Callback for destroying a packet */ |
149 | 149 | ||
150 | spx_int32_t delay_step; /**< Size of the steps when adjusting buffering (timestamp units) */ | 150 | spx_int32_t delay_step; /**< Size of the steps when adjusting buffering (timestamp units) */ |
@@ -154,7 +154,7 @@ struct JitterBuffer_ { | |||
154 | int late_cutoff; /**< How late must a packet be for it not to be considered at all */ | 154 | int late_cutoff; /**< How late must a packet be for it not to be considered at all */ |
155 | int interp_requested; /**< An interpolation is requested by speex_jitter_update_delay() */ | 155 | int interp_requested; /**< An interpolation is requested by speex_jitter_update_delay() */ |
156 | int auto_adjust; /**< Whether to automatically adjust the delay at any time */ | 156 | int auto_adjust; /**< Whether to automatically adjust the delay at any time */ |
157 | 157 | ||
158 | struct TimingBuffer _tb[MAX_BUFFERS]; /**< Don't use those directly */ | 158 | struct TimingBuffer _tb[MAX_BUFFERS]; /**< Don't use those directly */ |
159 | struct TimingBuffer *timeBuffers[MAX_BUFFERS]; /**< Storing arrival time of latest frames so we can compute some stats */ | 159 | struct TimingBuffer *timeBuffers[MAX_BUFFERS]; /**< Storing arrival time of latest frames so we can compute some stats */ |
160 | int window_size; /**< Total window over which the late frames are counted */ | 160 | int window_size; /**< Total window over which the late frames are counted */ |
@@ -162,15 +162,15 @@ struct JitterBuffer_ { | |||
162 | int max_late_rate; /**< Absolute maximum amount of late packets tolerable (in percent) */ | 162 | int max_late_rate; /**< Absolute maximum amount of late packets tolerable (in percent) */ |
163 | int latency_tradeoff; /**< Latency equivalent of losing one percent of packets */ | 163 | int latency_tradeoff; /**< Latency equivalent of losing one percent of packets */ |
164 | int auto_tradeoff; /**< Latency equivalent of losing one percent of packets (automatic default) */ | 164 | int auto_tradeoff; /**< Latency equivalent of losing one percent of packets (automatic default) */ |
165 | 165 | ||
166 | int lost_count; /**< Number of consecutive lost packets */ | 166 | int lost_count; /**< Number of consecutive lost packets */ |
167 | }; | 167 | }; |
168 | 168 | ||
169 | /** Based on available data, this computes the optimal delay for the jitter buffer. | 169 | /** Based on available data, this computes the optimal delay for the jitter buffer. |
170 | The optimised function is in timestamp units and is: | 170 | The optimised function is in timestamp units and is: |
171 | cost = delay + late_factor*[number of frames that would be late if we used that delay] | 171 | cost = delay + late_factor*[number of frames that would be late if we used that delay] |
172 | @param tb Array of buffers | 172 | @param tb Array of buffers |
173 | @param late_factor Equivalent cost of a late frame (in timestamp units) | 173 | @param late_factor Equivalent cost of a late frame (in timestamp units) |
174 | */ | 174 | */ |
175 | static spx_int16_t compute_opt_delay(JitterBuffer *jitter) | 175 | static spx_int16_t compute_opt_delay(JitterBuffer *jitter) |
176 | { | 176 | { |
@@ -186,27 +186,27 @@ static spx_int16_t compute_opt_delay(JitterBuffer *jitter) | |||
186 | int worst = 0; | 186 | int worst = 0; |
187 | spx_int32_t deltaT; | 187 | spx_int32_t deltaT; |
188 | struct TimingBuffer *tb; | 188 | struct TimingBuffer *tb; |
189 | 189 | ||
190 | tb = jitter->_tb; | 190 | tb = jitter->_tb; |
191 | 191 | ||
192 | /* Number of packet timings we have received (including those we didn't keep) */ | 192 | /* Number of packet timings we have received (including those we didn't keep) */ |
193 | tot_count = 0; | 193 | tot_count = 0; |
194 | for (i=0;i<MAX_BUFFERS;i++) | 194 | for (i=0;i<MAX_BUFFERS;i++) |
195 | tot_count += tb[i].curr_count; | 195 | tot_count += tb[i].curr_count; |
196 | if (tot_count==0) | 196 | if (tot_count==0) |
197 | return 0; | 197 | return 0; |
198 | 198 | ||
199 | /* Compute cost for one lost packet */ | 199 | /* Compute cost for one lost packet */ |
200 | if (jitter->latency_tradeoff != 0) | 200 | if (jitter->latency_tradeoff != 0) |
201 | late_factor = jitter->latency_tradeoff * 100.0f / tot_count; | 201 | late_factor = jitter->latency_tradeoff * 100.0f / tot_count; |
202 | else | 202 | else |
203 | late_factor = jitter->auto_tradeoff * jitter->window_size/tot_count; | 203 | late_factor = jitter->auto_tradeoff * jitter->window_size/tot_count; |
204 | 204 | ||
205 | /*fprintf(stderr, "late_factor = %f\n", late_factor);*/ | 205 | /*fprintf(stderr, "late_factor = %f\n", late_factor);*/ |
206 | for (i=0;i<MAX_BUFFERS;i++) | 206 | for (i=0;i<MAX_BUFFERS;i++) |
207 | pos[i] = 0; | 207 | pos[i] = 0; |
208 | 208 | ||
209 | /* Pick the TOP_DELAY "latest" packets (doesn't need to actually be late | 209 | /* Pick the TOP_DELAY "latest" packets (doesn't need to actually be late |
210 | for the current settings) */ | 210 | for the current settings) */ |
211 | for (i=0;i<TOP_DELAY;i++) | 211 | for (i=0;i<TOP_DELAY;i++) |
212 | { | 212 | { |
@@ -225,13 +225,13 @@ static spx_int16_t compute_opt_delay(JitterBuffer *jitter) | |||
225 | if (next != -1) | 225 | if (next != -1) |
226 | { | 226 | { |
227 | spx_int32_t cost; | 227 | spx_int32_t cost; |
228 | 228 | ||
229 | if (i==0) | 229 | if (i==0) |
230 | worst = latest; | 230 | worst = latest; |
231 | best = latest; | 231 | best = latest; |
232 | latest = ROUND_DOWN(latest, jitter->delay_step); | 232 | latest = ROUND_DOWN(latest, jitter->delay_step); |
233 | pos[next]++; | 233 | pos[next]++; |
234 | 234 | ||
235 | /* Actual cost function that tells us how bad using this delay would be */ | 235 | /* Actual cost function that tells us how bad using this delay would be */ |
236 | cost = -latest + late_factor*late; | 236 | cost = -latest + late_factor*late; |
237 | /*fprintf(stderr, "cost %d = %d + %f * %d\n", cost, -latest, late_factor, late);*/ | 237 | /*fprintf(stderr, "cost %d = %d + %f * %d\n", cost, -latest, late_factor, late);*/ |
@@ -243,24 +243,24 @@ static spx_int16_t compute_opt_delay(JitterBuffer *jitter) | |||
243 | } else { | 243 | } else { |
244 | break; | 244 | break; |
245 | } | 245 | } |
246 | 246 | ||
247 | /* For the next timing we will consider, there will be one more late packet to count */ | 247 | /* For the next timing we will consider, there will be one more late packet to count */ |
248 | late++; | 248 | late++; |
249 | /* Two-frame penalty if we're going to increase the amount of late frames (hysteresis) */ | 249 | /* Two-frame penalty if we're going to increase the amount of late frames (hysteresis) */ |
250 | if (latest >= 0 && !penalty_taken) | 250 | if (latest >= 0 && !penalty_taken) |
251 | { | 251 | { |
252 | penalty_taken = 1; | 252 | penalty_taken = 1; |
253 | late+=2; | 253 | late+=4; |
254 | } | 254 | } |
255 | } | 255 | } |
256 | 256 | ||
257 | deltaT = best-worst; | 257 | deltaT = best-worst; |
258 | /* This is a default "automatic latency tradeoff" when none is provided */ | 258 | /* This is a default "automatic latency tradeoff" when none is provided */ |
259 | jitter->auto_tradeoff = 1 + deltaT/TOP_DELAY; | 259 | jitter->auto_tradeoff = 1 + deltaT/TOP_DELAY; |
260 | /*fprintf(stderr, "auto_tradeoff = %d (%d %d %d)\n", jitter->auto_tradeoff, best, worst, i);*/ | 260 | /*fprintf(stderr, "auto_tradeoff = %d (%d %d %d)\n", jitter->auto_tradeoff, best, worst, i);*/ |
261 | 261 | ||
262 | /* FIXME: Compute a short-term estimate too and combine with the long-term one */ | 262 | /* FIXME: Compute a short-term estimate too and combine with the long-term one */ |
263 | 263 | ||
264 | /* Prevents reducing the buffer size when we haven't really had much data */ | 264 | /* Prevents reducing the buffer size when we haven't really had much data */ |
265 | if (tot_count < TOP_DELAY && opt > 0) | 265 | if (tot_count < TOP_DELAY && opt > 0) |
266 | return 0; | 266 | return 0; |
@@ -269,7 +269,7 @@ static spx_int16_t compute_opt_delay(JitterBuffer *jitter) | |||
269 | 269 | ||
270 | 270 | ||
271 | /** Initialise jitter buffer */ | 271 | /** Initialise jitter buffer */ |
272 | JitterBuffer *jitter_buffer_init(int step_size) | 272 | EXPORT JitterBuffer *jitter_buffer_init(int step_size) |
273 | { | 273 | { |
274 | JitterBuffer *jitter = (JitterBuffer*)speex_alloc(sizeof(JitterBuffer)); | 274 | JitterBuffer *jitter = (JitterBuffer*)speex_alloc(sizeof(JitterBuffer)); |
275 | if (jitter) | 275 | if (jitter) |
@@ -294,7 +294,7 @@ JitterBuffer *jitter_buffer_init(int step_size) | |||
294 | } | 294 | } |
295 | 295 | ||
296 | /** Reset jitter buffer */ | 296 | /** Reset jitter buffer */ |
297 | void jitter_buffer_reset(JitterBuffer *jitter) | 297 | EXPORT void jitter_buffer_reset(JitterBuffer *jitter) |
298 | { | 298 | { |
299 | int i; | 299 | int i; |
300 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | 300 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
@@ -315,7 +315,7 @@ void jitter_buffer_reset(JitterBuffer *jitter) | |||
315 | jitter->lost_count = 0; | 315 | jitter->lost_count = 0; |
316 | jitter->buffered = 0; | 316 | jitter->buffered = 0; |
317 | jitter->auto_tradeoff = 32000; | 317 | jitter->auto_tradeoff = 32000; |
318 | 318 | ||
319 | for (i=0;i<MAX_BUFFERS;i++) | 319 | for (i=0;i<MAX_BUFFERS;i++) |
320 | { | 320 | { |
321 | tb_init(&jitter->_tb[i]); | 321 | tb_init(&jitter->_tb[i]); |
@@ -325,7 +325,7 @@ void jitter_buffer_reset(JitterBuffer *jitter) | |||
325 | } | 325 | } |
326 | 326 | ||
327 | /** Destroy jitter buffer */ | 327 | /** Destroy jitter buffer */ |
328 | void jitter_buffer_destroy(JitterBuffer *jitter) | 328 | EXPORT void jitter_buffer_destroy(JitterBuffer *jitter) |
329 | { | 329 | { |
330 | jitter_buffer_reset(jitter); | 330 | jitter_buffer_reset(jitter); |
331 | speex_free(jitter); | 331 | speex_free(jitter); |
@@ -365,12 +365,12 @@ static void shift_timings(JitterBuffer *jitter, spx_int16_t amount) | |||
365 | 365 | ||
366 | 366 | ||
367 | /** Put one packet into the jitter buffer */ | 367 | /** Put one packet into the jitter buffer */ |
368 | void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet) | 368 | EXPORT void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet) |
369 | { | 369 | { |
370 | int i,j; | 370 | int i,j; |
371 | int late; | 371 | int late; |
372 | /*fprintf (stderr, "put packet %d %d\n", timestamp, span);*/ | 372 | /*fprintf (stderr, "put packet %d %d\n", timestamp, span);*/ |
373 | 373 | ||
374 | /* Cleanup buffer (remove old packets that weren't played) */ | 374 | /* Cleanup buffer (remove old packets that weren't played) */ |
375 | if (!jitter->reset_state) | 375 | if (!jitter->reset_state) |
376 | { | 376 | { |
@@ -388,7 +388,7 @@ void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet) | |||
388 | } | 388 | } |
389 | } | 389 | } |
390 | } | 390 | } |
391 | 391 | ||
392 | /*fprintf(stderr, "arrival: %d %d %d\n", packet->timestamp, jitter->next_stop, jitter->pointer_timestamp);*/ | 392 | /*fprintf(stderr, "arrival: %d %d %d\n", packet->timestamp, jitter->next_stop, jitter->pointer_timestamp);*/ |
393 | /* Check if packet is late (could still be useful though) */ | 393 | /* Check if packet is late (could still be useful though) */ |
394 | if (!jitter->reset_state && LT32(packet->timestamp, jitter->next_stop)) | 394 | if (!jitter->reset_state && LT32(packet->timestamp, jitter->next_stop)) |
@@ -398,7 +398,14 @@ void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet) | |||
398 | } else { | 398 | } else { |
399 | late = 0; | 399 | late = 0; |
400 | } | 400 | } |
401 | 401 | ||
402 | /* For some reason, the consumer has failed the last 20 fetches. Make sure this packet is | ||
403 | * used to resync. */ | ||
404 | if (jitter->lost_count>20) | ||
405 | { | ||
406 | jitter_buffer_reset(jitter); | ||
407 | } | ||
408 | |||
402 | /* Only insert the packet if it's not hopelessly late (i.e. totally useless) */ | 409 | /* Only insert the packet if it's not hopelessly late (i.e. totally useless) */ |
403 | if (jitter->reset_state || GE32(packet->timestamp+packet->span+jitter->delay_step, jitter->pointer_timestamp)) | 410 | if (jitter->reset_state || GE32(packet->timestamp+packet->span+jitter->delay_step, jitter->pointer_timestamp)) |
404 | { | 411 | { |
@@ -409,7 +416,7 @@ void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet) | |||
409 | if (jitter->packets[i].data==NULL) | 416 | if (jitter->packets[i].data==NULL) |
410 | break; | 417 | break; |
411 | } | 418 | } |
412 | 419 | ||
413 | /*No place left in the buffer, need to make room for it by discarding the oldest packet */ | 420 | /*No place left in the buffer, need to make room for it by discarding the oldest packet */ |
414 | if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) | 421 | if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) |
415 | { | 422 | { |
@@ -428,13 +435,9 @@ void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet) | |||
428 | else | 435 | else |
429 | speex_free(jitter->packets[i].data); | 436 | speex_free(jitter->packets[i].data); |
430 | jitter->packets[i].data=NULL; | 437 | jitter->packets[i].data=NULL; |
431 | if (jitter->lost_count>20) | 438 | /*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp);*/ |
432 | { | ||
433 | jitter_buffer_reset(jitter); | ||
434 | } | ||
435 | /*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp);*/ | ||
436 | } | 439 | } |
437 | 440 | ||
438 | /* Copy packet in buffer */ | 441 | /* Copy packet in buffer */ |
439 | if (jitter->destroy) | 442 | if (jitter->destroy) |
440 | { | 443 | { |
@@ -454,18 +457,18 @@ void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet) | |||
454 | else | 457 | else |
455 | jitter->arrival[i] = jitter->next_stop; | 458 | jitter->arrival[i] = jitter->next_stop; |
456 | } | 459 | } |
457 | 460 | ||
458 | 461 | ||
459 | } | 462 | } |
460 | 463 | ||
461 | /** Get one packet from the jitter buffer */ | 464 | /** Get one packet from the jitter buffer */ |
462 | int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset) | 465 | EXPORT int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset) |
463 | { | 466 | { |
464 | int i; | 467 | int i; |
465 | unsigned int j; | 468 | unsigned int j; |
466 | int incomplete = 0; | 469 | int incomplete = 0; |
467 | spx_int16_t opt; | 470 | spx_int16_t opt; |
468 | 471 | ||
469 | if (start_offset != NULL) | 472 | if (start_offset != NULL) |
470 | *start_offset = 0; | 473 | *start_offset = 0; |
471 | 474 | ||
@@ -485,7 +488,7 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 | |||
485 | } | 488 | } |
486 | if (found) | 489 | if (found) |
487 | { | 490 | { |
488 | jitter->reset_state=0; | 491 | jitter->reset_state=0; |
489 | jitter->pointer_timestamp = oldest; | 492 | jitter->pointer_timestamp = oldest; |
490 | jitter->next_stop = oldest; | 493 | jitter->next_stop = oldest; |
491 | } else { | 494 | } else { |
@@ -494,36 +497,36 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 | |||
494 | return JITTER_BUFFER_MISSING; | 497 | return JITTER_BUFFER_MISSING; |
495 | } | 498 | } |
496 | } | 499 | } |
497 | 500 | ||
498 | 501 | ||
499 | jitter->last_returned_timestamp = jitter->pointer_timestamp; | 502 | jitter->last_returned_timestamp = jitter->pointer_timestamp; |
500 | 503 | ||
501 | if (jitter->interp_requested != 0) | 504 | if (jitter->interp_requested != 0) |
502 | { | 505 | { |
503 | packet->timestamp = jitter->pointer_timestamp; | 506 | packet->timestamp = jitter->pointer_timestamp; |
504 | packet->span = jitter->interp_requested; | 507 | packet->span = jitter->interp_requested; |
505 | 508 | ||
506 | /* Increment the pointer because it got decremented in the delay update */ | 509 | /* Increment the pointer because it got decremented in the delay update */ |
507 | jitter->pointer_timestamp += jitter->interp_requested; | 510 | jitter->pointer_timestamp += jitter->interp_requested; |
508 | packet->len = 0; | 511 | packet->len = 0; |
509 | /*fprintf (stderr, "Deferred interpolate\n");*/ | 512 | /*fprintf (stderr, "Deferred interpolate\n");*/ |
510 | 513 | ||
511 | jitter->interp_requested = 0; | 514 | jitter->interp_requested = 0; |
512 | 515 | ||
513 | jitter->buffered = packet->span - desired_span; | 516 | jitter->buffered = packet->span - desired_span; |
514 | 517 | ||
515 | return JITTER_BUFFER_INSERTION; | 518 | return JITTER_BUFFER_INSERTION; |
516 | } | 519 | } |
517 | 520 | ||
518 | /* Searching for the packet that fits best */ | 521 | /* Searching for the packet that fits best */ |
519 | 522 | ||
520 | /* Search the buffer for a packet with the right timestamp and spanning the whole current chunk */ | 523 | /* Search the buffer for a packet with the right timestamp and spanning the whole current chunk */ |
521 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | 524 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
522 | { | 525 | { |
523 | if (jitter->packets[i].data && jitter->packets[i].timestamp==jitter->pointer_timestamp && GE32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp+desired_span)) | 526 | if (jitter->packets[i].data && jitter->packets[i].timestamp==jitter->pointer_timestamp && GE32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp+desired_span)) |
524 | break; | 527 | break; |
525 | } | 528 | } |
526 | 529 | ||
527 | /* If no match, try for an "older" packet that still spans (fully) the current chunk */ | 530 | /* If no match, try for an "older" packet that still spans (fully) the current chunk */ |
528 | if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) | 531 | if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) |
529 | { | 532 | { |
@@ -533,7 +536,7 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 | |||
533 | break; | 536 | break; |
534 | } | 537 | } |
535 | } | 538 | } |
536 | 539 | ||
537 | /* If still no match, try for an "older" packet that spans part of the current chunk */ | 540 | /* If still no match, try for an "older" packet that spans part of the current chunk */ |
538 | if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) | 541 | if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) |
539 | { | 542 | { |
@@ -543,7 +546,7 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 | |||
543 | break; | 546 | break; |
544 | } | 547 | } |
545 | } | 548 | } |
546 | 549 | ||
547 | /* If still no match, try for earliest packet possible */ | 550 | /* If still no match, try for earliest packet possible */ |
548 | if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) | 551 | if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) |
549 | { | 552 | { |
@@ -577,17 +580,17 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 | |||
577 | if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE) | 580 | if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE) |
578 | { | 581 | { |
579 | spx_int32_t offset; | 582 | spx_int32_t offset; |
580 | 583 | ||
581 | /* We (obviously) haven't lost this packet */ | 584 | /* We (obviously) haven't lost this packet */ |
582 | jitter->lost_count = 0; | 585 | jitter->lost_count = 0; |
583 | 586 | ||
584 | /* In this case, 0 isn't as a valid timestamp */ | 587 | /* In this case, 0 isn't as a valid timestamp */ |
585 | if (jitter->arrival[i] != 0) | 588 | if (jitter->arrival[i] != 0) |
586 | { | 589 | { |
587 | update_timings(jitter, ((spx_int32_t)jitter->packets[i].timestamp) - ((spx_int32_t)jitter->arrival[i]) - jitter->buffer_margin); | 590 | update_timings(jitter, ((spx_int32_t)jitter->packets[i].timestamp) - ((spx_int32_t)jitter->arrival[i]) - jitter->buffer_margin); |
588 | } | 591 | } |
589 | 592 | ||
590 | 593 | ||
591 | if (jitter->packets[i].len > packet->len) | 594 | if (jitter->packets[i].len > packet->len) |
592 | { | 595 | { |
593 | speex_warning_int("jitter_buffer_get(): packet too large to fit. Size is", jitter->packets[i].len); | 596 | speex_warning_int("jitter_buffer_get(): packet too large to fit. Size is", jitter->packets[i].len); |
@@ -611,10 +614,10 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 | |||
611 | *start_offset = offset; | 614 | *start_offset = offset; |
612 | else if (offset != 0) | 615 | else if (offset != 0) |
613 | speex_warning_int("jitter_buffer_get() discarding non-zero start_offset", offset); | 616 | speex_warning_int("jitter_buffer_get() discarding non-zero start_offset", offset); |
614 | 617 | ||
615 | packet->timestamp = jitter->packets[i].timestamp; | 618 | packet->timestamp = jitter->packets[i].timestamp; |
616 | jitter->last_returned_timestamp = packet->timestamp; | 619 | jitter->last_returned_timestamp = packet->timestamp; |
617 | 620 | ||
618 | packet->span = jitter->packets[i].span; | 621 | packet->span = jitter->packets[i].span; |
619 | packet->sequence = jitter->packets[i].sequence; | 622 | packet->sequence = jitter->packets[i].sequence; |
620 | packet->user_data = jitter->packets[i].user_data; | 623 | packet->user_data = jitter->packets[i].user_data; |
@@ -622,36 +625,36 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 | |||
622 | jitter->pointer_timestamp = jitter->packets[i].timestamp+jitter->packets[i].span; | 625 | jitter->pointer_timestamp = jitter->packets[i].timestamp+jitter->packets[i].span; |
623 | 626 | ||
624 | jitter->buffered = packet->span - desired_span; | 627 | jitter->buffered = packet->span - desired_span; |
625 | 628 | ||
626 | if (start_offset != NULL) | 629 | if (start_offset != NULL) |
627 | jitter->buffered += *start_offset; | 630 | jitter->buffered += *start_offset; |
628 | 631 | ||
629 | return JITTER_BUFFER_OK; | 632 | return JITTER_BUFFER_OK; |
630 | } | 633 | } |
631 | 634 | ||
632 | 635 | ||
633 | /* If we haven't found anything worth returning */ | 636 | /* If we haven't found anything worth returning */ |
634 | 637 | ||
635 | /*fprintf (stderr, "not found\n");*/ | 638 | /*fprintf (stderr, "not found\n");*/ |
636 | jitter->lost_count++; | 639 | jitter->lost_count++; |
637 | /*fprintf (stderr, "m");*/ | 640 | /*fprintf (stderr, "m");*/ |
638 | /*fprintf (stderr, "lost_count = %d\n", jitter->lost_count);*/ | 641 | /*fprintf (stderr, "lost_count = %d\n", jitter->lost_count);*/ |
639 | 642 | ||
640 | opt = compute_opt_delay(jitter); | 643 | opt = compute_opt_delay(jitter); |
641 | 644 | ||
642 | /* Should we force an increase in the buffer or just do normal interpolation? */ | 645 | /* Should we force an increase in the buffer or just do normal interpolation? */ |
643 | if (opt < 0) | 646 | if (opt < 0) |
644 | { | 647 | { |
645 | /* Need to increase buffering */ | 648 | /* Need to increase buffering */ |
646 | 649 | ||
647 | /* Shift histogram to compensate */ | 650 | /* Shift histogram to compensate */ |
648 | shift_timings(jitter, -opt); | 651 | shift_timings(jitter, -opt); |
649 | 652 | ||
650 | packet->timestamp = jitter->pointer_timestamp; | 653 | packet->timestamp = jitter->pointer_timestamp; |
651 | packet->span = -opt; | 654 | packet->span = -opt; |
652 | /* Don't move the pointer_timestamp forward */ | 655 | /* Don't move the pointer_timestamp forward */ |
653 | packet->len = 0; | 656 | packet->len = 0; |
654 | 657 | ||
655 | jitter->buffered = packet->span - desired_span; | 658 | jitter->buffered = packet->span - desired_span; |
656 | return JITTER_BUFFER_INSERTION; | 659 | return JITTER_BUFFER_INSERTION; |
657 | /*jitter->pointer_timestamp -= jitter->delay_step;*/ | 660 | /*jitter->pointer_timestamp -= jitter->delay_step;*/ |
@@ -659,12 +662,12 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 | |||
659 | } else { | 662 | } else { |
660 | /* Normal packet loss */ | 663 | /* Normal packet loss */ |
661 | packet->timestamp = jitter->pointer_timestamp; | 664 | packet->timestamp = jitter->pointer_timestamp; |
662 | 665 | ||
663 | desired_span = ROUND_DOWN(desired_span, jitter->concealment_size); | 666 | desired_span = ROUND_DOWN(desired_span, jitter->concealment_size); |
664 | packet->span = desired_span; | 667 | packet->span = desired_span; |
665 | jitter->pointer_timestamp += desired_span; | 668 | jitter->pointer_timestamp += desired_span; |
666 | packet->len = 0; | 669 | packet->len = 0; |
667 | 670 | ||
668 | jitter->buffered = packet->span - desired_span; | 671 | jitter->buffered = packet->span - desired_span; |
669 | return JITTER_BUFFER_MISSING; | 672 | return JITTER_BUFFER_MISSING; |
670 | /*fprintf (stderr, "Normal loss\n");*/ | 673 | /*fprintf (stderr, "Normal loss\n");*/ |
@@ -673,7 +676,7 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 | |||
673 | 676 | ||
674 | } | 677 | } |
675 | 678 | ||
676 | int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet) | 679 | EXPORT int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet) |
677 | { | 680 | { |
678 | int i, j; | 681 | int i, j; |
679 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | 682 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
@@ -713,11 +716,11 @@ static int _jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket | |||
713 | { | 716 | { |
714 | spx_int16_t opt = compute_opt_delay(jitter); | 717 | spx_int16_t opt = compute_opt_delay(jitter); |
715 | /*fprintf(stderr, "opt adjustment is %d ", opt);*/ | 718 | /*fprintf(stderr, "opt adjustment is %d ", opt);*/ |
716 | 719 | ||
717 | if (opt < 0) | 720 | if (opt < 0) |
718 | { | 721 | { |
719 | shift_timings(jitter, -opt); | 722 | shift_timings(jitter, -opt); |
720 | 723 | ||
721 | jitter->pointer_timestamp += opt; | 724 | jitter->pointer_timestamp += opt; |
722 | jitter->interp_requested = -opt; | 725 | jitter->interp_requested = -opt; |
723 | /*fprintf (stderr, "Decision to interpolate %d samples\n", -opt);*/ | 726 | /*fprintf (stderr, "Decision to interpolate %d samples\n", -opt);*/ |
@@ -727,14 +730,14 @@ static int _jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket | |||
727 | jitter->pointer_timestamp += opt; | 730 | jitter->pointer_timestamp += opt; |
728 | /*fprintf (stderr, "Decision to drop %d samples\n", opt);*/ | 731 | /*fprintf (stderr, "Decision to drop %d samples\n", opt);*/ |
729 | } | 732 | } |
730 | 733 | ||
731 | return opt; | 734 | return opt; |
732 | } | 735 | } |
733 | 736 | ||
734 | /* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */ | 737 | /* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */ |
735 | int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset) | 738 | EXPORT int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset) |
736 | { | 739 | { |
737 | /* If the programmer calls jitter_buffer_update_delay() directly, | 740 | /* If the programmer calls jitter_buffer_update_delay() directly, |
738 | automatically disable auto-adjustment */ | 741 | automatically disable auto-adjustment */ |
739 | jitter->auto_adjust = 0; | 742 | jitter->auto_adjust = 0; |
740 | 743 | ||
@@ -742,17 +745,17 @@ int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, | |||
742 | } | 745 | } |
743 | 746 | ||
744 | /** Get pointer timestamp of jitter buffer */ | 747 | /** Get pointer timestamp of jitter buffer */ |
745 | int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter) | 748 | EXPORT int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter) |
746 | { | 749 | { |
747 | return jitter->pointer_timestamp; | 750 | return jitter->pointer_timestamp; |
748 | } | 751 | } |
749 | 752 | ||
750 | void jitter_buffer_tick(JitterBuffer *jitter) | 753 | EXPORT void jitter_buffer_tick(JitterBuffer *jitter) |
751 | { | 754 | { |
752 | /* Automatically-adjust the buffering delay if requested */ | 755 | /* Automatically-adjust the buffering delay if requested */ |
753 | if (jitter->auto_adjust) | 756 | if (jitter->auto_adjust) |
754 | _jitter_buffer_update_delay(jitter, NULL, NULL); | 757 | _jitter_buffer_update_delay(jitter, NULL, NULL); |
755 | 758 | ||
756 | if (jitter->buffered >= 0) | 759 | if (jitter->buffered >= 0) |
757 | { | 760 | { |
758 | jitter->next_stop = jitter->pointer_timestamp - jitter->buffered; | 761 | jitter->next_stop = jitter->pointer_timestamp - jitter->buffered; |
@@ -763,12 +766,12 @@ void jitter_buffer_tick(JitterBuffer *jitter) | |||
763 | jitter->buffered = 0; | 766 | jitter->buffered = 0; |
764 | } | 767 | } |
765 | 768 | ||
766 | void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem) | 769 | EXPORT void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem) |
767 | { | 770 | { |
768 | /* Automatically-adjust the buffering delay if requested */ | 771 | /* Automatically-adjust the buffering delay if requested */ |
769 | if (jitter->auto_adjust) | 772 | if (jitter->auto_adjust) |
770 | _jitter_buffer_update_delay(jitter, NULL, NULL); | 773 | _jitter_buffer_update_delay(jitter, NULL, NULL); |
771 | 774 | ||
772 | if (jitter->buffered < 0) | 775 | if (jitter->buffered < 0) |
773 | speex_warning_int("jitter buffer sees negative buffering, your code might be broken. Value is ", jitter->buffered); | 776 | speex_warning_int("jitter buffer sees negative buffering, your code might be broken. Value is ", jitter->buffered); |
774 | jitter->next_stop = jitter->pointer_timestamp - rem; | 777 | jitter->next_stop = jitter->pointer_timestamp - rem; |
@@ -776,7 +779,7 @@ void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem) | |||
776 | 779 | ||
777 | 780 | ||
778 | /* Used like the ioctl function to control the jitter buffer parameters */ | 781 | /* Used like the ioctl function to control the jitter buffer parameters */ |
779 | int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr) | 782 | EXPORT int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr) |
780 | { | 783 | { |
781 | int count, i; | 784 | int count, i; |
782 | switch(request) | 785 | switch(request) |
@@ -836,4 +839,3 @@ int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr) | |||
836 | } | 839 | } |
837 | return 0; | 840 | return 0; |
838 | } | 841 | } |
839 | |||