1
/* $Id: jbuf.c 3553 2011-05-05 06:14:19Z nanang $ */
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
/* Minimal difference between JB size and 2*burst-level to perform
38
#define SAFE_SHRINKING_DIFF 1
40
/* Minimal gap (in ms) between JB shrinking */
41
#define MIN_SHRINK_GAP_MSEC 200
43
/* Invalid sequence number, used as the initial value. */
44
#define INVALID_OFFSET -9999
46
/* Maximum burst length, whenever an operation is bursting longer than
47
* this value, JB will assume that the opposite operation was idle.
49
#define MAX_BURST_MSEC 1000
51
/* Number of OP switches to be performed in JB_STATUS_INITIALIZING, before
52
* JB can switch its states to JB_STATUS_PROCESSING.
57
/* Struct of JB internal buffer, represented in a circular buffer containing
58
* frame content, frame type, frame length, and frame bit info.
60
typedef struct jb_framelist_t
63
unsigned frame_size; /**< maximum size of frame */
64
unsigned max_count; /**< maximum number of frames */
67
char *content; /**< frame content array */
68
int *frame_type; /**< frame type array */
69
pj_size_t *content_len; /**< frame length array */
70
pj_uint32_t *bit_info; /**< frame bit info array */
73
unsigned head; /**< index of head, pointed frame
74
will be returned by next GET */
75
unsigned size; /**< current size of framelist,
76
including discarded frames. */
77
unsigned discarded_num; /**< current number of discarded
79
int origin; /**< original index of flist_head */
86
/* Settings (consts) */
87
pj_str_t jb_name; /**< jitter buffer name */
88
pj_size_t jb_frame_size; /**< frame size */
89
unsigned jb_frame_ptime; /**< frame duration. */
90
pj_size_t jb_max_count; /**< capacity of jitter buffer,
92
int jb_init_prefetch; /**< Initial prefetch */
93
int jb_min_prefetch; /**< Minimum allowable prefetch */
94
int jb_max_prefetch; /**< Maximum allowable prefetch */
95
int jb_max_burst; /**< maximum possible burst, whenever
96
burst exceeds this value, it
97
won't be included in level
99
int jb_min_shrink_gap; /**< How often can we shrink */
102
jb_framelist_t jb_framelist; /**< the buffer */
105
int jb_level; /**< delay between source &
106
destination (calculated according
107
of the number of burst get/put
109
int jb_max_hist_level; /**< max level during the last level
111
int jb_stable_hist; /**< num of times the delay has been
112
lower then the prefetch num */
113
int jb_last_op; /**< last operation executed
115
int jb_eff_level; /**< effective burst level */
116
int jb_prefetch; /**< no. of frame to insert before
117
removing some (at the beginning
118
of the framelist->content
119
operation), the value may be
120
continuously updated based on
121
current frame burst level. */
122
int jb_status; /**< status is 'init' until the first
124
int jb_init_cycle_cnt; /**< status is 'init' until the first
126
int jb_last_del_seq; /**< Seq # of last frame deleted */
128
int jb_last_discard_seq;/**< Seq # of last frame discarded */
131
pj_math_stat jb_delay; /**< Delay statistics of jitter buffer
133
pj_math_stat jb_burst; /**< Burst statistics (in frames) */
134
unsigned jb_lost; /**< Number of lost frames. */
135
unsigned jb_discard; /**< Number of discarded frames. */
136
unsigned jb_empty; /**< Number of empty/prefetching frame
141
#define JB_STATUS_INITIALIZING 0
142
#define JB_STATUS_PROCESSING 1
143
#define JB_STATUS_PREFETCHING 2
147
/* Progressive discard algorithm introduced to reduce JB latency
148
* by discarding incoming frames with adaptive aggressiveness based on
149
* actual burst level.
151
#define PROGRESSIVE_DISCARD 1
153
/* Internal JB frame flag, discarded frame will not be returned by JB to
154
* application, it's just simply discarded.
156
#define PJMEDIA_JB_DISCARDED_FRAME 1024
160
/* Enabling this would log the jitter buffer state about once per
164
# define TRACE__(args) PJ_LOG(5,args)
166
# define TRACE__(args)
169
static pj_status_t jb_framelist_reset(jb_framelist_t *framelist);
170
static unsigned jb_framelist_remove_head(jb_framelist_t *framelist,
173
static pj_status_t jb_framelist_init( pj_pool_t *pool,
174
jb_framelist_t *framelist,
178
PJ_ASSERT_RETURN(pool && framelist, PJ_EINVAL);
180
pj_bzero(framelist, sizeof(jb_framelist_t));
182
framelist->frame_size = frame_size;
183
framelist->max_count = max_count;
184
framelist->content = (char*)
186
framelist->frame_size*
187
framelist->max_count);
188
framelist->frame_type = (int*)
190
sizeof(framelist->frame_type[0])*
191
framelist->max_count);
192
framelist->content_len = (pj_size_t*)
194
sizeof(framelist->content_len[0])*
195
framelist->max_count);
196
framelist->bit_info = (pj_uint32_t*)
198
sizeof(framelist->bit_info[0])*
199
framelist->max_count);
202
return jb_framelist_reset(framelist);
206
static pj_status_t jb_framelist_destroy(jb_framelist_t *framelist)
208
PJ_UNUSED_ARG(framelist);
212
static pj_status_t jb_framelist_reset(jb_framelist_t *framelist)
215
framelist->origin = INVALID_OFFSET;
217
framelist->discarded_num = 0;
220
//pj_bzero(framelist->content,
221
// framelist->frame_size *
222
// framelist->max_count);
224
pj_memset(framelist->frame_type,
225
PJMEDIA_JB_MISSING_FRAME,
226
sizeof(framelist->frame_type[0]) *
227
framelist->max_count);
229
pj_bzero(framelist->content_len,
230
sizeof(framelist->content_len[0]) *
231
framelist->max_count);
233
//pj_bzero(framelist->bit_info,
234
// sizeof(framelist->bit_info[0]) *
235
// framelist->max_count);
241
static unsigned jb_framelist_size(const jb_framelist_t *framelist)
243
return framelist->size;
247
static unsigned jb_framelist_eff_size(const jb_framelist_t *framelist)
249
return (framelist->size - framelist->discarded_num);
252
static int jb_framelist_origin(const jb_framelist_t *framelist)
254
return framelist->origin;
258
static pj_bool_t jb_framelist_get(jb_framelist_t *framelist,
259
void *frame, pj_size_t *size,
260
pjmedia_jb_frame_type *p_type,
261
pj_uint32_t *bit_info)
263
if (framelist->size) {
264
pj_bool_t prev_discarded = PJ_FALSE;
266
/* Skip discarded frames */
267
while (framelist->frame_type[framelist->head] ==
268
PJMEDIA_JB_DISCARDED_FRAME)
270
jb_framelist_remove_head(framelist, 1);
271
prev_discarded = PJ_TRUE;
274
/* Return the head frame if any */
275
if (framelist->size) {
276
if (prev_discarded) {
277
/* Ticket #1188: when previous frame(s) was discarded, return
278
* 'missing' frame to trigger PLC to get smoother signal.
280
*p_type = PJMEDIA_JB_MISSING_FRAME;
288
framelist->head * framelist->frame_size,
289
framelist->frame_size);
290
*p_type = (pjmedia_jb_frame_type)
291
framelist->frame_type[framelist->head];
293
*size = framelist->content_len[framelist->head];
295
*bit_info = framelist->bit_info[framelist->head];
298
//pj_bzero(framelist->content +
299
// framelist->head * framelist->frame_size,
300
// framelist->frame_size);
301
framelist->frame_type[framelist->head] = PJMEDIA_JB_MISSING_FRAME;
302
framelist->content_len[framelist->head] = 0;
303
framelist->bit_info[framelist->head] = 0;
306
framelist->head = (framelist->head + 1) % framelist->max_count;
313
/* No frame available */
314
pj_bzero(frame, framelist->frame_size);
320
/* Remove oldest frames as many as param 'count' */
321
static unsigned jb_framelist_remove_head(jb_framelist_t *framelist,
324
if (count > framelist->size)
325
count = framelist->size;
328
/* may be done in two steps if overlapping */
329
unsigned step1,step2;
330
unsigned tmp = framelist->head+count;
333
if (tmp > framelist->max_count) {
334
step1 = framelist->max_count - framelist->head;
341
for (i = framelist->head; i < (framelist->head + step1); ++i) {
342
if (framelist->frame_type[i] == PJMEDIA_JB_DISCARDED_FRAME) {
343
pj_assert(framelist->discarded_num > 0);
344
framelist->discarded_num--;
348
//pj_bzero(framelist->content +
349
// framelist->head * framelist->frame_size,
350
// step1*framelist->frame_size);
351
pj_memset(framelist->frame_type+framelist->head,
352
PJMEDIA_JB_MISSING_FRAME,
353
step1*sizeof(framelist->frame_type[0]));
354
pj_bzero(framelist->content_len+framelist->head,
355
step1*sizeof(framelist->content_len[0]));
358
for (i = 0; i < step2; ++i) {
359
if (framelist->frame_type[i] == PJMEDIA_JB_DISCARDED_FRAME) {
360
pj_assert(framelist->discarded_num > 0);
361
framelist->discarded_num--;
364
//pj_bzero( framelist->content,
365
// step2*framelist->frame_size);
366
pj_memset(framelist->frame_type,
367
PJMEDIA_JB_MISSING_FRAME,
368
step2*sizeof(framelist->frame_type[0]));
369
pj_bzero (framelist->content_len,
370
step2*sizeof(framelist->content_len[0]));
374
framelist->origin += count;
375
framelist->head = (framelist->head + count) % framelist->max_count;
376
framelist->size -= count;
383
static pj_status_t jb_framelist_put_at(jb_framelist_t *framelist,
387
pj_uint32_t bit_info,
392
enum { MAX_MISORDER = 100 };
393
enum { MAX_DROPOUT = 3000 };
395
assert(frame_size <= framelist->frame_size);
397
/* too late or sequence restart */
398
if (index < framelist->origin) {
399
if (framelist->origin - index < MAX_MISORDER) {
403
/* sequence restart */
404
framelist->origin = index - framelist->size;
408
/* if jbuf is empty, just reset the origin */
409
if (framelist->size == 0) {
410
pj_assert(framelist->discarded_num == 0);
411
framelist->origin = index;
414
/* get distance of this frame to the first frame in the buffer */
415
distance = index - framelist->origin;
417
/* far jump, the distance is greater than buffer capacity */
418
if (distance >= (int)framelist->max_count) {
419
if (distance > MAX_DROPOUT) {
420
/* jump too far, reset the buffer */
421
jb_framelist_reset(framelist);
422
framelist->origin = index;
425
/* otherwise, reject the frame */
430
/* get the slot position */
431
pos = (framelist->head + distance) % framelist->max_count;
433
/* if the slot is occupied, it must be duplicated frame, ignore it. */
434
if (framelist->frame_type[pos] != PJMEDIA_JB_MISSING_FRAME)
437
/* put the frame into the slot */
438
framelist->frame_type[pos] = frame_type;
439
framelist->content_len[pos] = frame_size;
440
framelist->bit_info[pos] = bit_info;
442
/* update framelist size */
443
if (framelist->origin + (int)framelist->size <= index)
444
framelist->size = distance + 1;
446
if(PJMEDIA_JB_NORMAL_FRAME == frame_type) {
447
/* copy frame content */
448
pj_memcpy(framelist->content + pos * framelist->frame_size,
452
/* frame is being discarded */
453
framelist->discarded_num++;
468
PJ_DEF(pj_status_t) pjmedia_jbuf_create(pj_pool_t *pool,
469
const pj_str_t *name,
478
jb = PJ_POOL_ZALLOC_T(pool, pjmedia_jbuf);
480
status = jb_framelist_init(pool, &jb->jb_framelist, frame_size, max_count);
481
if (status != PJ_SUCCESS)
484
pj_strdup_with_null(pool, &jb->jb_name, name);
485
jb->jb_frame_size = frame_size;
486
jb->jb_frame_ptime = ptime;
487
jb->jb_prefetch = PJ_MIN(PJMEDIA_JB_DEFAULT_INIT_DELAY,max_count*4/5);
488
jb->jb_min_prefetch = 0;
489
jb->jb_max_prefetch = max_count*4/5;
490
jb->jb_max_count = max_count;
491
jb->jb_min_shrink_gap= MIN_SHRINK_GAP_MSEC / ptime;
492
jb->jb_max_burst = PJ_MAX(MAX_BURST_MSEC / ptime, max_count*3/4);
493
jb->jb_last_discard_seq = 0;
495
pj_math_stat_init(&jb->jb_delay);
496
pj_math_stat_init(&jb->jb_burst);
498
pjmedia_jbuf_reset(jb);
506
* Set the jitter buffer to fixed delay mode. The default behavior
507
* is to adapt the delay with actual packet delay.
510
PJ_DEF(pj_status_t) pjmedia_jbuf_set_fixed( pjmedia_jbuf *jb,
513
PJ_ASSERT_RETURN(jb, PJ_EINVAL);
514
PJ_ASSERT_RETURN(prefetch <= jb->jb_max_count, PJ_EINVAL);
516
jb->jb_min_prefetch = jb->jb_max_prefetch =
517
jb->jb_prefetch = jb->jb_init_prefetch = prefetch;
524
* Set the jitter buffer to adaptive mode.
526
PJ_DEF(pj_status_t) pjmedia_jbuf_set_adaptive( pjmedia_jbuf *jb,
528
unsigned min_prefetch,
529
unsigned max_prefetch)
531
PJ_ASSERT_RETURN(jb, PJ_EINVAL);
532
PJ_ASSERT_RETURN(min_prefetch < max_prefetch &&
533
prefetch <= max_prefetch &&
534
max_prefetch <= jb->jb_max_count,
537
jb->jb_prefetch = jb->jb_init_prefetch = prefetch;
538
jb->jb_min_prefetch = min_prefetch;
539
jb->jb_max_prefetch = max_prefetch;
545
PJ_DEF(pj_status_t) pjmedia_jbuf_reset(pjmedia_jbuf *jb)
548
jb->jb_last_op = JB_OP_INIT;
549
jb->jb_stable_hist = 0;
550
jb->jb_status = JB_STATUS_INITIALIZING;
551
jb->jb_init_cycle_cnt= 0;
552
jb->jb_max_hist_level= 0;
554
jb_framelist_reset(&jb->jb_framelist);
560
PJ_DEF(pj_status_t) pjmedia_jbuf_destroy(pjmedia_jbuf *jb)
562
PJ_LOG(5, (jb->jb_name.ptr, ""
564
" size=%d prefetch=%d level=%d\n"
565
" delay (min/max/avg/dev)=%d/%d/%d/%d ms\n"
566
" burst (min/max/avg/dev)=%d/%d/%d/%d frames\n"
567
" lost=%d discard=%d empty=%d",
568
jb->jb_framelist.size, jb->jb_prefetch, jb->jb_eff_level,
569
jb->jb_delay.min, jb->jb_delay.max, jb->jb_delay.mean,
570
pj_math_stat_get_stddev(&jb->jb_delay),
571
jb->jb_burst.min, jb->jb_burst.max, jb->jb_burst.mean,
572
pj_math_stat_get_stddev(&jb->jb_burst),
573
jb->jb_lost, jb->jb_discard, jb->jb_empty));
575
return jb_framelist_destroy(&jb->jb_framelist);
579
static void jbuf_calculate_jitter(pjmedia_jbuf *jb)
583
cur_size = jb_framelist_eff_size(&jb->jb_framelist);
584
pj_math_stat_update(&jb->jb_burst, jb->jb_level);
585
jb->jb_max_hist_level = PJ_MAX(jb->jb_max_hist_level, jb->jb_level);
587
/* Burst level is decreasing */
588
if (jb->jb_level < jb->jb_eff_level) {
590
enum { STABLE_HISTORY_LIMIT = 20 };
592
jb->jb_stable_hist++;
594
/* Only update the effective level (and prefetch) if 'stable'
595
* condition is reached (not just short time impulse)
597
if (jb->jb_stable_hist > STABLE_HISTORY_LIMIT) {
599
diff = (jb->jb_eff_level - jb->jb_max_hist_level) / 3;
604
/* Update effective burst level */
605
jb->jb_eff_level -= diff;
607
/* Update prefetch based on level */
608
if (jb->jb_init_prefetch) {
609
jb->jb_prefetch = jb->jb_eff_level;
610
if (jb->jb_prefetch < jb->jb_min_prefetch)
611
jb->jb_prefetch = jb->jb_min_prefetch;
615
jb->jb_max_hist_level = 0;
616
jb->jb_stable_hist = 0;
618
TRACE__((jb->jb_name.ptr,"jb updated(1), lvl=%d pre=%d, size=%d",
619
jb->jb_eff_level, jb->jb_prefetch, cur_size));
623
/* Burst level is increasing */
624
else if (jb->jb_level > jb->jb_eff_level) {
626
/* Instaneous set effective burst level to recent maximum level */
627
jb->jb_eff_level = PJ_MIN(jb->jb_max_hist_level,
628
(int)(jb->jb_max_count*4/5));
630
/* Update prefetch based on level */
631
if (jb->jb_init_prefetch) {
632
jb->jb_prefetch = jb->jb_eff_level;
633
if (jb->jb_prefetch > jb->jb_max_prefetch)
634
jb->jb_prefetch = jb->jb_max_prefetch;
637
jb->jb_stable_hist = 0;
638
/* Do not reset max_hist_level. */
639
//jb->jb_max_hist_level = 0;
641
TRACE__((jb->jb_name.ptr,"jb updated(2), lvl=%d pre=%d, size=%d",
642
jb->jb_eff_level, jb->jb_prefetch, cur_size));
645
/* Level is unchanged */
647
jb->jb_stable_hist = 0;
651
PJ_INLINE(void) jbuf_update(pjmedia_jbuf *jb, int oper)
653
if(jb->jb_last_op != oper) {
654
jb->jb_last_op = oper;
656
if (jb->jb_status == JB_STATUS_INITIALIZING) {
657
/* Switch status 'initializing' -> 'processing' after some OP
658
* switch cycles and current OP is GET (burst level is calculated
659
* based on PUT burst), so burst calculation is guaranted to be
660
* performed right after the status switching.
662
if (++jb->jb_init_cycle_cnt >= INIT_CYCLE && oper == JB_OP_GET) {
663
jb->jb_status = JB_STATUS_PROCESSING;
664
/* To make sure the burst calculation will be done right after
665
* this, adjust burst level if it exceeds max burst level.
667
jb->jb_level = PJ_MIN(jb->jb_level, jb->jb_max_burst);
674
/* Perform jitter calculation based on PUT burst-level only, since
675
* GET burst-level may not be accurate, e.g: when VAD is active.
676
* Note that when burst-level is too big, i.e: exceeds jb_max_burst,
677
* the GET op may be idle, in this case, we better skip the jitter
680
if (oper == JB_OP_GET && jb->jb_level <= jb->jb_max_burst)
681
jbuf_calculate_jitter(jb);
686
/* These code is used for shortening the delay in the jitter buffer.
687
* It needs shrink only when there is possibility of drift. Drift
688
* detection is performed by inspecting the jitter buffer size, if
689
* its size is twice of current burst level, there can be drift.
691
* Moreover, normally drift level is quite low, so JB shouldn't need
692
* to shrink aggresively, it will shrink maximum one frame per
693
* MIN_SHRINK_GAP_MSEC ms. Theoritically, JB may handle drift level
694
* as much as = FRAME_PTIME/MIN_SHRINK_GAP_MSEC * 100%
696
* Whenever there is drift, where PUT > GET, this method will keep
697
* the latency (JB size) as much as twice of burst level.
700
/* Shrinking due of drift will be implicitly done by progressive discard,
701
* so just disable it when progressive discard is active.
703
#if !PROGRESSIVE_DISCARD
705
if (jb->jb_status != JB_STATUS_PROCESSING)
709
int diff, burst_level;
711
burst_level = PJ_MAX(jb->jb_eff_level, jb->jb_level);
712
diff = jb_framelist_eff_size(&jb->jb_framelist) - burst_level*2;
714
if (diff >= SAFE_SHRINKING_DIFF) {
717
/* Check and adjust jb_last_del_seq, in case there was
720
seq_origin = jb_framelist_origin(&jb->jb_framelist);
721
if (seq_origin < jb->jb_last_del_seq)
722
jb->jb_last_del_seq = seq_origin;
724
if (seq_origin - jb->jb_last_del_seq >= jb->jb_min_shrink_gap)
726
/* Shrink slowly, one frame per cycle */
730
diff = jb_framelist_remove_head(&jb->jb_framelist, diff);
731
jb->jb_last_del_seq = jb_framelist_origin(&jb->jb_framelist);
732
jb->jb_discard += diff;
734
TRACE__((jb->jb_name.ptr,
735
"JB shrinking %d frame(s), cur size=%d", diff,
736
jb_framelist_eff_size(&jb->jb_framelist)));
741
#endif /* !PROGRESSIVE_DISCARD */
745
PJ_DEF(void) pjmedia_jbuf_put_frame( pjmedia_jbuf *jb,
747
pj_size_t frame_size,
750
pjmedia_jbuf_put_frame2(jb, frame, frame_size, 0, frame_seq, NULL);
753
PJ_DEF(void) pjmedia_jbuf_put_frame2(pjmedia_jbuf *jb,
755
pj_size_t frame_size,
756
pj_uint32_t bit_info,
758
pj_bool_t *discarded)
760
pj_size_t min_frame_size;
761
int new_size, cur_size, frame_type = PJMEDIA_JB_NORMAL_FRAME;
764
cur_size = jb_framelist_eff_size(&jb->jb_framelist);
766
#if PROGRESSIVE_DISCARD
768
unsigned interval, seq_delta;
769
unsigned burst_level, burst_factor;
771
/* Calculating discard interval (aggressiveness) based on
772
* (current size / burst level).
774
if (jb->jb_status == JB_STATUS_PROCESSING) {
775
burst_level = PJ_MAX(jb->jb_eff_level, jb->jb_level);
776
burst_factor = cur_size / burst_level;
777
/* Tolerate small spikes */
778
if ((burst_level <= 5) && (burst_factor < 3))
784
switch (burst_factor) {
799
/* Do the math now to see if we should discard this packet.
800
* Calculate the distance from the last sequence
801
* discarded. If negative, then this is an out of
802
* order frame so just proceed with discard. Else
803
* see if the delta is at least the intervals worth away
804
* from the last frame discarded.
806
seq_delta = (pj_uint16_t)(frame_seq - jb->jb_last_discard_seq);
807
if ((0 != interval) && (seq_delta >= interval)) {
808
frame_type = PJMEDIA_JB_DISCARDED_FRAME;
809
jb->jb_last_discard_seq = frame_seq;
811
TRACE__((jb->jb_name.ptr,
812
"Discarding frame #%d: eff=%d disc=%d orig:%d"
816
jb_framelist_size(&jb->jb_framelist) - cur_size,
817
jb_framelist_origin(&jb->jb_framelist),
821
#endif /* PROGRESSIVE_DISCARD */
824
/* Attempt to store the frame */
825
min_frame_size = PJ_MIN(frame_size, jb->jb_frame_size);
826
status = jb_framelist_put_at(&jb->jb_framelist, frame_seq, frame,
827
min_frame_size, bit_info, frame_type);
829
/* Jitter buffer is full, remove some older frames */
830
while (status == PJ_ETOOMANY) {
834
/* When progressive discard activated, just remove as few as possible
835
* just to make this frame in.
837
#if PROGRESSIVE_DISCARD
838
/* The cases of seq-jump, out-of-order, and seq restart should have
839
* been handled/normalized by previous call of jb_framelist_put_at().
840
* So we're confident about 'distance' value here.
842
distance = (frame_seq - jb_framelist_origin(&jb->jb_framelist)) -
843
jb->jb_max_count + 1;
844
pj_assert(distance > 0);
846
distance = PJ_MAX(jb->jb_max_count/4, 1);
848
removed = jb_framelist_remove_head(&jb->jb_framelist, distance);
849
status = jb_framelist_put_at(&jb->jb_framelist, frame_seq, frame,
850
min_frame_size, bit_info, frame_type);
852
jb->jb_discard += removed;
855
/* Get new JB size after PUT */
856
new_size = jb_framelist_eff_size(&jb->jb_framelist);
858
/* Return the flag if this frame is discarded */
860
*discarded = (status != PJ_SUCCESS);
862
if (status == PJ_SUCCESS) {
863
if (jb->jb_status == JB_STATUS_PREFETCHING) {
864
TRACE__((jb->jb_name.ptr, "PUT prefetch_cnt=%d/%d",
865
new_size, jb->jb_prefetch));
866
if (new_size >= jb->jb_prefetch)
867
jb->jb_status = JB_STATUS_PROCESSING;
869
jb->jb_level += (new_size > cur_size ? new_size-cur_size : 1);
870
jbuf_update(jb, JB_OP_PUT);
876
* Get frame from jitter buffer.
878
PJ_DEF(void) pjmedia_jbuf_get_frame( pjmedia_jbuf *jb,
882
pjmedia_jbuf_get_frame2(jb, frame, NULL, p_frame_type, NULL);
886
* Get frame from jitter buffer.
888
PJ_DEF(void) pjmedia_jbuf_get_frame2(pjmedia_jbuf *jb,
892
pj_uint32_t *bit_info)
894
if (jb->jb_status == JB_STATUS_PREFETCHING) {
896
/* Can't return frame because jitter buffer is filling up
900
//pj_bzero(frame, jb->jb_frame_size);
901
*p_frame_type = PJMEDIA_JB_ZERO_PREFETCH_FRAME;
905
TRACE__((jb->jb_name.ptr, "GET prefetch_cnt=%d/%d",
906
jb_framelist_eff_size(&jb->jb_framelist), jb->jb_prefetch));
912
pjmedia_jb_frame_type ftype = PJMEDIA_JB_NORMAL_FRAME;
915
/* Try to retrieve a frame from frame list */
916
res = jb_framelist_get(&jb->jb_framelist, frame, size, &ftype,
919
/* We've successfully retrieved a frame from the frame list, but
920
* the frame could be a blank frame!
922
if (ftype == PJMEDIA_JB_NORMAL_FRAME) {
923
*p_frame_type = PJMEDIA_JB_NORMAL_FRAME;
925
*p_frame_type = PJMEDIA_JB_MISSING_FRAME;
929
/* Store delay history at the first GET */
930
if (jb->jb_last_op == JB_OP_PUT) {
933
/* We've just retrieved one frame, so add one to cur_size */
934
cur_size = jb_framelist_eff_size(&jb->jb_framelist) + 1;
935
pj_math_stat_update(&jb->jb_delay,
936
cur_size*jb->jb_frame_ptime);
939
/* Jitter buffer is empty */
941
jb->jb_status = JB_STATUS_PREFETCHING;
943
//pj_bzero(frame, jb->jb_frame_size);
944
*p_frame_type = PJMEDIA_JB_ZERO_EMPTY_FRAME;
953
jbuf_update(jb, JB_OP_GET);
957
* Get jitter buffer state.
959
PJ_DEF(pj_status_t) pjmedia_jbuf_get_state( const pjmedia_jbuf *jb,
960
pjmedia_jb_state *state )
962
PJ_ASSERT_RETURN(jb && state, PJ_EINVAL);
964
state->frame_size = jb->jb_frame_size;
965
state->min_prefetch = jb->jb_min_prefetch;
966
state->max_prefetch = jb->jb_max_prefetch;
968
state->burst = jb->jb_eff_level;
969
state->prefetch = jb->jb_prefetch;
970
state->size = jb_framelist_eff_size(&jb->jb_framelist);
972
state->avg_delay = jb->jb_delay.mean;
973
state->min_delay = jb->jb_delay.min;
974
state->max_delay = jb->jb_delay.max;
975
state->dev_delay = pj_math_stat_get_stddev(&jb->jb_delay);
977
state->avg_burst = jb->jb_burst.mean;
978
state->empty = jb->jb_empty;
979
state->discard = jb->jb_discard;
980
state->lost = jb->jb_lost;