Changeset 2578 for pjproject/trunk


Ignore:
Timestamp:
Apr 6, 2009 5:05:34 PM (15 years ago)
Author:
nanang
Message:

Ticket #762: Major updates on jitter buffer:

  • Updated loop condition in put_frame() to avoid possibility of infinite loop.
  • Added JB capabilities to handle sequence restart & jump.
  • Updated jitter calculation, e.g: reset max_hist_level after updating prefetch, avoid updating prefetch when burst level is exceeding max_burst.
  • Updated shrinking method to be less agressive (only shrink JB when JB size is twice larger than burst level).
  • Updated the way JB switching status from 'initializing' to 'processing' by waiting for some OP switch cycles.
  • Few simplifications in framelist process, e.g: replacing fields 'empty' & 'tail' with 'size'.
  • Minor updates: comments, shortened framelist field names, added some JB states for reporting/monitoring purpose.
Location:
pjproject/trunk/pjmedia
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/include/pjmedia/jbuf.h

    r2394 r2578  
    6767 
    6868/** 
    69  * This structure describes jitter buffer current status. 
     69 * This structure describes jitter buffer state. 
    7070 */ 
    7171struct pjmedia_jb_state 
    7272{ 
     73    /* Setting */ 
    7374    unsigned    frame_size;         /**< Individual frame size, in bytes.   */ 
    74     unsigned    prefetch;           /**< Current prefetch value, in frames  */ 
    7575    unsigned    min_prefetch;       /**< Minimum allowed prefetch, in frms. */ 
    7676    unsigned    max_prefetch;       /**< Maximum allowed prefetch, in frms. */ 
     77 
     78    /* Status */ 
     79    unsigned    prefetch;           /**< Current prefetch value, in frames  */ 
    7780    unsigned    size;               /**< Current buffer size, in frames.    */ 
     81 
     82    /* Statistic */ 
    7883    unsigned    avg_delay;          /**< Average delay, in ms.              */ 
    7984    unsigned    min_delay;          /**< Minimum delay, in ms.              */ 
    8085    unsigned    max_delay;          /**< Maximum delay, in ms.              */ 
    81     unsigned    dev_delay;          /**< Standard deviation of delay, in ms. */ 
     86    unsigned    dev_delay;          /**< Standard deviation of delay, in ms.*/ 
     87    unsigned    avg_burst;          /**< Average burst, in frames.          */ 
     88    unsigned    lost;               /**< Number of lost frames.             */ 
     89    unsigned    discard;            /**< Number of discarded frames.        */ 
     90    unsigned    empty;              /**< Number of empty on GET events.     */ 
    8291}; 
    8392 
  • pjproject/trunk/pjmedia/src/pjmedia/jbuf.c

    r2485 r2578  
    3232#define THIS_FILE   "jbuf.c" 
    3333 
     34 
     35/* Minimal difference between JB size and 2*burst-level to perform  
     36 * JB shrinking.  
     37 */ 
    3438#define SAFE_SHRINKING_DIFF     1 
     39 
     40/* Minimal gap (in ms) between JB shrinking */ 
    3541#define MIN_SHRINK_GAP_MSEC     200 
    3642 
     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 */ 
    3760typedef struct jb_framelist_t 
    3861{ 
    39     char        *flist_buffer; 
    40     int         *flist_frame_type; 
    41     pj_size_t   *flist_content_len; 
    42     pj_uint32_t *flist_bit_info; 
    43     unsigned     flist_frame_size; 
    44     unsigned     flist_max_count; 
    45     unsigned     flist_empty; 
    46     unsigned     flist_head; 
    47     unsigned     flist_tail; 
    48     unsigned     flist_origin; 
     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    int              origin;            /**< original index of flist_head   */ 
    4977} jb_framelist_t; 
    5078 
     
    5280struct pjmedia_jbuf 
    5381{ 
    54     pj_str_t        name;                 // jitter buffer name 
    55     jb_framelist_t  jb_framelist; 
    56     pj_size_t       jb_frame_size;        // frame size  
    57     unsigned        jb_frame_ptime;       // frame duration. 
    58     pj_size_t       jb_max_count;         // max frames in the jitter framelist->flist_buffer 
    59  
    60     int             jb_level;             // delay between source & destination 
    61                                           // (calculated according of the number of get/put operations) 
    62     int             jb_max_hist_level;    // max level during the last level calculations 
    63     int             jb_stable_hist;       // num of times the delay has been lower then the prefetch num 
    64     int             jb_last_op;           // last operation executed on the framelist->flist_buffer (put/get) 
    65     int             jb_last_seq_no;       // seq no. of the last frame inserted to the framelist->flist_buffer 
    66     int             jb_prefetch;          // no. of frame to insert before removing some 
    67                                           // (at the beginning of the framelist->flist_buffer operation) 
    68     int             jb_prefetch_cnt;      // prefetch counter 
    69     int             jb_def_prefetch;      // Default prefetch 
    70     int             jb_min_prefetch;      // Minimum allowable prefetch 
    71     int             jb_max_prefetch;      // Maximum allowable prefetch 
    72     int             jb_status;            // status is 'init' until the first 'put' operation 
    73     pj_math_stat    jb_delay;             // Delay statistics of jitter buffer (in frame unit) 
    74  
    75     unsigned        jb_last_del_seq;      // Seq # of last frame deleted 
    76     unsigned        jb_min_shrink_gap;    // How often can we shrink 
     82    /* Settings (consts) */ 
     83    pj_str_t        jb_name;            /**< jitter buffer name             */ 
     84    pj_size_t       jb_frame_size;      /**< frame size                     */ 
     85    unsigned        jb_frame_ptime;     /**< frame duration.                */ 
     86    pj_size_t       jb_max_count;       /**< capacity of jitter buffer,  
     87                                             in frames                      */ 
     88    int             jb_def_prefetch;    /**< Default prefetch               */ 
     89    int             jb_min_prefetch;    /**< Minimum allowable prefetch     */ 
     90    int             jb_max_prefetch;    /**< Maximum allowable prefetch     */ 
     91    int             jb_max_burst;       /**< maximum possible burst, whenever 
     92                                             burst exceeds this value, it  
     93                                             won't be included in level  
     94                                             calculation                    */ 
     95    int             jb_min_shrink_gap;  /**< How often can we shrink        */ 
     96 
     97    /* Buffer */ 
     98    jb_framelist_t  jb_framelist;       /**< the buffer                     */ 
     99 
     100    /* States */ 
     101    int             jb_level;           /**< delay between source &  
     102                                             destination (calculated according  
     103                                             of the number of burst get/put  
     104                                             operations)                    */ 
     105    int             jb_max_hist_level;  /**< max level during the last level  
     106                                             calculations                   */ 
     107    int             jb_stable_hist;     /**< num of times the delay has been  
     108                                             lower then the prefetch num    */ 
     109    int             jb_last_op;         /**< last operation executed  
     110                                             (put/get)                      */ 
     111    int             jb_prefetch;        /**< no. of frame to insert before  
     112                                             removing some (at the beginning  
     113                                             of the framelist->content  
     114                                             operation), the value may be 
     115                                             continuously updated based on 
     116                                             current frame burst level.     */ 
     117    int             jb_status;          /**< status is 'init' until the first  
     118                                             'put' operation                */ 
     119    int             jb_init_cycle_cnt;  /**< status is 'init' until the first  
     120                                             'put' operation                */ 
     121    int             jb_last_del_seq;    /**< Seq # of last frame deleted    */ 
     122 
     123    /* Statistics */ 
     124    pj_math_stat    jb_delay;           /**< Delay statistics of jitter buffer  
     125                                             (in ms)                        */ 
     126    pj_math_stat    jb_burst;           /**< Burst statistics (in frames)   */ 
     127    unsigned        jb_lost;            /**< Number of lost frames.         */ 
     128    unsigned        jb_discard;         /**< Number of discarded frames.    */ 
     129    unsigned        jb_empty;           /**< Number of empty/prefetching frame 
     130                                             returned by GET. */ 
    77131}; 
    78132 
     
    91145#endif 
    92146 
     147static pj_status_t jb_framelist_reset(jb_framelist_t *framelist); 
    93148 
    94149static pj_status_t jb_framelist_init( pj_pool_t *pool, 
     
    101156    pj_bzero(framelist, sizeof(jb_framelist_t)); 
    102157 
    103     framelist->flist_frame_size = frame_size; 
    104     framelist->flist_max_count = max_count; 
    105     framelist->flist_buffer = (char*)  
    106                               pj_pool_zalloc(pool, 
    107                                              framelist->flist_frame_size *  
    108                                              framelist->flist_max_count); 
    109  
    110     framelist->flist_frame_type = (int*) 
    111         pj_pool_zalloc(pool, sizeof(framelist->flist_frame_type[0]) *  
    112                                 framelist->flist_max_count); 
    113  
    114     framelist->flist_content_len = (pj_size_t*) 
    115         pj_pool_zalloc(pool, sizeof(framelist->flist_content_len[0]) *  
    116                                 framelist->flist_max_count); 
    117  
    118     framelist->flist_bit_info = (pj_uint32_t*) 
    119         pj_pool_zalloc(pool, sizeof(framelist->flist_bit_info[0]) *  
    120                                 framelist->flist_max_count); 
    121  
    122     framelist->flist_empty = 1; 
    123  
    124     return PJ_SUCCESS; 
     158    framelist->frame_size   = frame_size; 
     159    framelist->max_count    = max_count; 
     160    framelist->content      = (char*)  
     161                              pj_pool_alloc(pool, 
     162                                            framelist->frame_size*  
     163                                            framelist->max_count); 
     164    framelist->frame_type   = (int*) 
     165                              pj_pool_alloc(pool,  
     166                                            sizeof(framelist->frame_type[0])* 
     167                                            framelist->max_count); 
     168    framelist->content_len  = (pj_size_t*) 
     169                              pj_pool_alloc(pool,  
     170                                            sizeof(framelist->content_len[0])* 
     171                                            framelist->max_count); 
     172    framelist->bit_info     = (pj_uint32_t*) 
     173                              pj_pool_alloc(pool,  
     174                                            sizeof(framelist->bit_info[0])* 
     175                                            framelist->max_count); 
     176 
     177    return jb_framelist_reset(framelist); 
    125178 
    126179} 
     
    132185} 
    133186 
     187static pj_status_t jb_framelist_reset(jb_framelist_t *framelist)  
     188{ 
     189    framelist->head = 0; 
     190    framelist->origin = INVALID_OFFSET; 
     191    framelist->size = 0; 
     192 
     193    //pj_bzero(framelist->content,  
     194    //       framelist->frame_size *  
     195    //       framelist->max_count); 
     196 
     197    pj_memset(framelist->frame_type, 
     198              PJMEDIA_JB_MISSING_FRAME, 
     199              sizeof(framelist->frame_type[0]) *  
     200              framelist->max_count); 
     201 
     202    pj_bzero(framelist->content_len,  
     203             sizeof(framelist->content_len[0]) *  
     204             framelist->max_count); 
     205 
     206    //pj_bzero(framelist->bit_info, 
     207    //       sizeof(framelist->bit_info[0]) *  
     208    //       framelist->max_count); 
     209 
     210    return PJ_SUCCESS; 
     211} 
     212 
    134213 
    135214static unsigned jb_framelist_size(jb_framelist_t *framelist)  
    136215{ 
    137     if (framelist->flist_tail == framelist->flist_head) { 
    138         return framelist->flist_empty ? 0 : framelist->flist_max_count; 
    139     } else { 
    140         return (framelist->flist_tail - framelist->flist_head +  
    141                 framelist->flist_max_count) % framelist->flist_max_count; 
    142     } 
     216    return framelist->size; 
     217} 
     218 
     219static unsigned jb_framelist_origin(jb_framelist_t *framelist)  
     220{ 
     221    return framelist->origin; 
    143222} 
    144223 
     
    149228                                  pj_uint32_t *bit_info)  
    150229{ 
    151     if (!framelist->flist_empty) { 
     230    if (framelist->size) { 
    152231        pj_memcpy(frame,  
    153                   framelist->flist_buffer +  
    154                     framelist->flist_head * framelist->flist_frame_size, 
    155                   framelist->flist_frame_size); 
     232                  framelist->content +  
     233                  framelist->head * framelist->frame_size, 
     234                  framelist->frame_size); 
    156235        *p_type = (pjmedia_jb_frame_type)  
    157                   framelist->flist_frame_type[framelist->flist_head]; 
     236                  framelist->frame_type[framelist->head]; 
    158237        if (size) 
    159             *size   = framelist->flist_content_len[framelist->flist_head]; 
     238            *size   = framelist->content_len[framelist->head]; 
    160239        if (bit_info) 
    161             *bit_info = framelist->flist_bit_info[framelist->flist_head]; 
    162  
    163         pj_bzero(framelist->flist_buffer +  
    164                     framelist->flist_head * framelist->flist_frame_size, 
    165                   framelist->flist_frame_size); 
    166         framelist->flist_frame_type[framelist->flist_head] =  
    167             PJMEDIA_JB_MISSING_FRAME; 
    168         framelist->flist_content_len[framelist->flist_head] = 0; 
    169  
    170         framelist->flist_origin++; 
    171         framelist->flist_head = (framelist->flist_head + 1 ) %  
    172                                 framelist->flist_max_count; 
    173         if (framelist->flist_head == framelist->flist_tail)  
    174             framelist->flist_empty = PJ_TRUE; 
     240            *bit_info = framelist->bit_info[framelist->head]; 
     241 
     242        //pj_bzero(framelist->content +  
     243        //       framelist->head * framelist->frame_size, 
     244        //       framelist->frame_size); 
     245        framelist->frame_type[framelist->head] = PJMEDIA_JB_MISSING_FRAME; 
     246        framelist->content_len[framelist->head] = 0; 
     247        framelist->bit_info[framelist->head] = 0; 
     248 
     249        framelist->origin++; 
     250        framelist->head = (framelist->head + 1) % framelist->max_count; 
     251        framelist->size--; 
    175252         
    176253        return PJ_TRUE; 
    177  
    178254    } else { 
    179         pj_bzero(frame, framelist->flist_frame_size); 
     255        pj_bzero(frame, framelist->frame_size); 
     256 
    180257        return PJ_FALSE; 
    181258    } 
     
    183260 
    184261 
    185 static void jb_framelist_remove_head( jb_framelist_t *framelist, 
    186                                       unsigned count)  
    187 { 
    188     unsigned cur_size; 
    189  
    190     cur_size = jb_framelist_size(framelist); 
    191     if (count > cur_size)  
    192         count = cur_size; 
     262static unsigned jb_framelist_remove_head(jb_framelist_t *framelist, 
     263                                         unsigned count)  
     264{ 
     265    if (count > framelist->size)  
     266        count = framelist->size; 
    193267 
    194268    if (count) { 
    195         // may be done in two steps if overlapping 
     269        /* may be done in two steps if overlapping */ 
    196270        unsigned step1,step2; 
    197         unsigned tmp = framelist->flist_head+count; 
    198  
    199         if (tmp > framelist->flist_max_count) { 
    200             step1 = framelist->flist_max_count - framelist->flist_head; 
     271        unsigned tmp = framelist->head+count; 
     272 
     273        if (tmp > framelist->max_count) { 
     274            step1 = framelist->max_count - framelist->head; 
    201275            step2 = count-step1; 
    202276        } else { 
     
    205279        } 
    206280 
    207         pj_bzero(framelist->flist_buffer +  
    208                     framelist->flist_head * framelist->flist_frame_size, 
    209                   step1*framelist->flist_frame_size); 
    210         pj_memset(framelist->flist_frame_type+framelist->flist_head, 
     281        //pj_bzero(framelist->content +  
     282        //          framelist->head * framelist->frame_size, 
     283        //          step1*framelist->frame_size); 
     284        pj_memset(framelist->frame_type+framelist->head, 
    211285                  PJMEDIA_JB_MISSING_FRAME, 
    212                   step1*sizeof(framelist->flist_frame_type[0])); 
    213         pj_bzero(framelist->flist_content_len+framelist->flist_head, 
    214                   step1*sizeof(framelist->flist_content_len[0])); 
     286                  step1*sizeof(framelist->frame_type[0])); 
     287        pj_bzero(framelist->content_len+framelist->head, 
     288                  step1*sizeof(framelist->content_len[0])); 
    215289 
    216290        if (step2) { 
    217             pj_bzero( framelist->flist_buffer, 
    218                       step2*framelist->flist_frame_size); 
    219             pj_memset(framelist->flist_frame_type, 
     291            //pj_bzero( framelist->content, 
     292            //        step2*framelist->frame_size); 
     293            pj_memset(framelist->frame_type, 
    220294                      PJMEDIA_JB_MISSING_FRAME, 
    221                       step2*sizeof(framelist->flist_frame_type[0])); 
    222             pj_bzero (framelist->flist_content_len, 
    223                       step2*sizeof(framelist->flist_content_len[0])); 
    224         } 
    225  
    226         // update pointers 
    227         framelist->flist_origin += count; 
    228         framelist->flist_head = (framelist->flist_head + count) %  
    229                                 framelist->flist_max_count; 
    230         if (framelist->flist_head == framelist->flist_tail)  
    231             framelist->flist_empty = PJ_TRUE; 
    232     } 
    233 } 
    234  
    235  
    236 static pj_bool_t jb_framelist_put_at(jb_framelist_t *framelist, 
    237                                      unsigned index, 
    238                                      const void *frame, 
    239                                      unsigned frame_size, 
    240                                      pj_uint32_t bit_info) 
    241 { 
     295                      step2*sizeof(framelist->frame_type[0])); 
     296            pj_bzero (framelist->content_len, 
     297                      step2*sizeof(framelist->content_len[0])); 
     298        } 
     299 
     300        /* update states */ 
     301        framelist->origin += count; 
     302        framelist->head = (framelist->head + count) % framelist->max_count; 
     303        framelist->size -= count; 
     304    } 
     305     
     306    return count; 
     307} 
     308 
     309 
     310static pj_status_t jb_framelist_put_at(jb_framelist_t *framelist, 
     311                                       int index, 
     312                                       const void *frame, 
     313                                       unsigned frame_size, 
     314                                       pj_uint32_t bit_info) 
     315{ 
     316    int distance; 
    242317    unsigned where; 
    243  
    244     assert(frame_size <= framelist->flist_frame_size); 
    245  
    246     if (!framelist->flist_empty) { 
    247         unsigned max_index; 
    248         unsigned cur_size; 
    249  
    250         // too late 
    251         if (index < framelist->flist_origin)  
    252             return PJ_FALSE; 
    253  
    254         // too soon 
    255         max_index = framelist->flist_origin + framelist->flist_max_count - 1; 
    256         if (index > max_index) 
    257             return PJ_FALSE; 
    258  
    259         where = (index - framelist->flist_origin + framelist->flist_head) %  
    260                 framelist->flist_max_count; 
    261  
    262         // update framelist->flist_tail pointer 
    263         cur_size = jb_framelist_size(framelist); 
    264         if (index >= framelist->flist_origin + cur_size) { 
    265             unsigned diff = (index - (framelist->flist_origin + cur_size)); 
    266             framelist->flist_tail = (framelist->flist_tail + diff + 1) %  
    267                                     framelist->flist_max_count; 
    268         } 
    269     } else { 
    270         // check if frame is not too late, but watch out for sequence restart. 
    271         if (index < framelist->flist_origin &&  
    272             framelist->flist_origin - index < 0x7FFF)  
    273         { 
    274             return PJ_FALSE; 
    275         } 
    276  
    277         where = framelist->flist_tail; 
    278         framelist->flist_origin = index; 
    279         framelist->flist_tail = (framelist->flist_tail + 1) %  
    280                                 framelist->flist_max_count; 
    281         framelist->flist_empty = PJ_FALSE; 
    282     } 
    283  
    284     pj_memcpy(framelist->flist_buffer + where * framelist->flist_frame_size,  
     318    enum { MAX_MISORDER = 100 }; 
     319    enum { MAX_DROPOUT = 3000 }; 
     320 
     321    assert(frame_size <= framelist->frame_size); 
     322 
     323    /* the first ever frame since inited/resetted. */ 
     324    if (framelist->origin == INVALID_OFFSET) 
     325        framelist->origin = index; 
     326 
     327    /* too late or duplicated or sequence restart */ 
     328    if (index < framelist->origin) { 
     329        if (framelist->origin - index < MAX_MISORDER) { 
     330            /* too late or duplicated */ 
     331            return PJ_ETOOSMALL; 
     332        } else { 
     333            /* sequence restart */ 
     334            framelist->origin = index - framelist->size; 
     335        } 
     336    } 
     337 
     338    /* too soon or jump too far */ 
     339    distance = index - framelist->origin; 
     340    if (distance >= (int)framelist->max_count) { 
     341        if (distance > MAX_DROPOUT) { 
     342            /* jump too far */ 
     343            jb_framelist_reset(framelist); 
     344            framelist->origin = index; 
     345            distance = 0; 
     346        } else { 
     347            /* too soon, buffer is not enough */ 
     348            return PJ_ETOOMANY; 
     349        } 
     350    } 
     351 
     352    /* get the slot position */ 
     353    where = (framelist->head + distance) % framelist->max_count; 
     354 
     355    /* if the slot is occupied, it must be duplicated frame, ignore it. */ 
     356    if (framelist->frame_type[where] != PJMEDIA_JB_MISSING_FRAME) 
     357        return PJ_EEXISTS; 
     358 
     359    /* put the frame into the slot */ 
     360    pj_memcpy(framelist->content + where * framelist->frame_size, 
    285361              frame, frame_size); 
    286  
    287     framelist->flist_frame_type[where] = PJMEDIA_JB_NORMAL_FRAME; 
    288     framelist->flist_content_len[where] = frame_size; 
    289     framelist->flist_bit_info[where] = bit_info; 
    290  
    291     return PJ_TRUE; 
     362    framelist->frame_type[where] = PJMEDIA_JB_NORMAL_FRAME; 
     363    framelist->content_len[where] = frame_size; 
     364    framelist->bit_info[where] = bit_info; 
     365    if (framelist->origin + (int)framelist->size <= index) 
     366        framelist->size = distance + 1; 
     367 
     368    return PJ_SUCCESS; 
    292369} 
    293370 
     
    318395        return status; 
    319396 
    320     pj_strdup_with_null(pool, &jb->name, name); 
     397    pj_strdup_with_null(pool, &jb->jb_name, name); 
    321398    jb->jb_frame_size    = frame_size; 
    322399    jb->jb_frame_ptime   = ptime; 
    323     jb->jb_last_seq_no   = -1; 
    324     jb->jb_level         = 0; 
    325     jb->jb_last_op       = JB_OP_INIT; 
    326400    jb->jb_prefetch      = PJ_MIN(PJMEDIA_JB_DEFAULT_INIT_DELAY,max_count*4/5); 
    327     jb->jb_prefetch_cnt  = 0; 
    328401    jb->jb_min_prefetch  = 0; 
    329402    jb->jb_max_prefetch  = max_count*4/5; 
    330     jb->jb_stable_hist   = 0; 
    331     jb->jb_status        = JB_STATUS_INITIALIZING; 
    332     jb->jb_max_hist_level = 0; 
    333403    jb->jb_max_count     = max_count; 
    334404    jb->jb_min_shrink_gap= MIN_SHRINK_GAP_MSEC / ptime; 
    335  
     405    jb->jb_max_burst     = MAX_BURST_MSEC / ptime; 
    336406    pj_math_stat_init(&jb->jb_delay); 
     407    pj_math_stat_init(&jb->jb_burst); 
     408 
     409    pjmedia_jbuf_reset(jb); 
    337410 
    338411    *p_jb = jb; 
     
    383456PJ_DEF(pj_status_t) pjmedia_jbuf_reset(pjmedia_jbuf *jb) 
    384457{ 
    385     jb->jb_last_seq_no   = -1; 
    386458    jb->jb_level         = 0; 
    387459    jb->jb_last_op       = JB_OP_INIT; 
    388     jb->jb_prefetch_cnt  = 0; 
    389460    jb->jb_stable_hist   = 0; 
    390461    jb->jb_status        = JB_STATUS_INITIALIZING; 
    391     jb->jb_max_hist_level = 0; 
    392  
    393     jb_framelist_remove_head(&jb->jb_framelist,  
    394                              jb_framelist_size(&jb->jb_framelist)); 
    395  
    396     pj_math_stat_init(&jb->jb_delay); 
    397      
     462    jb->jb_init_cycle_cnt= 0; 
     463    jb->jb_max_hist_level= 0; 
     464 
     465    jb_framelist_reset(&jb->jb_framelist); 
     466 
    398467    return PJ_SUCCESS; 
    399468} 
     
    411480 
    412481    cur_size = jb_framelist_size(&jb->jb_framelist); 
    413  
    414     /* Only apply burst-level calculation on PUT operation since if VAD is  
    415      * active the burst-level may not be accurate. 
     482    pj_math_stat_update(&jb->jb_burst, jb->jb_level); 
     483    jb->jb_max_hist_level = PJ_MAX(jb->jb_max_hist_level, jb->jb_level); 
     484 
     485    /* Burst level is decreasing */ 
     486    if (jb->jb_level < jb->jb_prefetch) { 
     487 
     488        enum { STABLE_HISTORY_LIMIT = 100 }; 
     489         
     490        jb->jb_stable_hist++; 
     491         
     492        /* Only update the prefetch if 'stable' condition is reached  
     493         * (not just short time impulse) 
     494         */ 
     495        if (jb->jb_stable_hist > STABLE_HISTORY_LIMIT) { 
     496         
     497            diff = (jb->jb_prefetch - jb->jb_max_hist_level) / 3; 
     498 
     499            if (diff < 1) 
     500                diff = 1; 
     501 
     502            jb->jb_prefetch -= diff; 
     503            if (jb->jb_prefetch < jb->jb_min_prefetch)  
     504                jb->jb_prefetch = jb->jb_min_prefetch; 
     505 
     506            /* Reset history */ 
     507            jb->jb_max_hist_level = 0; 
     508            jb->jb_stable_hist = 0; 
     509 
     510            TRACE__((jb->jb_name.ptr,"jb updated(1), prefetch=%d, size=%d", 
     511                     jb->jb_prefetch, cur_size)); 
     512        } 
     513    } 
     514 
     515    /* Burst level is increasing */ 
     516    else if (jb->jb_level > jb->jb_prefetch) { 
     517 
     518        /* Instaneous set prefetch to recent maximum level (max_hist_level) */ 
     519        jb->jb_prefetch = PJ_MIN(jb->jb_max_hist_level, 
     520                                 (int)(jb->jb_max_count*4/5)); 
     521        if (jb->jb_prefetch > jb->jb_max_prefetch) 
     522            jb->jb_prefetch = jb->jb_max_prefetch; 
     523 
     524        jb->jb_stable_hist = 0; 
     525        /* Do not reset max_hist_level. */ 
     526        //jb->jb_max_hist_level = 0; 
     527 
     528        TRACE__((jb->jb_name.ptr,"jb updated(2), prefetch=%d, size=%d",  
     529                 jb->jb_prefetch, cur_size)); 
     530    } 
     531 
     532    /* Level is unchanged */ 
     533    else { 
     534        jb->jb_stable_hist = 0; 
     535    } 
     536} 
     537 
     538PJ_INLINE(void) jbuf_update(pjmedia_jbuf *jb, int oper) 
     539{ 
     540    int diff, burst_level; 
     541 
     542    if(jb->jb_last_op != oper) { 
     543        jb->jb_last_op = oper; 
     544 
     545        if (jb->jb_status == JB_STATUS_INITIALIZING) { 
     546            /* Switch status 'initializing' -> 'processing' after some OP  
     547             * switch cycles and current OP is GET (burst level is calculated  
     548             * based on PUT burst), so burst calculation is guaranted to be 
     549             * performed right after the status switching. 
     550             */ 
     551            if (++jb->jb_init_cycle_cnt >= INIT_CYCLE && oper == JB_OP_GET) { 
     552                jb->jb_status = JB_STATUS_PROCESSING; 
     553            } else { 
     554                jb->jb_level = 0; 
     555                return; 
     556            } 
     557        } 
     558 
     559        /* Perform jitter calculation based on PUT burst-level only, since  
     560         * GET burst-level may not be accurate, e.g: when VAD is active. 
     561         * Note that when burst-level is too big, i.e: exceeds jb_max_burst, 
     562         * the GET op may be idle, in this case, we better skip the jitter  
     563         * calculation. 
     564         */ 
     565        if (oper == JB_OP_GET && jb->jb_level < jb->jb_max_burst) 
     566            jbuf_calculate_jitter(jb); 
     567 
     568        jb->jb_level = 0; 
     569    } 
     570 
     571    /* These code is used for shortening the delay in the jitter buffer. 
     572     * It needs shrink only when there is possibility of drift. Drift 
     573     * detection is performed by inspecting the jitter buffer size, if 
     574     * its size is twice of current burst level, there can be drift. 
     575     * 
     576     * Moreover, normally drift level is quite low, so JB shouldn't need 
     577     * to shrink aggresively, it will shrink maximum one frame per  
     578     * MIN_SHRINK_GAP_MSEC ms. Theoritically, JB may handle drift level  
     579     * as much as = FRAME_PTIME/MIN_SHRINK_GAP_MSEC * 100% 
     580     * 
     581     * Whenever there is drift, where PUT > GET, this method will keep  
     582     * the latency (JB size) as much as twice of burst level. 
    416583     */ 
    417     if (jb->jb_last_op == JB_OP_PUT) { 
    418  
    419         jb->jb_max_hist_level = PJ_MAX(jb->jb_max_hist_level,jb->jb_level); 
    420  
    421         /* Level is decreasing */ 
    422         if (jb->jb_level < jb->jb_prefetch) { 
    423  
    424             enum { STABLE_HISTORY_LIMIT = 100 }; 
    425              
    426             jb->jb_stable_hist++; 
    427              
    428             /* Only update the prefetch if 'stable' condition is reached  
    429              * (not just short time impulse) 
    430              */ 
    431             if (jb->jb_stable_hist > STABLE_HISTORY_LIMIT) { 
    432                  
    433                 diff = (jb->jb_prefetch - jb->jb_max_hist_level) / 3; 
    434  
    435                 if (diff < 1) 
    436                     diff = 1; 
    437  
    438                 /* Update max_hist_level. */ 
    439                 jb->jb_max_hist_level = jb->jb_prefetch; 
    440  
    441                 jb->jb_prefetch -= diff; 
    442                 if (jb->jb_prefetch < jb->jb_min_prefetch)  
    443                     jb->jb_prefetch = jb->jb_min_prefetch; 
    444  
    445                 jb->jb_stable_hist = 0; 
    446  
    447                 TRACE__((jb->name.ptr,"jb updated(1), prefetch=%d, size=%d",  
    448                          jb->jb_prefetch, cur_size)); 
    449             } 
    450         } 
    451  
    452         /* Level is increasing */ 
    453         else if (jb->jb_level > jb->jb_prefetch) { 
    454  
    455             /* Instaneous set prefetch */ 
    456             jb->jb_prefetch = PJ_MIN(jb->jb_max_hist_level, 
    457                                      (int)(jb->jb_max_count*4/5)); 
    458             if (jb->jb_prefetch > jb->jb_max_prefetch) 
    459                 jb->jb_prefetch = jb->jb_max_prefetch; 
    460  
    461             jb->jb_stable_hist = 0; 
    462             // Keep max_hist_level. 
    463             //jb->jb_max_hist_level = 0; 
    464  
    465             TRACE__((jb->name.ptr,"jb updated(2), prefetch=%d, size=%d",  
    466                      jb->jb_prefetch, cur_size)); 
    467         } 
    468  
    469         /* Level is unchanged */ 
    470         else { 
    471             jb->jb_stable_hist = 0; 
    472         } 
    473     } 
    474  
    475     /* These code is used for shortening the delay in the jitter buffer. */ 
    476     // Shrinking based on max_hist_level (recent max level). 
    477     //diff = cur_size - jb->jb_prefetch; 
    478     diff = cur_size - jb->jb_max_hist_level; 
    479     if (diff > SAFE_SHRINKING_DIFF &&  
    480         jb->jb_framelist.flist_origin-jb->jb_last_del_seq > jb->jb_min_shrink_gap) 
    481     { 
    482         /* Shrink slowly */ 
    483         diff = 1; 
    484  
    485         /* Drop frame(s)! */ 
    486         jb_framelist_remove_head(&jb->jb_framelist, diff); 
    487         jb->jb_last_del_seq = jb->jb_framelist.flist_origin; 
    488  
    489         pj_math_stat_update(&jb->jb_delay, cur_size - diff); 
    490  
    491         TRACE__((jb->name.ptr,  
    492                  "JB shrinking %d frame(s), size=%d", diff, 
    493                  jb_framelist_size(&jb->jb_framelist))); 
    494     } else { 
    495         pj_math_stat_update(&jb->jb_delay, cur_size); 
    496     } 
    497  
    498     jb->jb_level = 0; 
    499 } 
    500  
    501 PJ_INLINE(void) jbuf_update(pjmedia_jbuf *jb, int oper) 
    502 { 
    503     if(jb->jb_last_op != oper) { 
    504         jbuf_calculate_jitter(jb); 
    505         jb->jb_last_op = oper; 
     584 
     585    if (jb->jb_status != JB_STATUS_PROCESSING) 
     586        return; 
     587 
     588    burst_level = PJ_MAX(jb->jb_prefetch, jb->jb_level); 
     589    diff = jb_framelist_size(&jb->jb_framelist) - burst_level*2; 
     590 
     591    if (diff >= SAFE_SHRINKING_DIFF) { 
     592        /* Check and adjust jb_last_del_seq, in case there was seq restart */ 
     593        if (jb->jb_framelist.origin < jb->jb_last_del_seq) 
     594            jb->jb_last_del_seq = jb->jb_framelist.origin; 
     595 
     596        if (jb->jb_framelist.origin - jb->jb_last_del_seq >= 
     597            jb->jb_min_shrink_gap) 
     598        { 
     599            /* Shrink slowly, one frame per cycle */ 
     600            diff = 1; 
     601 
     602            /* Drop frame(s)! */ 
     603            diff = jb_framelist_remove_head(&jb->jb_framelist, diff); 
     604            jb->jb_last_del_seq = jb->jb_framelist.origin; 
     605            jb->jb_discard += diff; 
     606 
     607            TRACE__((jb->jb_name.ptr,  
     608                     "JB shrinking %d frame(s), cur size=%d", diff, 
     609                     jb_framelist_size(&jb->jb_framelist))); 
     610        } 
    506611    } 
    507612} 
     
    523628{ 
    524629    pj_size_t min_frame_size; 
    525     int seq_diff; 
    526  
    527     if (jb->jb_last_seq_no == -1)       { 
    528         jb->jb_last_seq_no = frame_seq - 1; 
    529     } 
    530  
    531     seq_diff = frame_seq - jb->jb_last_seq_no; 
    532     jb->jb_last_seq_no = PJ_MAX(jb->jb_last_seq_no, frame_seq); 
    533     if (seq_diff > 0) jb->jb_level += seq_diff; 
    534  
    535     if(jb->jb_status == JB_STATUS_INITIALIZING) { 
    536         jb->jb_status = JB_STATUS_PROCESSING; 
    537         jb->jb_level = 0; 
    538     } else { 
     630    int prev_size, cur_size; 
     631    pj_status_t status; 
     632 
     633    /* Get JB size before PUT */ 
     634    prev_size = jb_framelist_size(&jb->jb_framelist); 
     635     
     636    /* Attempt to store the frame */ 
     637    min_frame_size = PJ_MIN(frame_size, jb->jb_frame_size); 
     638    status = jb_framelist_put_at(&jb->jb_framelist, frame_seq, frame, 
     639                                 min_frame_size, bit_info); 
     640     
     641    /* Jitter buffer is full, cannot store the frame */ 
     642    while (status == PJ_ETOOMANY) { 
     643        unsigned removed; 
     644 
     645        removed = jb_framelist_remove_head(&jb->jb_framelist, 
     646                                           PJ_MAX(jb->jb_max_count/4, 1)); 
     647        status = jb_framelist_put_at(&jb->jb_framelist, frame_seq, frame, 
     648                                     min_frame_size, bit_info); 
     649 
     650        jb->jb_discard += removed; 
     651    } 
     652 
     653    /* Get JB size after PUT */ 
     654    cur_size = jb_framelist_size(&jb->jb_framelist); 
     655 
     656    /* Return the flag if this frame is discarded */ 
     657    if (discarded) 
     658        *discarded = (status != PJ_SUCCESS); 
     659 
     660    if (status == PJ_SUCCESS) { 
     661        if (jb->jb_status == JB_STATUS_PREFETCHING) { 
     662            TRACE__((jb->jb_name.ptr, "PUT prefetch_cnt=%d/%d",  
     663                     cur_size, jb->jb_prefetch)); 
     664            if (cur_size >= jb->jb_prefetch) 
     665                jb->jb_status = JB_STATUS_PROCESSING; 
     666        } 
     667        jb->jb_level += (cur_size > prev_size ? cur_size-prev_size : 1); 
    539668        jbuf_update(jb, JB_OP_PUT); 
    540     } 
    541  
    542     min_frame_size = PJ_MIN(frame_size, jb->jb_frame_size); 
    543     if (seq_diff > 0) { 
    544  
    545         while (jb_framelist_put_at(&jb->jb_framelist, frame_seq, frame, 
    546                                    min_frame_size, bit_info) == PJ_FALSE) 
    547         { 
    548             jb_framelist_remove_head(&jb->jb_framelist, 
    549                                      PJ_MAX(jb->jb_max_count/4,1) ); 
    550         } 
    551  
    552         if (jb->jb_prefetch_cnt < jb->jb_prefetch) { 
    553             jb->jb_prefetch_cnt += seq_diff; 
    554              
    555             TRACE__((jb->name.ptr, "PUT prefetch_cnt=%d/%d",  
    556                      jb->jb_prefetch_cnt, jb->jb_prefetch)); 
    557  
    558             if (jb->jb_status == JB_STATUS_PREFETCHING &&  
    559                 jb->jb_prefetch_cnt >= jb->jb_prefetch) 
    560             { 
    561                 jb->jb_status = JB_STATUS_PROCESSING; 
    562             } 
    563         } 
    564  
    565  
    566  
    567         if (discarded) 
    568             *discarded = PJ_FALSE; 
    569     } 
    570     else 
    571     { 
    572         pj_bool_t res; 
    573         res = jb_framelist_put_at(&jb->jb_framelist,frame_seq,frame, 
    574                                   min_frame_size, bit_info); 
    575         if (discarded) 
    576             *discarded = !res; 
    577     } 
     669    } else 
     670        jb->jb_discard++; 
    578671} 
    579672 
     
    597690                                     pj_uint32_t *bit_info) 
    598691{ 
    599     pjmedia_jb_frame_type ftype; 
    600  
    601     jb->jb_level++; 
    602  
    603     jbuf_update(jb, JB_OP_GET); 
    604  
    605     if (jb_framelist_size(&jb->jb_framelist) == 0) { 
    606         jb->jb_prefetch_cnt = 0; 
     692    int cur_size; 
     693 
     694    cur_size = jb_framelist_size(&jb->jb_framelist); 
     695 
     696    if (cur_size == 0) { 
     697        /* jitter buffer empty */ 
     698 
    607699        if (jb->jb_def_prefetch) 
    608700            jb->jb_status = JB_STATUS_PREFETCHING; 
    609     } 
    610  
    611     if (jb->jb_status == JB_STATUS_PREFETCHING &&  
    612         jb->jb_prefetch_cnt < jb->jb_prefetch) 
    613     { 
     701 
     702        //pj_bzero(frame, jb->jb_frame_size); 
     703        *p_frame_type = PJMEDIA_JB_ZERO_EMPTY_FRAME; 
     704        if (size) 
     705            *size = 0; 
     706 
     707        jb->jb_empty++; 
     708 
     709    } else if (jb->jb_status == JB_STATUS_PREFETCHING) { 
     710 
    614711        /* Can't return frame because jitter buffer is filling up 
    615712         * minimum prefetch. 
    616713         */ 
    617         pj_bzero(frame, jb->jb_frame_size); 
    618         if (jb_framelist_size(&jb->jb_framelist) == 0) 
    619             *p_frame_type = PJMEDIA_JB_ZERO_EMPTY_FRAME; 
    620         else 
    621             *p_frame_type = PJMEDIA_JB_ZERO_PREFETCH_FRAME; 
    622  
     714 
     715        //pj_bzero(frame, jb->jb_frame_size); 
     716        *p_frame_type = PJMEDIA_JB_ZERO_PREFETCH_FRAME; 
    623717        if (size) 
    624718            *size = 0; 
    625719 
    626         TRACE__((jb->name.ptr, "GET prefetch_cnt=%d/%d", 
    627                  jb->jb_prefetch_cnt, jb->jb_prefetch)); 
    628         return; 
    629     } 
    630  
    631     /* Retrieve a frame from frame list */ 
    632     if (jb_framelist_get(&jb->jb_framelist,frame,size,&ftype,bit_info) == 
    633         PJ_FALSE)  
    634     { 
    635         /* Can't return frame because jitter buffer is empty! */ 
    636         pj_bzero(frame, jb->jb_frame_size); 
    637         *p_frame_type = PJMEDIA_JB_ZERO_EMPTY_FRAME; 
    638         if (size) 
    639             *size = 0; 
    640  
    641         return; 
    642     } 
    643  
    644     /* We've successfully retrieved a frame from the frame list, but 
    645      * the frame could be a blank frame! 
    646      */ 
    647     if (ftype == PJMEDIA_JB_NORMAL_FRAME)  
    648         *p_frame_type   = PJMEDIA_JB_NORMAL_FRAME; 
    649     else  
    650         *p_frame_type   = PJMEDIA_JB_MISSING_FRAME; 
     720        TRACE__((jb->jb_name.ptr, "GET prefetch_cnt=%d/%d", 
     721                 cur_size, jb->jb_prefetch)); 
     722 
     723        jb->jb_empty++; 
     724 
     725    } else { 
     726 
     727        pjmedia_jb_frame_type ftype; 
     728        pj_bool_t res; 
     729 
     730        /* Retrieve a frame from frame list */ 
     731        res = jb_framelist_get(&jb->jb_framelist, frame, size, &ftype,  
     732                               bit_info); 
     733        pj_assert(res); 
     734 
     735        /* We've successfully retrieved a frame from the frame list, but 
     736         * the frame could be a blank frame! 
     737         */ 
     738        if (ftype == PJMEDIA_JB_NORMAL_FRAME) { 
     739            *p_frame_type = PJMEDIA_JB_NORMAL_FRAME; 
     740            pj_math_stat_update(&jb->jb_delay, cur_size * jb->jb_frame_ptime); 
     741        } else { 
     742            *p_frame_type = PJMEDIA_JB_MISSING_FRAME; 
     743            jb->jb_lost++; 
     744        } 
     745    } 
     746 
     747    jb->jb_level++; 
     748    jbuf_update(jb, JB_OP_GET); 
    651749} 
    652750 
     
    660758 
    661759    state->frame_size = jb->jb_frame_size; 
    662     state->prefetch = jb->jb_prefetch; 
    663760    state->min_prefetch = jb->jb_min_prefetch; 
    664761    state->max_prefetch = jb->jb_max_prefetch; 
     762     
     763    state->prefetch = jb->jb_prefetch; 
    665764    state->size = jb_framelist_size(&jb->jb_framelist); 
    666     state->avg_delay = jb->jb_delay.mean * jb->jb_frame_ptime; 
    667     state->min_delay = jb->jb_delay.min * jb->jb_frame_ptime; 
    668     state->max_delay = jb->jb_delay.max * jb->jb_frame_ptime; 
    669     state->dev_delay = pj_math_stat_get_stddev(&jb->jb_delay) *  
    670                        jb->jb_frame_ptime; 
     765     
     766    state->avg_delay = jb->jb_delay.mean; 
     767    state->min_delay = jb->jb_delay.min; 
     768    state->max_delay = jb->jb_delay.max; 
     769    state->dev_delay = pj_math_stat_get_stddev(&jb->jb_delay); 
     770     
     771    state->avg_burst = jb->jb_burst.mean; 
     772    state->empty = jb->jb_empty; 
     773    state->discard = jb->jb_discard; 
     774    state->lost = jb->jb_lost; 
    671775 
    672776    return PJ_SUCCESS; 
Note: See TracChangeset for help on using the changeset viewer.