~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject/pjmedia/src/pjmedia/jbuf.c

  • Committer: Package Import Robot
  • Author(s): Francois Marier
  • Date: 2011-11-25 13:24:12 UTC
  • mfrom: (4.1.10 sid)
  • Revision ID: package-import@ubuntu.com-20111125132412-dc4qvhyosk74cd42
Tags: 1.0.1-4
Don't assume that arch:all packages will get built (closes: #649726)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: jbuf.c 3553 2011-05-05 06:14:19Z nanang $ */
 
2
/* 
 
3
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 
4
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
 
5
 *
 
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.
 
10
 *
 
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.
 
15
 *
 
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 
 
19
 */
 
20
/*
 
21
 * Based on implementation kindly contributed by Switchlab, Ltd.
 
22
 */
 
23
#include <pjmedia/jbuf.h>
 
24
#include <pjmedia/errno.h>
 
25
#include <pj/pool.h>
 
26
#include <pj/assert.h>
 
27
#include <pj/log.h>
 
28
#include <pj/math.h>
 
29
#include <pj/string.h>
 
30
 
 
31
 
 
32
#define THIS_FILE   "jbuf.c"
 
33
 
 
34
 
 
35
/* Minimal difference between JB size and 2*burst-level to perform 
 
36
 * JB shrinking. 
 
37
 */
 
38
#define SAFE_SHRINKING_DIFF     1
 
39
 
 
40
/* Minimal gap (in ms) between JB shrinking */
 
41
#define MIN_SHRINK_GAP_MSEC     200
 
42
 
 
43
/* Invalid sequence number, used as the initial value. */
 
44
#define INVALID_OFFSET          -9999
 
45
 
 
46
/* Maximum burst length, whenever an operation is bursting longer than 
 
47
 * this value, JB will assume that the opposite operation was idle.
 
48
 */
 
49
#define MAX_BURST_MSEC          1000
 
50
 
 
51
/* Number of OP switches to be performed in JB_STATUS_INITIALIZING, before
 
52
 * JB can switch its states to JB_STATUS_PROCESSING.
 
53
 */
 
54
#define INIT_CYCLE              10
 
55
 
 
56
 
 
57
/* Struct of JB internal buffer, represented in a circular buffer containing
 
58
 * frame content, frame type, frame length, and frame bit info.
 
59
 */
 
60
typedef struct jb_framelist_t
 
61
{
 
62
    /* Settings */
 
63
    unsigned         frame_size;        /**< maximum size of frame          */
 
64
    unsigned         max_count;         /**< maximum number of frames       */
 
65
 
 
66
    /* Buffers */
 
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           */
 
71
    
 
72
    /* States */
 
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 
 
78
                                             frames.                        */
 
79
    int              origin;            /**< original index of flist_head   */
 
80
 
 
81
} jb_framelist_t;
 
82
 
 
83
 
 
84
struct pjmedia_jbuf
 
85
{
 
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, 
 
91
                                             in frames                      */
 
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 
 
98
                                             calculation                    */
 
99
    int             jb_min_shrink_gap;  /**< How often can we shrink        */
 
100
 
 
101
    /* Buffer */
 
102
    jb_framelist_t  jb_framelist;       /**< the buffer                     */
 
103
 
 
104
    /* States */
 
105
    int             jb_level;           /**< delay between source & 
 
106
                                             destination (calculated according 
 
107
                                             of the number of burst get/put 
 
108
                                             operations)                    */
 
109
    int             jb_max_hist_level;  /**< max level during the last level 
 
110
                                             calculations                   */
 
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 
 
114
                                             (put/get)                      */
 
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 
 
123
                                             'put' operation                */
 
124
    int             jb_init_cycle_cnt;  /**< status is 'init' until the first 
 
125
                                             'put' operation                */
 
126
    int             jb_last_del_seq;    /**< Seq # of last frame deleted    */
 
127
 
 
128
    int             jb_last_discard_seq;/**< Seq # of last frame discarded  */
 
129
 
 
130
    /* Statistics */
 
131
    pj_math_stat    jb_delay;           /**< Delay statistics of jitter buffer 
 
132
                                             (in ms)                        */
 
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
 
137
                                             returned by GET. */
 
138
};
 
