123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839 |
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include "arch.h"
- #include <speex/speex_jitter.h>
- #include "os_support.h"
- #ifndef NULL
- #define NULL 0
- #endif
- #define SPEEX_JITTER_MAX_BUFFER_SIZE 200
- #define TSUB(a,b) ((spx_int32_t)((a)-(b)))
- #define GT32(a,b) (((spx_int32_t)((a)-(b)))>0)
- #define GE32(a,b) (((spx_int32_t)((a)-(b)))>=0)
- #define LT32(a,b) (((spx_int32_t)((a)-(b)))<0)
- #define LE32(a,b) (((spx_int32_t)((a)-(b)))<=0)
- #define ROUND_DOWN(x, step) ((x)<0 ? ((x)-(step)+1)/(step)*(step) : (x)/(step)*(step))
- #define MAX_TIMINGS 40
- #define MAX_BUFFERS 3
- #define TOP_DELAY 40
- struct TimingBuffer {
- int filled;
- int curr_count;
- spx_int32_t timing[MAX_TIMINGS];
- spx_int16_t counts[MAX_TIMINGS];
- };
- static void tb_init(struct TimingBuffer *tb)
- {
- tb->filled = 0;
- tb->curr_count = 0;
- }
- static void tb_add(struct TimingBuffer *tb, spx_int16_t timing)
- {
- int pos;
-
- if (tb->filled >= MAX_TIMINGS && timing >= tb->timing[tb->filled-1])
- {
- tb->curr_count++;
- return;
- }
-
-
- pos = 0;
-
- while (pos<tb->filled && timing >= tb->timing[pos])
- {
- pos++;
- }
-
- speex_assert(pos <= tb->filled && pos < MAX_TIMINGS);
-
-
- if (pos < tb->filled)
- {
- int move_size = tb->filled-pos;
- if (tb->filled == MAX_TIMINGS)
- move_size -= 1;
- SPEEX_MOVE(&tb->timing[pos+1], &tb->timing[pos], move_size);
- SPEEX_MOVE(&tb->counts[pos+1], &tb->counts[pos], move_size);
- }
-
- tb->timing[pos] = timing;
- tb->counts[pos] = tb->curr_count;
-
- tb->curr_count++;
- if (tb->filled<MAX_TIMINGS)
- tb->filled++;
- }
- struct JitterBuffer_ {
- spx_uint32_t pointer_timestamp;
- spx_uint32_t last_returned_timestamp;
- spx_uint32_t next_stop;
-
- spx_int32_t buffered;
-
- JitterBufferPacket packets[SPEEX_JITTER_MAX_BUFFER_SIZE];
- spx_uint32_t arrival[SPEEX_JITTER_MAX_BUFFER_SIZE];
-
- void (*destroy) (void *);
- spx_int32_t delay_step;
- spx_int32_t concealment_size;
- int reset_state;
- int buffer_margin;
- int late_cutoff;
- int interp_requested;
- int auto_adjust;
-
- struct TimingBuffer _tb[MAX_BUFFERS];
- struct TimingBuffer *timeBuffers[MAX_BUFFERS];
- int window_size;
- int subwindow_size;
- int max_late_rate;
- int latency_tradeoff;
- int auto_tradeoff;
-
- int lost_count;
- };
- static spx_int16_t compute_opt_delay(JitterBuffer *jitter)
- {
- int i;
- spx_int16_t opt=0;
- spx_int32_t best_cost=0x7fffffff;
- int late = 0;
- int pos[MAX_BUFFERS];
- int tot_count;
- float late_factor;
- int penalty_taken = 0;
- int best = 0;
- int worst = 0;
- spx_int32_t deltaT;
- struct TimingBuffer *tb;
-
- tb = jitter->_tb;
-
-
- tot_count = 0;
- for (i=0;i<MAX_BUFFERS;i++)
- tot_count += tb[i].curr_count;
- if (tot_count==0)
- return 0;
-
-
- if (jitter->latency_tradeoff != 0)
- late_factor = jitter->latency_tradeoff * 100.0f / tot_count;
- else
- late_factor = jitter->auto_tradeoff * jitter->window_size/tot_count;
-
-
- for (i=0;i<MAX_BUFFERS;i++)
- pos[i] = 0;
-
-
- for (i=0;i<TOP_DELAY;i++)
- {
- int j;
- int next=-1;
- int latest = 32767;
-
- for (j=0;j<MAX_BUFFERS;j++)
- {
- if (pos[j] < tb[j].filled && tb[j].timing[pos[j]] < latest)
- {
- next = j;
- latest = tb[j].timing[pos[j]];
- }
- }
- if (next != -1)
- {
- spx_int32_t cost;
-
- if (i==0)
- worst = latest;
- best = latest;
- latest = ROUND_DOWN(latest, jitter->delay_step);
- pos[next]++;
-
-
- cost = -latest + late_factor*late;
-
- if (cost < best_cost)
- {
- best_cost = cost;
- opt = latest;
- }
- } else {
- break;
- }
-
-
- late++;
-
- if (latest >= 0 && !penalty_taken)
- {
- penalty_taken = 1;
- late+=4;
- }
- }
-
- deltaT = best-worst;
-
- jitter->auto_tradeoff = 1 + deltaT/TOP_DELAY;
-
-
-
-
-
- if (tot_count < TOP_DELAY && opt > 0)
- return 0;
- return opt;
- }
- EXPORT JitterBuffer *jitter_buffer_init(int step_size)
- {
- JitterBuffer *jitter = (JitterBuffer*)speex_alloc(sizeof(JitterBuffer));
- if (jitter)
- {
- int i;
- spx_int32_t tmp;
- for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
- jitter->packets[i].data=NULL;
- jitter->delay_step = step_size;
- jitter->concealment_size = step_size;
-
- jitter->buffer_margin = 0;
- jitter->late_cutoff = 50;
- jitter->destroy = NULL;
- jitter->latency_tradeoff = 0;
- jitter->auto_adjust = 1;
- tmp = 4;
- jitter_buffer_ctl(jitter, JITTER_BUFFER_SET_MAX_LATE_RATE, &tmp);
- jitter_buffer_reset(jitter);
- }
- return jitter;
- }
- EXPORT void jitter_buffer_reset(JitterBuffer *jitter)
- {
- int i;
- for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
- {
- if (jitter->packets[i].data)
- {
- if (jitter->destroy)
- jitter->destroy(jitter->packets[i].data);
- else
- speex_free(jitter->packets[i].data);
- jitter->packets[i].data = NULL;
- }
- }
-
- jitter->pointer_timestamp = 0;
- jitter->next_stop = 0;
- jitter->reset_state = 1;
- jitter->lost_count = 0;
- jitter->buffered = 0;
- jitter->auto_tradeoff = 32000;
-
- for (i=0;i<MAX_BUFFERS;i++)
- {
- tb_init(&jitter->_tb[i]);
- jitter->timeBuffers[i] = &jitter->_tb[i];
- }
-
- }
- EXPORT void jitter_buffer_destroy(JitterBuffer *jitter)
- {
- jitter_buffer_reset(jitter);
- speex_free(jitter);
- }
- static void update_timings(JitterBuffer *jitter, spx_int32_t timing)
- {
- if (timing < -32767)
- timing = -32767;
- if (timing > 32767)
- timing = 32767;
-
- if (jitter->timeBuffers[0]->curr_count >= jitter->subwindow_size)
- {
- int i;
-
- struct TimingBuffer *tmp = jitter->timeBuffers[MAX_BUFFERS-1];
- for (i=MAX_BUFFERS-1;i>=1;i--)
- jitter->timeBuffers[i] = jitter->timeBuffers[i-1];
- jitter->timeBuffers[0] = tmp;
- tb_init(jitter->timeBuffers[0]);
- }
- tb_add(jitter->timeBuffers[0], timing);
- }
- static void shift_timings(JitterBuffer *jitter, spx_int16_t amount)
- {
- int i, j;
- for (i=0;i<MAX_BUFFERS;i++)
- {
- for (j=0;j<jitter->timeBuffers[i]->filled;j++)
- jitter->timeBuffers[i]->timing[j] += amount;
- }
- }
- EXPORT void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet)
- {
- int i,j;
- int late;
-
-
-
- if (!jitter->reset_state)
- {
- for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
- {
-
- if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp + jitter->packets[i].span, jitter->pointer_timestamp))
- {
-
- if (jitter->destroy)
- jitter->destroy(jitter->packets[i].data);
- else
- speex_free(jitter->packets[i].data);
- jitter->packets[i].data = NULL;
- }
- }
- }
-
-
-
- if (!jitter->reset_state && LT32(packet->timestamp, jitter->next_stop))
- {
- update_timings(jitter, ((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->next_stop) - jitter->buffer_margin);
- late = 1;
- } else {
- late = 0;
- }
-
- if (jitter->lost_count>20)
- {
- jitter_buffer_reset(jitter);
- }
-
-
- if (jitter->reset_state || GE32(packet->timestamp+packet->span+jitter->delay_step, jitter->pointer_timestamp))
- {
-
- for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
- {
- if (jitter->packets[i].data==NULL)
- break;
- }
-
-
- if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
- {
- int earliest=jitter->packets[0].timestamp;
- i=0;
- for (j=1;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++)
- {
- if (!jitter->packets[i].data || LT32(jitter->packets[j].timestamp,earliest))
- {
- earliest = jitter->packets[j].timestamp;
- i=j;
- }
- }
- if (jitter->destroy)
- jitter->destroy(jitter->packets[i].data);
- else
- speex_free(jitter->packets[i].data);
- jitter->packets[i].data=NULL;
-
- }
-
-
- if (jitter->destroy)
- {
- jitter->packets[i].data = packet->data;
- } else {
- jitter->packets[i].data=(char*)speex_alloc(packet->len);
- for (j=0;j<packet->len;j++)
- jitter->packets[i].data[j]=packet->data[j];
- }
- jitter->packets[i].timestamp=packet->timestamp;
- jitter->packets[i].span=packet->span;
- jitter->packets[i].len=packet->len;
- jitter->packets[i].sequence=packet->sequence;
- jitter->packets[i].user_data=packet->user_data;
- if (jitter->reset_state || late)
- jitter->arrival[i] = 0;
- else
- jitter->arrival[i] = jitter->next_stop;
- }
-
-
- }
- EXPORT int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset)
- {
- int i;
- unsigned int j;
- spx_int16_t opt;
-
- if (start_offset != NULL)
- *start_offset = 0;
-
- if (jitter->reset_state)
- {
- int found = 0;
-
- spx_uint32_t oldest=0;
- for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
- {
- if (jitter->packets[i].data && (!found || LT32(jitter->packets[i].timestamp,oldest)))
- {
- oldest = jitter->packets[i].timestamp;
- found = 1;
- }
- }
- if (found)
- {
- jitter->reset_state=0;
- jitter->pointer_timestamp = oldest;
- jitter->next_stop = oldest;
- } else {
- packet->timestamp = 0;
- packet->span = jitter->interp_requested;
- return JITTER_BUFFER_MISSING;
- }
- }
-
- jitter->last_returned_timestamp = jitter->pointer_timestamp;
-
- if (jitter->interp_requested != 0)
- {
- packet->timestamp = jitter->pointer_timestamp;
- packet->span = jitter->interp_requested;
-
-
- jitter->pointer_timestamp += jitter->interp_requested;
- packet->len = 0;
-
-
- jitter->interp_requested = 0;
-
- jitter->buffered = packet->span - desired_span;
- return JITTER_BUFFER_INSERTION;
- }
-
-
-
-
- for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
- {
- 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))
- break;
- }
-
-
- if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
- {
- for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
- {
- if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp, jitter->pointer_timestamp) && GE32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp+desired_span))
- break;
- }
- }
-
-
- if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
- {
- for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
- {
- if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp, jitter->pointer_timestamp) && GT32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp))
- break;
- }
- }
-
-
- if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
- {
- int found = 0;
- spx_uint32_t best_time=0;
- int best_span=0;
- int besti=0;
- for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
- {
-
- if (jitter->packets[i].data && LT32(jitter->packets[i].timestamp,jitter->pointer_timestamp+desired_span) && GE32(jitter->packets[i].timestamp,jitter->pointer_timestamp))
- {
- if (!found || LT32(jitter->packets[i].timestamp,best_time) || (jitter->packets[i].timestamp==best_time && GT32(jitter->packets[i].span,best_span)))
- {
- best_time = jitter->packets[i].timestamp;
- best_span = jitter->packets[i].span;
- besti = i;
- found = 1;
- }
- }
- }
- if (found)
- {
- i=besti;
-
- }
- }
-
- if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE)
- {
- spx_int32_t offset;
-
-
- jitter->lost_count = 0;
-
-
- if (jitter->arrival[i] != 0)
- {
- update_timings(jitter, ((spx_int32_t)jitter->packets[i].timestamp) - ((spx_int32_t)jitter->arrival[i]) - jitter->buffer_margin);
- }
-
-
-
- if (jitter->destroy)
- {
- packet->data = jitter->packets[i].data;
- packet->len = jitter->packets[i].len;
- } else {
- if (jitter->packets[i].len > packet->len)
- {
- speex_warning_int("jitter_buffer_get(): packet too large to fit. Size is", jitter->packets[i].len);
- } else {
- packet->len = jitter->packets[i].len;
- }
- for (j=0;j<packet->len;j++)
- packet->data[j] = jitter->packets[i].data[j];
-
- speex_free(jitter->packets[i].data);
- }
- jitter->packets[i].data = NULL;
-
- offset = (spx_int32_t)jitter->packets[i].timestamp-(spx_int32_t)jitter->pointer_timestamp;
- if (start_offset != NULL)
- *start_offset = offset;
- else if (offset != 0)
- speex_warning_int("jitter_buffer_get() discarding non-zero start_offset", offset);
-
- packet->timestamp = jitter->packets[i].timestamp;
- jitter->last_returned_timestamp = packet->timestamp;
-
- packet->span = jitter->packets[i].span;
- packet->sequence = jitter->packets[i].sequence;
- packet->user_data = jitter->packets[i].user_data;
-
- jitter->pointer_timestamp = jitter->packets[i].timestamp+jitter->packets[i].span;
- jitter->buffered = packet->span - desired_span;
-
- if (start_offset != NULL)
- jitter->buffered += *start_offset;
-
- return JITTER_BUFFER_OK;
- }
-
-
-
-
-
- jitter->lost_count++;
-
-
-
- opt = compute_opt_delay(jitter);
-
-
- if (opt < 0)
- {
-
-
-
- shift_timings(jitter, -opt);
-
- packet->timestamp = jitter->pointer_timestamp;
- packet->span = -opt;
-
- packet->len = 0;
-
- jitter->buffered = packet->span - desired_span;
- return JITTER_BUFFER_INSERTION;
-
-
- } else {
-
- packet->timestamp = jitter->pointer_timestamp;
-
- desired_span = ROUND_DOWN(desired_span, jitter->concealment_size);
- packet->span = desired_span;
- jitter->pointer_timestamp += desired_span;
- packet->len = 0;
-
- jitter->buffered = packet->span - desired_span;
- return JITTER_BUFFER_MISSING;
-
- }
- }
- EXPORT int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet)
- {
- int i, j;
- for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
- {
- if (jitter->packets[i].data && jitter->packets[i].timestamp==jitter->last_returned_timestamp)
- break;
- }
- if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE)
- {
-
- packet->len = jitter->packets[i].len;
- if (jitter->destroy)
- {
- packet->data = jitter->packets[i].data;
- } else {
- for (j=0;j<packet->len;j++)
- packet->data[j] = jitter->packets[i].data[j];
-
- speex_free(jitter->packets[i].data);
- }
- jitter->packets[i].data = NULL;
- packet->timestamp = jitter->packets[i].timestamp;
- packet->span = jitter->packets[i].span;
- packet->sequence = jitter->packets[i].sequence;
- packet->user_data = jitter->packets[i].user_data;
- return JITTER_BUFFER_OK;
- } else {
- packet->data = NULL;
- packet->len = 0;
- packet->span = 0;
- return JITTER_BUFFER_MISSING;
- }
- }
- static int _jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset)
- {
- spx_int16_t opt = compute_opt_delay(jitter);
-
-
- if (opt < 0)
- {
- shift_timings(jitter, -opt);
-
- jitter->pointer_timestamp += opt;
- jitter->interp_requested = -opt;
-
- } else if (opt > 0)
- {
- shift_timings(jitter, -opt);
- jitter->pointer_timestamp += opt;
-
- }
-
- return opt;
- }
- EXPORT int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset)
- {
-
- jitter->auto_adjust = 0;
- return _jitter_buffer_update_delay(jitter, packet, start_offset);
- }
- EXPORT int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter)
- {
- return jitter->pointer_timestamp;
- }
- EXPORT void jitter_buffer_tick(JitterBuffer *jitter)
- {
-
- if (jitter->auto_adjust)
- _jitter_buffer_update_delay(jitter, NULL, NULL);
-
- if (jitter->buffered >= 0)
- {
- jitter->next_stop = jitter->pointer_timestamp - jitter->buffered;
- } else {
- jitter->next_stop = jitter->pointer_timestamp;
- speex_warning_int("jitter buffer sees negative buffering, your code might be broken. Value is ", jitter->buffered);
- }
- jitter->buffered = 0;
- }
- EXPORT void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem)
- {
-
- if (jitter->auto_adjust)
- _jitter_buffer_update_delay(jitter, NULL, NULL);
-
- if (jitter->buffered < 0)
- speex_warning_int("jitter buffer sees negative buffering, your code might be broken. Value is ", jitter->buffered);
- jitter->next_stop = jitter->pointer_timestamp - rem;
- }
- EXPORT int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr)
- {
- int count, i;
- switch(request)
- {
- case JITTER_BUFFER_SET_MARGIN:
- jitter->buffer_margin = *(spx_int32_t*)ptr;
- break;
- case JITTER_BUFFER_GET_MARGIN:
- *(spx_int32_t*)ptr = jitter->buffer_margin;
- break;
- case JITTER_BUFFER_GET_AVALIABLE_COUNT:
- count = 0;
- for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
- {
- if (jitter->packets[i].data && LE32(jitter->pointer_timestamp, jitter->packets[i].timestamp))
- {
- count++;
- }
- }
- *(spx_int32_t*)ptr = count;
- break;
- case JITTER_BUFFER_SET_DESTROY_CALLBACK:
- jitter->destroy = (void (*) (void *))ptr;
- break;
- case JITTER_BUFFER_GET_DESTROY_CALLBACK:
- *(void (**) (void *))ptr = jitter->destroy;
- break;
- case JITTER_BUFFER_SET_DELAY_STEP:
- jitter->delay_step = *(spx_int32_t*)ptr;
- break;
- case JITTER_BUFFER_GET_DELAY_STEP:
- *(spx_int32_t*)ptr = jitter->delay_step;
- break;
- case JITTER_BUFFER_SET_CONCEALMENT_SIZE:
- jitter->concealment_size = *(spx_int32_t*)ptr;
- break;
- case JITTER_BUFFER_GET_CONCEALMENT_SIZE:
- *(spx_int32_t*)ptr = jitter->concealment_size;
- break;
- case JITTER_BUFFER_SET_MAX_LATE_RATE:
- jitter->max_late_rate = *(spx_int32_t*)ptr;
- jitter->window_size = 100*TOP_DELAY/jitter->max_late_rate;
- jitter->subwindow_size = jitter->window_size/MAX_BUFFERS;
- break;
- case JITTER_BUFFER_GET_MAX_LATE_RATE:
- *(spx_int32_t*)ptr = jitter->max_late_rate;
- break;
- case JITTER_BUFFER_SET_LATE_COST:
- jitter->latency_tradeoff = *(spx_int32_t*)ptr;
- break;
- case JITTER_BUFFER_GET_LATE_COST:
- *(spx_int32_t*)ptr = jitter->latency_tradeoff;
- break;
- default:
- speex_warning_int("Unknown jitter_buffer_ctl request: ", request);
- return -1;
- }
- return 0;
- }
|