1
/* $Id: jbuf.c 4728 2014-02-04 10:13:56Z bennylp $ */
3
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
6
* This program 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.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
* Based on implementation kindly contributed by Switchlab, Ltd.
23
#include <pjmedia/jbuf.h>
24
#include <pjmedia/errno.h>
26
#include <pj/assert.h>
29
#include <pj/string.h>
32
#define THIS_FILE "jbuf.c"
35
/* Invalid sequence number, used as the initial value. */
36
#define INVALID_OFFSET -9999
38
/* Maximum burst length, whenever an operation is bursting longer than
39
* this value, JB will assume that the opposite operation was idle.
41
#define MAX_BURST_MSEC 1000
43
/* Number of OP switches to be performed in JB_STATUS_INITIALIZING, before
44
* JB can switch its states to JB_STATUS_PROCESSING.
49
/* Minimal difference between JB size and 2*burst-level to perform
50
* JB shrinking in static discard algorithm.
52
#define STA_DISC_SAFE_SHRINKING_DIFF 1
55
/* Struct of JB internal buffer, represented in a circular buffer containing
56
* frame content, frame type, frame length, and frame bit info.
58
typedef struct jb_framelist_t
61
unsigned frame_size; /**< maximum size of frame */
62
unsigned max_count; /**< maximum number of frames */
65
char *content; /**< frame content array */
66
int *frame_type; /**< frame type array */
67
pj_size_t *content_len; /**< frame length array */
68
pj_uint32_t *bit_info; /**< frame bit info array */
69
pj_uint32_t *ts; /**< timestamp array */
72
unsigned head; /**< index of head, pointed frame
73
will be returned by next GET */
74
unsigned size; /**< current size of framelist,
75
including discarded frames. */
76
unsigned discarded_num; /**< current number of discarded
78
int origin; /**< original index of flist_head */
83
typedef void (*discard_algo)(pjmedia_jbuf *jb);
84
static void jbuf_discard_static(pjmedia_jbuf *jb);
85
static void jbuf_discard_progressive(pjmedia_jbuf *jb);
90
/* Settings (consts) */
91
pj_str_t jb_name; /**< jitter buffer name */
92
pj_size_t jb_frame_size; /**< frame size */
93
unsigned jb_frame_ptime; /**< frame duration. */
94
pj_size_t jb_max_count; /**< capacity of jitter buffer,
96
int jb_init_prefetch; /**< Initial prefetch */
97
int jb_min_prefetch; /**< Minimum allowable prefetch */
98
int jb_max_prefetch; /**< Maximum allowable prefetch */
99
int jb_max_burst; /**< maximum possible burst, whenever
100
burst exceeds this value, it
101
won't be included in level
103
int jb_min_shrink_gap; /**< How often can we shrink */
104
discard_algo jb_discard_algo; /**< Discard algorithm */
107
jb_framelist_t jb_framelist; /**< the buffer */
110
int jb_level; /**< delay between source &
111
destination (calculated according
112
of the number of burst get/put
114
int jb_max_hist_level; /**< max level during the last level
116
int jb_stable_hist; /**< num of times the delay has been
117
lower then the prefetch num */
118
int jb_last_op; /**< last operation executed
120
int jb_eff_level; /**< effective burst level */
121
int jb_prefetch; /**< no. of frame to insert before
122
removing some (at the beginning
123
of the framelist->content
124
operation), the value may be
125
continuously updated based on
126
current frame burst level. */
127
pj_bool_t jb_prefetching; /**< flag if jbuf is prefetching. */
128
int jb_status; /**< status is 'init' until the first
130
int jb_init_cycle_cnt; /**< status is 'init' until the first
133
int jb_discard_ref; /**< Seq # of last frame deleted or
135
unsigned jb_discard_dist; /**< Distance from jb_discard_ref
136
to perform discard (in frm) */
139
pj_math_stat jb_delay; /**< Delay statistics of jitter buffer
141
pj_math_stat jb_burst; /**< Burst statistics (in frames) */
142
unsigned jb_lost; /**< Number of lost frames. */
143
unsigned jb_discard; /**< Number of discarded frames. */
144
unsigned jb_empty; /**< Number of empty/prefetching frame
149
#define JB_STATUS_INITIALIZING 0
150
#define JB_STATUS_PROCESSING 1
154
/* Progressive discard algorithm introduced to reduce JB latency
155
* by discarding incoming frames with adaptive aggressiveness based on
156
* actual burst level.
158
#define PROGRESSIVE_DISCARD 1
160
/* Internal JB frame flag, discarded frame will not be returned by JB to
161
* application, it's just simply discarded.
163
#define PJMEDIA_JB_DISCARDED_FRAME 1024
167
/* Enabling this would log the jitter buffer state about once per
171
# define TRACE__(args) PJ_LOG(5,args)
173
# define TRACE__(args)
176
static pj_status_t jb_framelist_reset(jb_framelist_t *framelist);
177
static unsigned jb_framelist_remove_head(jb_framelist_t *framelist,
180
static pj_status_t jb_framelist_init( pj_pool_t *pool,
181
jb_framelist_t *framelist,
185
PJ_ASSERT_RETURN(pool && framelist, PJ_EINVAL);
187
pj_bzero(framelist, sizeof(jb_framelist_t));
189
framelist->frame_size = frame_size;
190
framelist->max_count = max_count;
191
framelist->content = (char*)
193
framelist->frame_size*
194
framelist->max_count);
195
framelist->frame_type = (int*)
197
sizeof(framelist->frame_type[0])*
198
framelist->max_count);
199
framelist->content_len = (pj_size_t*)
201
sizeof(framelist->content_len[0])*
202
framelist->max_count);
203
framelist->bit_info = (pj_uint32_t*)
205
sizeof(framelist->bit_info[0])*
206
framelist->max_count);
207
framelist->ts = (pj_uint32_t*)
209
sizeof(framelist->ts[0])*
210
framelist->max_count);
212
return jb_framelist_reset(framelist);
216
static pj_status_t jb_framelist_destroy(jb_framelist_t *framelist)
218
PJ_UNUSED_ARG(framelist);
222
static pj_status_t jb_framelist_reset(jb_framelist_t *framelist)
225
framelist->origin = INVALID_OFFSET;
227
framelist->discarded_num = 0;
230
//pj_bzero(framelist->content,
231
// framelist->frame_size *
232
// framelist->max_count);
234
pj_memset(framelist->frame_type,
235
PJMEDIA_JB_MISSING_FRAME,
236
sizeof(framelist->frame_type[0]) *
237
framelist->max_count);
239
pj_bzero(framelist->content_len,
240
sizeof(framelist->content_len[0]) *
241
framelist->max_count);
243
//pj_bzero(framelist->bit_info,
244
// sizeof(framelist->bit_info[0]) *
245
// framelist->max_count);
251
static unsigned jb_framelist_size(const jb_framelist_t *framelist)
253
return framelist->size;
257
static unsigned jb_framelist_eff_size(const jb_framelist_t *framelist)
259
return (framelist->size - framelist->discarded_num);
262
static int jb_framelist_origin(const jb_framelist_t *framelist)
264
return framelist->origin;
268
static pj_bool_t jb_framelist_get(jb_framelist_t *framelist,
269
void *frame, pj_size_t *size,
270
pjmedia_jb_frame_type *p_type,
271
pj_uint32_t *bit_info,
275
if (framelist->size) {
276
pj_bool_t prev_discarded = PJ_FALSE;
278
/* Skip discarded frames */
279
while (framelist->frame_type[framelist->head] ==
280
PJMEDIA_JB_DISCARDED_FRAME)
282
jb_framelist_remove_head(framelist, 1);
283
prev_discarded = PJ_TRUE;
286
/* Return the head frame if any */
287
if (framelist->size) {
288
if (prev_discarded) {
289
/* Ticket #1188: when previous frame(s) was discarded, return
290
* 'missing' frame to trigger PLC to get smoother signal.
292
*p_type = PJMEDIA_JB_MISSING_FRAME;
300
framelist->head * framelist->frame_size,
301
framelist->frame_size);
302
*p_type = (pjmedia_jb_frame_type)
303
framelist->frame_type[framelist->head];
305
*size = framelist->content_len[framelist->head];
307
*bit_info = framelist->bit_info[framelist->head];
310
*ts = framelist->ts[framelist->head];
312
*seq = framelist->origin;
314
//pj_bzero(framelist->content +
315
// framelist->head * framelist->frame_size,
316
// framelist->frame_size);
317
framelist->frame_type[framelist->head] = PJMEDIA_JB_MISSING_FRAME;
318
framelist->content_len[framelist->head] = 0;
319
framelist->bit_info[framelist->head] = 0;
320
framelist->ts[framelist->head] = 0;
323
framelist->head = (framelist->head + 1) % framelist->max_count;
330
/* No frame available */
331
pj_bzero(frame, framelist->frame_size);
337
static pj_bool_t jb_framelist_peek(jb_framelist_t *framelist,
341
pjmedia_jb_frame_type *type,
342
pj_uint32_t *bit_info,
348
if (offset >= jb_framelist_eff_size(framelist))
351
pos = framelist->head;
354
/* Find actual peek position, note there may be discarded frames */
356
if (framelist->frame_type[pos] != PJMEDIA_JB_DISCARDED_FRAME) {
362
pos = (pos + 1) % framelist->max_count;
365
/* Return the frame pointer */
367
*frame = framelist->content + pos*framelist->frame_size;
369
*type = (pjmedia_jb_frame_type)
370
framelist->frame_type[pos];
372
*size = framelist->content_len[pos];
374
*bit_info = framelist->bit_info[pos];
376
*ts = framelist->ts[pos];
378
*seq = framelist->origin + offset;
384
/* Remove oldest frames as many as param 'count' */
385
static unsigned jb_framelist_remove_head(jb_framelist_t *framelist,
388
if (count > framelist->size)
389
count = framelist->size;
392
/* may be done in two steps if overlapping */
393
unsigned step1,step2;
394
unsigned tmp = framelist->head+count;
397
if (tmp > framelist->max_count) {
398
step1 = framelist->max_count - framelist->head;
405
for (i = framelist->head; i < (framelist->head + step1); ++i) {
406
if (framelist->frame_type[i] == PJMEDIA_JB_DISCARDED_FRAME) {
407
pj_assert(framelist->discarded_num > 0);
408
framelist->discarded_num--;
412
//pj_bzero(framelist->content +
413
// framelist->head * framelist->frame_size,
414
// step1*framelist->frame_size);
415
pj_memset(framelist->frame_type+framelist->head,
416
PJMEDIA_JB_MISSING_FRAME,
417
step1*sizeof(framelist->frame_type[0]));
418
pj_bzero(framelist->content_len+framelist->head,
419
step1*sizeof(framelist->content_len[0]));
422
for (i = 0; i < step2; ++i) {
423
if (framelist->frame_type[i] == PJMEDIA_JB_DISCARDED_FRAME) {
424
pj_assert(framelist->discarded_num > 0);
425
framelist->discarded_num--;
428
//pj_bzero( framelist->content,
429
// step2*framelist->frame_size);
430
pj_memset(framelist->frame_type,
431
PJMEDIA_JB_MISSING_FRAME,
432
step2*sizeof(framelist->frame_type[0]));
433
pj_bzero (framelist->content_len,
434
step2*sizeof(framelist->content_len[0]));
438
framelist->origin += count;
439
framelist->head = (framelist->head + count) % framelist->max_count;
440
framelist->size -= count;
447
static pj_status_t jb_framelist_put_at(jb_framelist_t *framelist,
451
pj_uint32_t bit_info,
457
enum { MAX_MISORDER = 100 };
458
enum { MAX_DROPOUT = 3000 };
460
PJ_ASSERT_RETURN(frame_size <= framelist->frame_size, PJ_EINVAL);
462
/* too late or sequence restart */
463
if (index < framelist->origin) {
464
if (framelist->origin - index < MAX_MISORDER) {
468
/* sequence restart */
469
framelist->origin = index - framelist->size;
473
/* if jbuf is empty, just reset the origin */
474
if (framelist->size == 0) {
475
pj_assert(framelist->discarded_num == 0);
476
framelist->origin = index;
479
/* get distance of this frame to the first frame in the buffer */
480
distance = index - framelist->origin;
482
/* far jump, the distance is greater than buffer capacity */
483
if (distance >= (int)framelist->max_count) {
484
if (distance > MAX_DROPOUT) {
485
/* jump too far, reset the buffer */
486
jb_framelist_reset(framelist);
487
framelist->origin = index;
490
/* otherwise, reject the frame */
495
/* get the slot position */
496
pos = (framelist->head + distance) % framelist->max_count;
498
/* if the slot is occupied, it must be duplicated frame, ignore it. */
499
if (framelist->frame_type[pos] != PJMEDIA_JB_MISSING_FRAME)
502
/* put the frame into the slot */
503
framelist->frame_type[pos] = frame_type;
504
framelist->content_len[pos] = frame_size;
505
framelist->bit_info[pos] = bit_info;
506
framelist->ts[pos] = ts;
508
/* update framelist size */
509
if (framelist->origin + (int)framelist->size <= index)
510
framelist->size = distance + 1;
512
if(PJMEDIA_JB_NORMAL_FRAME == frame_type) {
513
/* copy frame content */
514
pj_memcpy(framelist->content + pos * framelist->frame_size,
522
static pj_status_t jb_framelist_discard(jb_framelist_t *framelist,
527
PJ_ASSERT_RETURN(index >= framelist->origin &&
528
index < framelist->origin + (int)framelist->size,
531
/* Get the slot position */
532
pos = (framelist->head + (index - framelist->origin)) %
533
framelist->max_count;
535
/* Discard the frame */
536
framelist->frame_type[pos] = PJMEDIA_JB_DISCARDED_FRAME;
537
framelist->discarded_num++;
551
PJ_DEF(pj_status_t) pjmedia_jbuf_create(pj_pool_t *pool,
552
const pj_str_t *name,
561
jb = PJ_POOL_ZALLOC_T(pool, pjmedia_jbuf);
563
status = jb_framelist_init(pool, &jb->jb_framelist, frame_size, max_count);
564
if (status != PJ_SUCCESS)
567
pj_strdup_with_null(pool, &jb->jb_name, name);
568
jb->jb_frame_size = frame_size;
569
jb->jb_frame_ptime = ptime;
570
jb->jb_prefetch = PJ_MIN(PJMEDIA_JB_DEFAULT_INIT_DELAY,max_count*4/5);
571
jb->jb_min_prefetch = 0;
572
jb->jb_max_prefetch = max_count*4/5;
573
jb->jb_max_count = max_count;
574
jb->jb_min_shrink_gap= PJMEDIA_JBUF_DISC_MIN_GAP / ptime;
575
jb->jb_max_burst = PJ_MAX(MAX_BURST_MSEC / ptime, max_count*3/4);
577
pj_math_stat_init(&jb->jb_delay);
578
pj_math_stat_init(&jb->jb_burst);
580
pjmedia_jbuf_set_discard(jb, PJMEDIA_JB_DISCARD_PROGRESSIVE);
581
pjmedia_jbuf_reset(jb);
589
* Set the jitter buffer to fixed delay mode. The default behavior
590
* is to adapt the delay with actual packet delay.
593
PJ_DEF(pj_status_t) pjmedia_jbuf_set_fixed( pjmedia_jbuf *jb,
596
PJ_ASSERT_RETURN(jb, PJ_EINVAL);
597
PJ_ASSERT_RETURN(prefetch <= jb->jb_max_count, PJ_EINVAL);
599
jb->jb_min_prefetch = jb->jb_max_prefetch =
600
jb->jb_prefetch = jb->jb_init_prefetch = prefetch;
602
pjmedia_jbuf_set_discard(jb, PJMEDIA_JB_DISCARD_NONE);
608
* Set the jitter buffer to adaptive mode.
610
PJ_DEF(pj_status_t) pjmedia_jbuf_set_adaptive( pjmedia_jbuf *jb,
612
unsigned min_prefetch,
613
unsigned max_prefetch)
615
PJ_ASSERT_RETURN(jb, PJ_EINVAL);
616
PJ_ASSERT_RETURN(min_prefetch <= max_prefetch &&
617
prefetch <= max_prefetch &&
618
max_prefetch <= jb->jb_max_count,
621
jb->jb_prefetch = jb->jb_init_prefetch = prefetch;
622
jb->jb_min_prefetch = min_prefetch;
623
jb->jb_max_prefetch = max_prefetch;
629
PJ_DEF(pj_status_t) pjmedia_jbuf_set_discard( pjmedia_jbuf *jb,
630
pjmedia_jb_discard_algo algo)
632
PJ_ASSERT_RETURN(jb, PJ_EINVAL);
633
PJ_ASSERT_RETURN(algo >= PJMEDIA_JB_DISCARD_NONE &&
634
algo <= PJMEDIA_JB_DISCARD_PROGRESSIVE,
638
case PJMEDIA_JB_DISCARD_PROGRESSIVE:
639
jb->jb_discard_algo = &jbuf_discard_progressive;
641
case PJMEDIA_JB_DISCARD_STATIC:
642
jb->jb_discard_algo = &jbuf_discard_static;
645
jb->jb_discard_algo = NULL;
653
PJ_DEF(pj_status_t) pjmedia_jbuf_reset(pjmedia_jbuf *jb)
656
jb->jb_last_op = JB_OP_INIT;
657
jb->jb_stable_hist = 0;
658
jb->jb_status = JB_STATUS_INITIALIZING;
659
jb->jb_init_cycle_cnt= 0;
660
jb->jb_max_hist_level= 0;
661
jb->jb_prefetching = (jb->jb_prefetch != 0);
662
jb->jb_discard_dist = 0;
664
jb_framelist_reset(&jb->jb_framelist);
670
PJ_DEF(pj_status_t) pjmedia_jbuf_destroy(pjmedia_jbuf *jb)
672
PJ_LOG(5, (jb->jb_name.ptr, ""
674
" size=%d/eff=%d prefetch=%d level=%d\n"
675
" delay (min/max/avg/dev)=%d/%d/%d/%d ms\n"
676
" burst (min/max/avg/dev)=%d/%d/%d/%d frames\n"
677
" lost=%d discard=%d empty=%d",
678
jb_framelist_size(&jb->jb_framelist),
679
jb_framelist_eff_size(&jb->jb_framelist),
680
jb->jb_prefetch, jb->jb_eff_level,
681
jb->jb_delay.min, jb->jb_delay.max, jb->jb_delay.mean,
682
pj_math_stat_get_stddev(&jb->jb_delay),
683
jb->jb_burst.min, jb->jb_burst.max, jb->jb_burst.mean,
684
pj_math_stat_get_stddev(&jb->jb_burst),
685
jb->jb_lost, jb->jb_discard, jb->jb_empty));
687
return jb_framelist_destroy(&jb->jb_framelist);
690
PJ_DEF(pj_bool_t) pjmedia_jbuf_is_full(const pjmedia_jbuf *jb)
692
return jb->jb_framelist.size == jb->jb_framelist.max_count;
695
static void jbuf_calculate_jitter(pjmedia_jbuf *jb)
699
cur_size = jb_framelist_eff_size(&jb->jb_framelist);
700
pj_math_stat_update(&jb->jb_burst, jb->jb_level);
701
jb->jb_max_hist_level = PJ_MAX(jb->jb_max_hist_level, jb->jb_level);
703
/* Burst level is decreasing */
704
if (jb->jb_level < jb->jb_eff_level) {
706
enum { STABLE_HISTORY_LIMIT = 20 };
708
jb->jb_stable_hist++;
710
/* Only update the effective level (and prefetch) if 'stable'
711
* condition is reached (not just short time impulse)
713
if (jb->jb_stable_hist > STABLE_HISTORY_LIMIT) {
715
diff = (jb->jb_eff_level - jb->jb_max_hist_level) / 3;
720
/* Update effective burst level */
721
jb->jb_eff_level -= diff;
723
/* Update prefetch based on level */
724
if (jb->jb_init_prefetch) {
725
jb->jb_prefetch = jb->jb_eff_level;
726
if (jb->jb_prefetch < jb->jb_min_prefetch)
727
jb->jb_prefetch = jb->jb_min_prefetch;
728
if (jb->jb_prefetch > jb->jb_max_prefetch)
729
jb->jb_prefetch = jb->jb_max_prefetch;
733
jb->jb_max_hist_level = 0;
734
jb->jb_stable_hist = 0;
736
TRACE__((jb->jb_name.ptr,"jb updated(1), lvl=%d pre=%d, size=%d",
737
jb->jb_eff_level, jb->jb_prefetch, cur_size));
738
PJ_UNUSED_ARG(cur_size); /* Warning about unused var */
742
/* Burst level is increasing */
743
else if (jb->jb_level > jb->jb_eff_level) {
745
/* Instaneous set effective burst level to recent maximum level */
746
jb->jb_eff_level = PJ_MIN(jb->jb_max_hist_level,
747
(int)(jb->jb_max_count*4/5));
749
/* Update prefetch based on level */
750
if (jb->jb_init_prefetch) {
751
jb->jb_prefetch = jb->jb_eff_level;
752
if (jb->jb_prefetch > jb->jb_max_prefetch)
753
jb->jb_prefetch = jb->jb_max_prefetch;
754
if (jb->jb_prefetch < jb->jb_min_prefetch)
755
jb->jb_prefetch = jb->jb_min_prefetch;
758
jb->jb_stable_hist = 0;
759
/* Do not reset max_hist_level. */
760
//jb->jb_max_hist_level = 0;
762
TRACE__((jb->jb_name.ptr,"jb updated(2), lvl=%d pre=%d, size=%d",
763
jb->jb_eff_level, jb->jb_prefetch, cur_size));
766
/* Level is unchanged */
768
jb->jb_stable_hist = 0;
773
static void jbuf_discard_static(pjmedia_jbuf *jb)
775
/* These code is used for shortening the delay in the jitter buffer.
776
* It needs shrink only when there is possibility of drift. Drift
777
* detection is performed by inspecting the jitter buffer size, if
778
* its size is twice of current burst level, there can be drift.
780
* Moreover, normally drift level is quite low, so JB shouldn't need
781
* to shrink aggresively, it will shrink maximum one frame per
782
* PJMEDIA_JBUF_DISC_MIN_GAP ms. Theoritically, JB may handle drift level
783
* as much as = FRAME_PTIME/PJMEDIA_JBUF_DISC_MIN_GAP * 100%
785
* Whenever there is drift, where PUT > GET, this method will keep
786
* the latency (JB size) as much as twice of burst level.
789
/* Shrinking due of drift will be implicitly done by progressive discard,
790
* so just disable it when progressive discard is active.
792
int diff, burst_level;
794
burst_level = PJ_MAX(jb->jb_eff_level, jb->jb_level);
795
diff = jb_framelist_eff_size(&jb->jb_framelist) - burst_level*2;
797
if (diff >= STA_DISC_SAFE_SHRINKING_DIFF) {
800
/* Check and adjust jb_discard_ref, in case there was
803
seq_origin = jb_framelist_origin(&jb->jb_framelist);
804
if (seq_origin < jb->jb_discard_ref)
805
jb->jb_discard_ref = seq_origin;
807
if (seq_origin - jb->jb_discard_ref >= jb->jb_min_shrink_gap)
809
/* Shrink slowly, one frame per cycle */
813
diff = jb_framelist_remove_head(&jb->jb_framelist, diff);
814
jb->jb_discard_ref = jb_framelist_origin(&jb->jb_framelist);
815
jb->jb_discard += diff;
817
TRACE__((jb->jb_name.ptr,
818
"JB shrinking %d frame(s), cur size=%d", diff,
819
jb_framelist_eff_size(&jb->jb_framelist)));
825
static void jbuf_discard_progressive(pjmedia_jbuf *jb)
827
unsigned cur_size, burst_level, overflow, T, discard_dist;
830
/* Should be done in PUT operation */
831
if (jb->jb_last_op != JB_OP_PUT)
834
/* Check if latency is longer than burst */
835
cur_size = jb_framelist_eff_size(&jb->jb_framelist);
836
burst_level = PJ_MAX(jb->jb_eff_level, jb->jb_level);
837
if (cur_size <= burst_level) {
838
/* Reset any scheduled discard */
839
jb->jb_discard_dist = 0;
843
/* Estimate discard duration needed for adjusting latency */
844
if (burst_level <= PJMEDIA_JBUF_PRO_DISC_MIN_BURST)
845
T = PJMEDIA_JBUF_PRO_DISC_T1;
846
else if (burst_level >= PJMEDIA_JBUF_PRO_DISC_MAX_BURST)
847
T = PJMEDIA_JBUF_PRO_DISC_T2;
849
T = PJMEDIA_JBUF_PRO_DISC_T1 +
850
(PJMEDIA_JBUF_PRO_DISC_T2 - PJMEDIA_JBUF_PRO_DISC_T1) *
851
(burst_level - PJMEDIA_JBUF_PRO_DISC_MIN_BURST) /
852
(PJMEDIA_JBUF_PRO_DISC_MAX_BURST-PJMEDIA_JBUF_PRO_DISC_MIN_BURST);
854
/* Calculate current discard distance */
855
overflow = cur_size - burst_level;
856
discard_dist = T / overflow / jb->jb_frame_ptime;
858
/* Get last seq number in the JB */
859
last_seq = jb_framelist_origin(&jb->jb_framelist) +
860
jb_framelist_size(&jb->jb_framelist) - 1;
862
/* Setup new discard schedule if none, otherwise, update the existing
863
* discard schedule (can be delayed or accelerated).
865
if (jb->jb_discard_dist == 0) {
866
/* Setup new discard schedule */
867
jb->jb_discard_ref = last_seq;
868
} else if (last_seq < jb->jb_discard_ref) {
869
/* Seq restarted, update discard reference */
870
jb->jb_discard_ref = last_seq;
872
jb->jb_discard_dist = PJ_MAX(jb->jb_min_shrink_gap, (int)discard_dist);
874
/* Check if we need to discard now */
875
if (last_seq >= (jb->jb_discard_ref + (int)jb->jb_discard_dist)) {
878
discard_seq = jb->jb_discard_ref + jb->jb_discard_dist;
879
if (discard_seq < jb_framelist_origin(&jb->jb_framelist))
880
discard_seq = jb_framelist_origin(&jb->jb_framelist);
882
jb_framelist_discard(&jb->jb_framelist, discard_seq);
884
TRACE__((jb->jb_name.ptr,
885
"Discard #%d: ref=#%d dist=%d orig=%d size=%d/%d "
890
jb_framelist_origin(&jb->jb_framelist),
892
jb_framelist_size(&jb->jb_framelist),
896
/* Update discard reference */
897
jb->jb_discard_ref = discard_seq;
902
PJ_INLINE(void) jbuf_update(pjmedia_jbuf *jb, int oper)
904
if(jb->jb_last_op != oper) {
905
jb->jb_last_op = oper;
907
if (jb->jb_status == JB_STATUS_INITIALIZING) {
908
/* Switch status 'initializing' -> 'processing' after some OP
909
* switch cycles and current OP is GET (burst level is calculated
910
* based on PUT burst), so burst calculation is guaranted to be
911
* performed right after the status switching.
913
if (++jb->jb_init_cycle_cnt >= INIT_CYCLE && oper == JB_OP_GET) {
914
jb->jb_status = JB_STATUS_PROCESSING;
915
/* To make sure the burst calculation will be done right after
916
* this, adjust burst level if it exceeds max burst level.
918
jb->jb_level = PJ_MIN(jb->jb_level, jb->jb_max_burst);
925
/* Perform jitter calculation based on PUT burst-level only, since
926
* GET burst-level may not be accurate, e.g: when VAD is active.
927
* Note that when burst-level is too big, i.e: exceeds jb_max_burst,
928
* the GET op may be idle, in this case, we better skip the jitter
931
if (oper == JB_OP_GET && jb->jb_level <= jb->jb_max_burst)
932
jbuf_calculate_jitter(jb);
937
/* Call discard algorithm */
938
if (jb->jb_status == JB_STATUS_PROCESSING && jb->jb_discard_algo) {
939
(*jb->jb_discard_algo)(jb);
943
PJ_DEF(void) pjmedia_jbuf_put_frame( pjmedia_jbuf *jb,
945
pj_size_t frame_size,
948
pjmedia_jbuf_put_frame3(jb, frame, frame_size, 0, frame_seq, 0, NULL);
951
PJ_DEF(void) pjmedia_jbuf_put_frame2(pjmedia_jbuf *jb,
953
pj_size_t frame_size,
954
pj_uint32_t bit_info,
956
pj_bool_t *discarded)
958
pjmedia_jbuf_put_frame3(jb, frame, frame_size, bit_info, frame_seq, 0,
962
PJ_DEF(void) pjmedia_jbuf_put_frame3(pjmedia_jbuf *jb,
964
pj_size_t frame_size,
965
pj_uint32_t bit_info,
968
pj_bool_t *discarded)
970
pj_size_t min_frame_size;
971
int new_size, cur_size;
974
cur_size = jb_framelist_eff_size(&jb->jb_framelist);
976
/* Attempt to store the frame */
977
min_frame_size = PJ_MIN(frame_size, jb->jb_frame_size);
978
status = jb_framelist_put_at(&jb->jb_framelist, frame_seq, frame,
979
(unsigned)min_frame_size, bit_info, ts,
980
PJMEDIA_JB_NORMAL_FRAME);
982
/* Jitter buffer is full, remove some older frames */
983
while (status == PJ_ETOOMANY) {
987
/* Remove as few as possible just to make this frame in. Note that
988
* the cases of seq-jump, out-of-order, and seq restart should have
989
* been handled/normalized by previous call of jb_framelist_put_at().
990
* So we're confident about 'distance' value here.
992
distance = (frame_seq - jb_framelist_origin(&jb->jb_framelist)) -
993
(int)jb->jb_max_count + 1;
994
pj_assert(distance > 0);
996
removed = jb_framelist_remove_head(&jb->jb_framelist, distance);
997
status = jb_framelist_put_at(&jb->jb_framelist, frame_seq, frame,
998
(unsigned)min_frame_size, bit_info, ts,
999
PJMEDIA_JB_NORMAL_FRAME);
1001
jb->jb_discard += removed;
1004
/* Get new JB size after PUT */
1005
new_size = jb_framelist_eff_size(&jb->jb_framelist);
1007
/* Return the flag if this frame is discarded */
1009
*discarded = (status != PJ_SUCCESS);
1011
if (status == PJ_SUCCESS) {
1012
if (jb->jb_prefetching) {
1013
TRACE__((jb->jb_name.ptr, "PUT prefetch_cnt=%d/%d",
1014
new_size, jb->jb_prefetch));
1015
if (new_size >= jb->jb_prefetch)
1016
jb->jb_prefetching = PJ_FALSE;
1018
jb->jb_level += (new_size > cur_size ? new_size-cur_size : 1);
1019
jbuf_update(jb, JB_OP_PUT);
1025
* Get frame from jitter buffer.
1027
PJ_DEF(void) pjmedia_jbuf_get_frame( pjmedia_jbuf *jb,
1031
pjmedia_jbuf_get_frame3(jb, frame, NULL, p_frame_type, NULL,
1036
* Get frame from jitter buffer.
1038
PJ_DEF(void) pjmedia_jbuf_get_frame2(pjmedia_jbuf *jb,
1042
pj_uint32_t *bit_info)
1044
pjmedia_jbuf_get_frame3(jb, frame, size, p_frame_type, bit_info,
1049
* Get frame from jitter buffer.
1051
PJ_DEF(void) pjmedia_jbuf_get_frame3(pjmedia_jbuf *jb,
1055
pj_uint32_t *bit_info,
1059
if (jb->jb_prefetching) {
1061
/* Can't return frame because jitter buffer is filling up
1065
//pj_bzero(frame, jb->jb_frame_size);
1066
*p_frame_type = PJMEDIA_JB_ZERO_PREFETCH_FRAME;
1070
TRACE__((jb->jb_name.ptr, "GET prefetch_cnt=%d/%d",
1071
jb_framelist_eff_size(&jb->jb_framelist), jb->jb_prefetch));
1077
pjmedia_jb_frame_type ftype = PJMEDIA_JB_NORMAL_FRAME;
1080
/* Try to retrieve a frame from frame list */
1081
res = jb_framelist_get(&jb->jb_framelist, frame, size, &ftype,
1084
/* We've successfully retrieved a frame from the frame list, but
1085
* the frame could be a blank frame!
1087
if (ftype == PJMEDIA_JB_NORMAL_FRAME) {
1088
*p_frame_type = PJMEDIA_JB_NORMAL_FRAME;
1090
*p_frame_type = PJMEDIA_JB_MISSING_FRAME;
1094
/* Store delay history at the first GET */
1095
if (jb->jb_last_op == JB_OP_PUT) {
1098
/* We've just retrieved one frame, so add one to cur_size */
1099
cur_size = jb_framelist_eff_size(&jb->jb_framelist) + 1;
1100
pj_math_stat_update(&jb->jb_delay,
1101
cur_size*jb->jb_frame_ptime);
1104
/* Jitter buffer is empty */
1105
if (jb->jb_prefetch)
1106
jb->jb_prefetching = PJ_TRUE;
1108
//pj_bzero(frame, jb->jb_frame_size);
1109
*p_frame_type = PJMEDIA_JB_ZERO_EMPTY_FRAME;
1118
jbuf_update(jb, JB_OP_GET);
1122
* Get jitter buffer state.
1124
PJ_DEF(pj_status_t) pjmedia_jbuf_get_state( const pjmedia_jbuf *jb,
1125
pjmedia_jb_state *state )
1127
PJ_ASSERT_RETURN(jb && state, PJ_EINVAL);
1129
state->frame_size = (unsigned)jb->jb_frame_size;
1130
state->min_prefetch = jb->jb_min_prefetch;
1131
state->max_prefetch = jb->jb_max_prefetch;
1133
state->burst = jb->jb_eff_level;
1134
state->prefetch = jb->jb_prefetch;
1135
state->size = jb_framelist_eff_size(&jb->jb_framelist);
1137
state->avg_delay = jb->jb_delay.mean;
1138
state->min_delay = jb->jb_delay.min;
1139
state->max_delay = jb->jb_delay.max;
1140
state->dev_delay = pj_math_stat_get_stddev(&jb->jb_delay);
1142
state->avg_burst = jb->jb_burst.mean;
1143
state->empty = jb->jb_empty;
1144
state->discard = jb->jb_discard;
1145
state->lost = jb->jb_lost;
1151
PJ_DEF(void) pjmedia_jbuf_peek_frame( pjmedia_jbuf *jb,
1156
pj_uint32_t *bit_info,
1160
pjmedia_jb_frame_type ftype;
1163
res = jb_framelist_peek(&jb->jb_framelist, offset, frame, size, &ftype,
1166
*p_frm_type = PJMEDIA_JB_ZERO_EMPTY_FRAME;
1167
else if (ftype == PJMEDIA_JB_NORMAL_FRAME)
1168
*p_frm_type = PJMEDIA_JB_NORMAL_FRAME;
1170
*p_frm_type = PJMEDIA_JB_MISSING_FRAME;
1174
PJ_DEF(unsigned) pjmedia_jbuf_remove_frame(pjmedia_jbuf *jb,
1177
unsigned count, last_discard_num;
1179
last_discard_num = jb->jb_framelist.discarded_num;
1180
count = jb_framelist_remove_head(&jb->jb_framelist, frame_cnt);
1182
/* Remove some more when there were discarded frames included */
1183
while (jb->jb_framelist.discarded_num < last_discard_num) {
1184
/* Calculate frames count to be removed next */
1185
frame_cnt = last_discard_num - jb->jb_framelist.discarded_num;
1187
/* Normalize non-discarded frames count just been removed */
1190
/* Remove more frames */
1191
last_discard_num = jb->jb_framelist.discarded_num;
1192
count += jb_framelist_remove_head(&jb->jb_framelist, frame_cnt);