139
 
 
140
 
 
141
#define JB_STATUS_INITIALIZING  0
 
142
#define JB_STATUS_PROCESSING    1
 
143
#define JB_STATUS_PREFETCHING   2
 
144
 
 
145
 
 
146
 
 
147
/* Progressive discard algorithm introduced to reduce JB latency
 
148
 * by discarding incoming frames with adaptive aggressiveness based on
 
149
 * actual burst level.
 
150
 */
 
151
#define PROGRESSIVE_DISCARD 1
 
152
 
 
153
/* Internal JB frame flag, discarded frame will not be returned by JB to
 
154
 * application, it's just simply discarded.
 
155
 */
 
156
#define PJMEDIA_JB_DISCARDED_FRAME 1024
 
157
 
 
158
 
 
159
 
 
160
/* Enabling this would log the jitter buffer state about once per 
 
161
 * second.
 
162
 */
 
163
#if 1
 
164
#  define TRACE__(args)     PJ_LOG(5,args)
 
165
#else
 
166
#  define TRACE__(args)
 
167
#endif
 
168
 
 
169
static pj_status_t jb_framelist_reset(jb_framelist_t *framelist);
 
170
static unsigned jb_framelist_remove_head(jb_framelist_t *framelist,
 
171
                                         unsigned count);
 
172
 
 
173
static pj_status_t jb_framelist_init( pj_pool_t *pool,
 
174
                                      jb_framelist_t *framelist,
 
175
                                      unsigned frame_size,
 
176
                                      unsigned max_count) 
 
177
{
 
178
    PJ_ASSERT_RETURN(pool && framelist, PJ_EINVAL);
 
179
 
 
180
    pj_bzero(framelist, sizeof(jb_framelist_t));
 
181
 
 
182
    framelist->frame_size   = frame_size;
 
183
    framelist->max_count    = max_count;
 
184
    framelist->content      = (char*) 
 
185
                              pj_pool_alloc(pool,
 
186
                                            framelist->frame_size* 
 
187
                                            framelist->max_count);
 
188
    framelist->frame_type   = (int*)
 
189
                              pj_pool_alloc(pool, 
 
190
                                            sizeof(framelist->frame_type[0])*
 
191
                                            framelist->max_count);
 
192
    framelist->content_len  = (pj_size_t*)
 
193
                              pj_pool_alloc(pool, 
 
194
                                            sizeof(framelist->content_len[0])*
 
195
                                            framelist->max_count);
 
196
    framelist->bit_info     = (pj_uint32_t*)
 
197
                              pj_pool_alloc(pool, 
 
198
                                            sizeof(framelist->bit_info[0])*
 
199
                                            framelist->max_count);
 
200
 
 
201
 
 
202
    return jb_framelist_reset(framelist);
 
203
 
 
204
}
 
205
 
 
206
static pj_status_t jb_framelist_destroy(jb_framelist_t *framelist) 
 
207
{
 
208
    PJ_UNUSED_ARG(framelist);
 
209
    return PJ_SUCCESS;
 
210
}
 
211
 
 
212
static pj_status_t jb_framelist_reset(jb_framelist_t *framelist) 
 
213
{
 
214
    framelist->head = 0;
 
215
    framelist->origin = INVALID_OFFSET;
 
216
    framelist->size = 0;
 
217
    framelist->discarded_num = 0;
 
218
 
 
219
 
 
220
    //pj_bzero(framelist->content, 
 
221
    //       framelist->frame_size * 
 
222
    //       framelist->max_count);
 
223
 
 
224
    pj_memset(framelist->frame_type,
 
225
              PJMEDIA_JB_MISSING_FRAME,
 
226
              sizeof(framelist->frame_type[0]) * 
 
227
              framelist->max_count);
 
228
 
 
229
    pj_bzero(framelist->content_len, 
 
230
             sizeof(framelist->content_len[0]) * 
 
231
             framelist->max_count);
 
232
 
 
233
    //pj_bzero(framelist->bit_info,
 
234
    //       sizeof(framelist->bit_info[0]) * 
 
235
    //       framelist->max_count);
 
236
 
 
237
    return PJ_SUCCESS;
 
238
}
 
239
 
 
240
 
 
241
static unsigned jb_framelist_size(const jb_framelist_t *framelist) 
 
242
{
 
243
    return framelist->size;
 
244
}
 
245
 
 
246
 
 
247
static unsigned jb_framelist_eff_size(const jb_framelist_t *framelist) 
 
248
{
 
249
    return (framelist->size - framelist->discarded_num);
 
250
}
 
251
 
 
252
static int jb_framelist_origin(const jb_framelist_t *framelist) 
 
253
{
 
254
    return framelist->origin;
 
255
}
 
256
 
 
257
 
 
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) 
 
262
{
 
263
    if (framelist->size) {
 
264
        pj_bool_t prev_discarded = PJ_FALSE;
 
265
 
 
266
        /* Skip discarded frames */
 
267
        while (framelist->frame_type[framelist->head] ==
 
268
               PJMEDIA_JB_DISCARDED_FRAME)
 
269
        {
 
270
            jb_framelist_remove_head(framelist, 1);
 
271
            prev_discarded = PJ_TRUE;
 
272
        }
 
273
 
 
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.
 
279
                 */
 
280
                *p_type = PJMEDIA_JB_MISSING_FRAME;
 
281
                if (size)
 
282
                    *size = 0;
 
283
                if (bit_info)
 
284
                    *bit_info = 0;
 
285
            } else {
 
286
                pj_memcpy(frame, 
 
287
                          framelist->content + 
 
288
                          framelist->head * framelist->frame_size,
 
289
                          framelist->frame_size);
 
290
                *p_type = (pjmedia_jb_frame_type) 
 
291
                          framelist->frame_type[framelist->head];
 
292
                if (size)
 
293
                    *size   = framelist->content_len[framelist->head];
 
294
                if (bit_info)
 
295
                    *bit_info = framelist->bit_info[framelist->head];
 
296
            }
 
297
 
 
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;
 
304
 
 
305
            framelist->origin++;
 
306
            framelist->head = (framelist->head + 1) % framelist->max_count;
 
307
            framelist->size--;
 
308
        
 
309
            return PJ_TRUE;
 
310
        }
 
311
    }
 
312
 
 
313
    /* No frame available */
 
314
    pj_bzero(frame, framelist->frame_size);
 
315
 
 
316
    return PJ_FALSE;
 
317
}
 
318
 
 
319
 
 
320
/* Remove oldest frames as many as param 'count' */
 
321
static unsigned jb_framelist_remove_head(jb_framelist_t *framelist,
 
322
                                         unsigned count) 
 
323
{
 
324
    if (count > framelist->size) 
 
325
        count = framelist->size;
 
326
 
 
327
    if (count) {
 
328
        /* may be done in two steps if overlapping */
 
329
        unsigned step1,step2;
 
330
        unsigned tmp = framelist->head+count;
 
331
        unsigned i;
 
332
 
 
333
        if (tmp > framelist->max_count) {
 
334
            step1 = framelist->max_count - framelist->head;
 
335
            step2 = count-step1;
 
336
        } else {
 
337
            step1 = count;
 
338
            step2 = 0;
 
339
        }
 
340
 
 
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--;
 
345
            }
 
346
        }
 
347
 
 
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]));
 
356
 
 
357
        if (step2) {
 
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--;
 
362
                }
 
363
            }
 
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]));
 
371
        }
 
372
 
 
373
        /* update states */
 
374
        framelist->origin += count;
 
375
        framelist->head = (framelist->head + count) % framelist->max_count;
 
376
        framelist->size -= count;
 
377
    }
 
378
    
 
379
    return count;
 
380
}
 
381
 
 
382
 
 
383
static pj_status_t jb_framelist_put_at(jb_framelist_t *framelist,
 
384
                                       int index,
 
385
                                       const void *frame,
 
386
                                       unsigned frame_size,
 
387
                                       pj_uint32_t bit_info,
 
388
                                       unsigned frame_type)
 
389
{
 
390
    int distance;
 
391
    unsigned pos;
 
392
    enum { MAX_MISORDER = 100 };
 
393
    enum { MAX_DROPOUT = 3000 };
 
394
 
 
395
    assert(frame_size <= framelist->frame_size);
 
396
 
 
397
    /* too late or sequence restart */
 
398
    if (index < framelist->origin) {
 
399
        if (framelist->origin - index < MAX_MISORDER) {
 
400
            /* too late */
 
401
            return PJ_ETOOSMALL;
 
402
        } else {
 
403
            /* sequence restart */
 
404
            framelist->origin = index - framelist->size;
 
405
        }
 
406
    }
 
407
 
 
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;
 
412
    }
 
413
 
 
414
    /* get distance of this frame to the first frame in the buffer */
 
415
    distance = index - framelist->origin;
 
416
 
 
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;
 
423
            distance = 0;
 
424
        } else {
 
425
            /* otherwise, reject the frame */
 
426
            return PJ_ETOOMANY;
 
427
        }
 
428
    }
 
429
 
 
430
    /* get the slot position */
 
431
    pos = (framelist->head + distance) % framelist->max_count;
 
432
 
 
433
    /* if the slot is occupied, it must be duplicated frame, ignore it. */
 
434
    if (framelist->frame_type[pos] != PJMEDIA_JB_MISSING_FRAME)
 
435
        return PJ_EEXISTS;
 
436
 
 
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;
 
441
 
 
442
    /* update framelist size */
 
443
    if (framelist->origin + (int)framelist->size <= index)
 
444
        framelist->size = distance + 1;
 
445
 
 
446
    if(PJMEDIA_JB_NORMAL_FRAME == frame_type) {
 
447
        /* copy frame content */
 
448
        pj_memcpy(framelist->content + pos * framelist->frame_size,
 
449
                  frame, frame_size);
 
450
        return PJ_SUCCESS;
 
451
    } else {
 
452
        /* frame is being discarded */
 
453
        framelist->discarded_num++;
 
454
        return PJ_EIGNORED;
 
455
    }
 
456
}
 
457
 
 
458
 
 
459
 
 
460
enum pjmedia_jb_op
 
461
{
 
462
    JB_OP_INIT  = -1,
 
463
    JB_OP_PUT   = 1,
 
464
    JB_OP_GET   = 2
 
465
};
 
466
 
 
467
 
 
468
PJ_DEF(pj_status_t) pjmedia_jbuf_create(pj_pool_t *pool, 
 
469
                                        const pj_str_t *name,
 
470
                                        unsigned frame_size, 
 
471
                                        unsigned ptime,
 
472
                                        unsigned max_count,
 
473
                                        pjmedia_jbuf **p_jb)
 
474
{
 
475
    pjmedia_jbuf *jb;
 
476
    pj_status_t status;
 
477
 
 
478
    jb = PJ_POOL_ZALLOC_T(pool, pjmedia_jbuf);
 
479
 
 
480
    status = jb_framelist_init(pool, &jb->jb_framelist, frame_size, max_count);
 
481
    if (status != PJ_SUCCESS)
 
482
        return status;
 
483
 
 
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;
 
494
 
 
495
    pj_math_stat_init(&jb->jb_delay);
 
496
    pj_math_stat_init(&jb->jb_burst);
 
497
 
 
498
    pjmedia_jbuf_reset(jb);
 
499
 
 
500
    *p_jb = jb;
 
501
    return PJ_SUCCESS;
 
502
}
 
503
 
 
504
 
 
505
/*
 
506
 * Set the jitter buffer to fixed delay mode. The default behavior
 
507
 * is to adapt the delay with actual packet delay.
 
508
 *
 
509
 */
 
510
PJ_DEF(pj_status_t) pjmedia_jbuf_set_fixed( pjmedia_jbuf *jb,
 
511
                                            unsigned prefetch)
 
512
{
 
513
    PJ_ASSERT_RETURN(jb, PJ_EINVAL);
 
514
    PJ_ASSERT_RETURN(prefetch <= jb->jb_max_count, PJ_EINVAL);
 
515
 
 
516
    jb->jb_min_prefetch = jb->jb_max_prefetch = 
 
517
        jb->jb_prefetch = jb->jb_init_prefetch = prefetch;
 
518
 
 
519
    return PJ_SUCCESS;
 
520
}
 
521
 
 
522
 
 
523
/*
 
524
 * Set the jitter buffer to adaptive mode.
 
525
 */
 
526
PJ_DEF(pj_status_t) pjmedia_jbuf_set_adaptive( pjmedia_jbuf *jb,
 
527
                                               unsigned prefetch,
 
528
                                               unsigned min_prefetch,
 
529
                                               unsigned max_prefetch)
 
530
{
 
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,
 
535
                     PJ_EINVAL);
 
536
 
 
537
    jb->jb_prefetch = jb->jb_init_prefetch = prefetch;
 
538
    jb->jb_min_prefetch = min_prefetch;
 
539
    jb->jb_max_prefetch = max_prefetch;
 
540
 
 
541
    return PJ_SUCCESS;
 
542
}
 
543
 
 
544
 
 
545
PJ_DEF(pj_status_t) pjmedia_jbuf_reset(pjmedia_jbuf *jb)
 
546
{
 
547
    jb->jb_level         = 0;
 
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;
 
553
 
 
554
    jb_framelist_reset(&jb->jb_framelist);
 
555
 
 
556
    return PJ_SUCCESS;
 
557
}
 
558
 
 
559
 
 
560
PJ_DEF(pj_status_t) pjmedia_jbuf_destroy(pjmedia_jbuf *jb)
 
561
{
 
562
    PJ_LOG(5, (jb->jb_name.ptr, ""
 
563
               "JB summary:\n"
 
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));
 
574
 
 
575
    return jb_framelist_destroy(&jb->jb_framelist);
 
576
}
 
577
 
 
578
 
 
579
static void jbuf_calculate_jitter(pjmedia_jbuf *jb)
 
580
{
 
581
    int diff, cur_size;
 
582
 
 
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);
 
586
 
 
587
    /* Burst level is decreasing */
 
588
    if (jb->jb_level < jb->jb_eff_level) {
 
589
 
 
590
        enum { STABLE_HISTORY_LIMIT = 20 };
 
591
        
 
592
        jb->jb_stable_hist++;
 
593
        
 
594
        /* Only update the effective level (and prefetch) if 'stable' 
 
595
         * condition is reached (not just short time impulse)
 
596
         */
 
597
        if (jb->jb_stable_hist > STABLE_HISTORY_LIMIT) {
 
598
        
 
599
            diff = (jb->jb_eff_level - jb->jb_max_hist_level) / 3;
 
600
 
 
601
            if (diff < 1)
 
602
                diff = 1;
 
603
 
 
604
            /* Update effective burst level */
 
605
            jb->jb_eff_level -= diff;
 
606
 
 
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;
 
612
            }
 
613
 
 
614
            /* Reset history */
 
615
            jb->jb_max_hist_level = 0;
 
616
            jb->jb_stable_hist = 0;
 
617
 
 
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));
 
620
        }
 
621
    }
 
622
 
 
623
    /* Burst level is increasing */
 
624
    else if (jb->jb_level > jb->jb_eff_level) {
 
625
 
 
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));
 
629
 
 
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;
 
635
        }
 
636
 
 
637
        jb->jb_stable_hist = 0;
 
638
        /* Do not reset max_hist_level. */
 
639
        //jb->jb_max_hist_level = 0;
 
640
 
 
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));
 
643
    }
 
644
 
 
645
    /* Level is unchanged */
 
646
    else {
 
647
        jb->jb_stable_hist = 0;
 
648
    }
 
649
}
 
650
 
 
651
PJ_INLINE(void) jbuf_update(pjmedia_jbuf *jb, int oper)
 
652
{
 
653
    if(jb->jb_last_op != oper) {
 
654
        jb->jb_last_op = oper;
 
655
 
 
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.
 
661
             */
 
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.
 
666
                 */
 
667
                jb->jb_level = PJ_MIN(jb->jb_level, jb->jb_max_burst);
 
668
            } else {
 
669
                jb->jb_level = 0;
 
670
                return;
 
671
            }
 
672
        }
 
673
 
 
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 
 
678
         * calculation.
 
679
         */
 
680
        if (oper == JB_OP_GET && jb->jb_level <= jb->jb_max_burst)
 
681
            jbuf_calculate_jitter(jb);
 
682
 
 
683
        jb->jb_level = 0;
 
684
    }
 
685
 
 
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.
 
690
     *
 
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%
 
695
     *
 
696
     * Whenever there is drift, where PUT > GET, this method will keep 
 
697
     * the latency (JB size) as much as twice of burst level.
 
698
     */
 
699
 
 
700
    /* Shrinking due of drift will be implicitly done by progressive discard,
 
701
     * so just disable it when progressive discard is active.
 
702
     */
 
703
#if !PROGRESSIVE_DISCARD
 
704
 
 
705
    if (jb->jb_status != JB_STATUS_PROCESSING)
 
706
        return;
 
707
 
 
708
    {
 
709
        int diff, burst_level;
 
710
 
 
711
        burst_level = PJ_MAX(jb->jb_eff_level, jb->jb_level);
 
712
        diff = jb_framelist_eff_size(&jb->jb_framelist) - burst_level*2;
 
713
 
 
714
        if (diff >= SAFE_SHRINKING_DIFF) {
 
715
            int seq_origin;
 
716
 
 
717
            /* Check and adjust jb_last_del_seq, in case there was 
 
718
             * seq restart 
 
719
             */
 
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;
 
723
 
 
724
            if (seq_origin - jb->jb_last_del_seq >= jb->jb_min_shrink_gap)
 
725
            {
 
726
                /* Shrink slowly, one frame per cycle */
 
727
                diff = 1;
 
728
 
 
729
                /* Drop frame(s)! */
 
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;
 
733
 
 
734
                TRACE__((jb->jb_name.ptr, 
 
735
                         "JB shrinking %d frame(s), cur size=%d", diff,
 
736
                         jb_framelist_eff_size(&jb->jb_framelist)));
 
737
            }
 
738
        }
 
739
    }
 
740
 
 
741
#endif /* !PROGRESSIVE_DISCARD */
 
742
 
 
743
}
 
744
 
 
745
PJ_DEF(void) pjmedia_jbuf_put_frame( pjmedia_jbuf *jb, 
 
746
                                     const void *frame, 
 
747
                                     pj_size_t frame_size, 
 
748
                                     int frame_seq)
 
749
{
 
750
    pjmedia_jbuf_put_frame2(jb, frame, frame_size, 0, frame_seq, NULL);
 
751
}
 
752
 
 
753
PJ_DEF(void) pjmedia_jbuf_put_frame2(pjmedia_jbuf *jb, 
 
754
                                     const void *frame, 
 
755
                                     pj_size_t frame_size, 
 
756
                                     pj_uint32_t bit_info,
 
757
                                     int frame_seq,
 
758
                                     pj_bool_t *discarded)
 
759
{
 
760
    pj_size_t min_frame_size;
 
761
    int new_size, cur_size, frame_type = PJMEDIA_JB_NORMAL_FRAME;
 
762
    pj_status_t status;
 
763
 
 
764
    cur_size = jb_framelist_eff_size(&jb->jb_framelist);
 
765
 
 
766
#if PROGRESSIVE_DISCARD
 
767
    {
 
768
        unsigned interval, seq_delta;
 
769
        unsigned burst_level, burst_factor;
 
770
 
 
771
        /* Calculating discard interval (aggressiveness) based on
 
772
         * (current size / burst level).
 
773
         */
 
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))
 
779
                burst_factor = 0;
 
780
        } else {
 
781
            burst_factor = 0;
 
782
        }
 
783
 
 
784
        switch (burst_factor) {
 
785
        case 0:
 
786
            interval = 0;
 
787
            break;
 
788
        case 1:
 
789
            interval = 7;
 
790
            break;
 
791
        case 2:
 
792
            interval = 5;
 
793
            break;
 
794
        default:
 
795
            interval = 4;
 
796
            break;
 
797
        }
 
798
 
 
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.
 
805
         */
 
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;
 
810
 
 
811
            TRACE__((jb->jb_name.ptr, 
 
812
                    "Discarding frame #%d: eff=%d disc=%d orig:%d"
 
813
                    " seq_delta:%d",
 
814
                    frame_seq,
 
815
                    cur_size,
 
816
                    jb_framelist_size(&jb->jb_framelist) - cur_size,
 
817
                    jb_framelist_origin(&jb->jb_framelist),
 
818
                    (int)seq_delta));
 
819
        }
 
820
    }
 
821
#endif /* PROGRESSIVE_DISCARD */
 
822
    
 
823
 
 
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);
 
828
    
 
829
    /* Jitter buffer is full, remove some older frames */
 
830
    while (status == PJ_ETOOMANY) {
 
831
        int distance;
 
832
        unsigned removed;
 
833
 
 
834
        /* When progressive discard activated, just remove as few as possible
 
835
         * just to make this frame in.
 
836
         */
 
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.
 
841
         */
 
842
        distance = (frame_seq - jb_framelist_origin(&jb->jb_framelist)) -
 
843
                   jb->jb_max_count + 1;
 
844
        pj_assert(distance > 0);
 
845
#else
 
846
        distance = PJ_MAX(jb->jb_max_count/4, 1);
 
847
#endif
 
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);
 
851
 
 
852
        jb->jb_discard += removed;
 
853
    }
 
854
 
 
855
    /* Get new JB size after PUT */
 
856
    new_size = jb_framelist_eff_size(&jb->jb_framelist);
 
857
 
 
858
    /* Return the flag if this frame is discarded */
 
859
    if (discarded)
 
860
        *discarded = (status != PJ_SUCCESS);
 
861
 
 
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;
 
868
        }
 
869
        jb->jb_level += (new_size > cur_size ? new_size-cur_size : 1);
 
870
        jbuf_update(jb, JB_OP_PUT);
 
871
    } else
 
872
        jb->jb_discard++;
 
873
}
 
874
 
 
875
/*
 
876
 * Get frame from jitter buffer.
 
877
 */
 
878
PJ_DEF(void) pjmedia_jbuf_get_frame( pjmedia_jbuf *jb, 
 
879
                                     void *frame, 
 
880
                                     char *p_frame_type)
 
881
{
 
882
    pjmedia_jbuf_get_frame2(jb, frame, NULL, p_frame_type, NULL);
 
883
}
 
884
 
 
885
/*
 
886
 * Get frame from jitter buffer.
 
887
 */
 
888
PJ_DEF(void) pjmedia_jbuf_get_frame2(pjmedia_jbuf *jb, 
 
889
                                     void *frame, 
 
890
                                     pj_size_t *size,
 
891
                                     char *p_frame_type,
 
892
                                     pj_uint32_t *bit_info)
 
893
{
 
894
    if (jb->jb_status == JB_STATUS_PREFETCHING) {
 
895
 
 
896
        /* Can't return frame because jitter buffer is filling up
 
897
         * minimum prefetch.
 
898
         */
 
899
 
 
900
        //pj_bzero(frame, jb->jb_frame_size);
 
901
        *p_frame_type = PJMEDIA_JB_ZERO_PREFETCH_FRAME;
 
902
        if (size)
 
903
            *size = 0;
 
904
 
 
905
        TRACE__((jb->jb_name.ptr, "GET prefetch_cnt=%d/%d",
 
906
                 jb_framelist_eff_size(&jb->jb_framelist), jb->jb_prefetch));
 
907
 
 
908
        jb->jb_empty++;
 
909
 
 
910
    } else {
 
911
 
 
912
        pjmedia_jb_frame_type ftype = PJMEDIA_JB_NORMAL_FRAME;
 
913
        pj_bool_t res;
 
914
 
 
915
        /* Try to retrieve a frame from frame list */
 
916
        res = jb_framelist_get(&jb->jb_framelist, frame, size, &ftype, 
 
917
                               bit_info);
 
918
        if (res) {
 
919
            /* We've successfully retrieved a frame from the frame list, but
 
920
             * the frame could be a blank frame!
 
921
             */
 
922
            if (ftype == PJMEDIA_JB_NORMAL_FRAME) {
 
923
                *p_frame_type = PJMEDIA_JB_NORMAL_FRAME;
 
924
            } else {
 
925
                *p_frame_type = PJMEDIA_JB_MISSING_FRAME;
 
926
                jb->jb_lost++;
 
927
            }
 
928
 
 
929
            /* Store delay history at the first GET */
 
930
            if (jb->jb_last_op == JB_OP_PUT) {
 
931
                unsigned cur_size;
 
932
 
 
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);
 
937
            }
 
938
        } else {
 
939
            /* Jitter buffer is empty */
 
940
            if (jb->jb_prefetch)
 
941
                jb->jb_status = JB_STATUS_PREFETCHING;
 
942
 
 
943
            //pj_bzero(frame, jb->jb_frame_size);
 
944
            *p_frame_type = PJMEDIA_JB_ZERO_EMPTY_FRAME;
 
945
            if (size)
 
946
                *size = 0;
 
947
 
 
948
            jb->jb_empty++;
 
949
        }
 
950
    }
 
951
 
 
952
    jb->jb_level++;
 
953
    jbuf_update(jb, JB_OP_GET);
 
954
}
 
955
 
 
956
/*
 
957
 * Get jitter buffer state.
 
958
 */
 
959
PJ_DEF(pj_status_t) pjmedia_jbuf_get_state( const pjmedia_jbuf *jb,
 
960
                                            pjmedia_jb_state *state )
 
961
{
 
962
    PJ_ASSERT_RETURN(jb && state, PJ_EINVAL);
 
963
 
 
964
    state->frame_size = jb->jb_frame_size;
 
965
    state->min_prefetch = jb->jb_min_prefetch;
 
966
    state->max_prefetch = jb->jb_max_prefetch;
 
967
    
 
968
    state->burst = jb->jb_eff_level;
 
969
    state->prefetch = jb->jb_prefetch;
 
970
    state->size = jb_framelist_eff_size(&jb->jb_framelist);
 
971
    
 
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);
 
976
    
 
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;
 
981
 
 
982
    return PJ_SUCCESS;
 
983
}
 
984