Ticket #505: ticket505.patch

File ticket505.patch, 8.4 KB (added by nanang, 14 years ago)

Level calcualtion restarted on each operation switching, disabled prefetch buffering on empty, and ability to shrink its buffer based on stable burst-level.

  • pjmedia/src/pjmedia/jbuf.c

     
    2929 
    3030#define THIS_FILE   "jbuf.c" 
    3131 
     32#define SAFE_SHRINKING_DIFF     2 
     33#define USE_PREFETCH_BUFFERING  0 
    3234 
    3335typedef struct jb_framelist_t 
    3436{ 
     
    5456 
    5557    int             jb_level;             // delay between source & destination 
    5658                                          // (calculated according of the number of get/put operations) 
    57     int             jb_last_level;        // last delay  
    58     int             jb_last_jitter;       // last jitter calculated 
    59     int             jb_max_hist_jitter;   // max jitter during the last jitter calculations 
     59    int             jb_max_hist_level;    // max level during the last level calculations 
    6060    int             jb_stable_hist;       // num of times the delay has been lower then the prefetch num 
    61     unsigned        jb_op_count;          // of of operations. 
    6261    int             jb_last_op;           // last operation executed on the framelist->flist_buffer (put/get) 
    6362    int             jb_last_seq_no;       // seq no. of the last frame inserted to the framelist->flist_buffer 
    6463    int             jb_prefetch;          // no. of frame to insert before removing some 
     
    8382/* Enabling this would log the jitter buffer state about once per  
    8483 * second. 
    8584 */ 
    86 #if 0 
     85#if 1 
    8786#  define TRACE__(args)     PJ_LOG(4,args) 
    8887#else 
    8988#  define TRACE__(args) 
     
    304303    jb->jb_frame_ptime   = ptime; 
    305304    jb->jb_last_seq_no   = -1; 
    306305    jb->jb_level         = 0; 
    307     jb->jb_last_level    = 0; 
    308     jb->jb_last_jitter   = 0; 
    309306    jb->jb_last_op       = JB_OP_INIT; 
    310307    jb->jb_prefetch      = PJ_MIN(PJMEDIA_JB_DEFAULT_INIT_DELAY,max_count*4/5); 
    311308    jb->jb_prefetch_cnt  = 0; 
     
    313310    jb->jb_max_prefetch  = max_count*4/5; 
    314311    jb->jb_stable_hist   = 0; 
    315312    jb->jb_status        = JB_STATUS_INITIALIZING; 
    316     jb->jb_max_hist_jitter = 0; 
     313    jb->jb_max_hist_level = 0; 
    317314    jb->jb_max_count     = max_count; 
    318315 
    319316    *p_jb = jb; 
     
    366363{ 
    367364    jb->jb_last_seq_no   = -1; 
    368365    jb->jb_level         = 0; 
    369     jb->jb_last_level    = 0; 
    370     jb->jb_last_jitter   = 0; 
    371366    jb->jb_last_op       = JB_OP_INIT; 
    372367    jb->jb_prefetch_cnt  = 0; 
    373368    jb->jb_stable_hist   = 0; 
    374369    jb->jb_status        = JB_STATUS_INITIALIZING; 
    375     jb->jb_max_hist_jitter = 0; 
     370    jb->jb_max_hist_level = 0; 
    376371 
    377372    jb_framelist_remove_head(&jb->jb_framelist,  
    378373                             jb_framelist_size(&jb->jb_framelist)); 
     
    388383 
    389384static void jbuf_calculate_jitter(pjmedia_jbuf *jb) 
    390385{ 
    391     unsigned stable_history_limit; 
     386    int diff; 
    392387 
    393     stable_history_limit = 1000 / jb->jb_frame_ptime; 
     388    /* Only apply burst-level calculation on PUT operation since if VAD is  
     389     * active the burst-level may not be accurate. 
     390     */ 
     391    if (jb->jb_last_op == JB_OP_PUT) { 
    394392 
    395     jb->jb_last_jitter = PJ_ABS(jb->jb_level-jb->jb_last_level); 
    396     jb->jb_last_level = jb->jb_level; 
    397     jb->jb_max_hist_jitter = PJ_MAX(jb->jb_max_hist_jitter,jb->jb_last_jitter); 
    398     jb->jb_op_count++; 
     393        jb->jb_max_hist_level = PJ_MAX(jb->jb_max_hist_level,jb->jb_level); 
    399394 
    400     if (jb->jb_last_jitter < jb->jb_prefetch) { 
    401         jb->jb_stable_hist += jb->jb_last_jitter; 
    402         if (jb->jb_stable_hist > (int)stable_history_limit) { 
    403             int seq_diff = (jb->jb_prefetch - jb->jb_max_hist_jitter)/3; 
    404             if (seq_diff<1) seq_diff = 1; 
     395        /* Level is decreasing */ 
     396        if (jb->jb_level < jb->jb_prefetch) { 
    405397 
    406             jb->jb_prefetch -= seq_diff; 
    407             if (jb->jb_prefetch < jb->jb_min_prefetch)  
    408                 jb->jb_prefetch = jb->jb_min_prefetch; 
     398            static const int stable_history_limit = 100; 
     399             
     400            jb->jb_stable_hist++; 
     401             
     402            /* Only update the prefetch if 'stable' condition is reached  
     403             * (not just short time impulse) 
     404             */ 
     405            if (jb->jb_stable_hist > (int)stable_history_limit) { 
     406                diff = (jb->jb_prefetch - jb->jb_max_hist_level) / 3; 
    409407 
    410             jb->jb_stable_hist = 0; 
    411             jb->jb_max_hist_jitter = 0; 
     408                if (diff < 1) 
     409                    diff = 1; 
    412410 
    413             TRACE__((THIS_FILE,"jb updated(1), prefetch=%d, size=%d",  
    414                      jb->jb_prefetch, jb_framelist_size(&jb->jb_framelist))); 
     411                jb->jb_prefetch -= diff; 
     412                if (jb->jb_prefetch < jb->jb_min_prefetch)  
     413                    jb->jb_prefetch = jb->jb_min_prefetch; 
    415414 
    416             /* These code is used to shorten the delay in the jitter buffer. 
     415                TRACE__((jb->name.ptr,"jb updated(1), prefetch=%d, size=%d",  
     416                         jb->jb_prefetch, jb_framelist_size(&jb->jb_framelist))); 
    417417 
    418             if (jb->jb_op_count >= stable_history_limit*2 && 
    419                 (int)jb_framelist_size(&jb->jb_framelist) > jb->jb_prefetch+2) 
    420             { 
    421                 jb_framelist_remove_head(&jb->jb_framelist,1); 
    422  
    423                 PJ_LOG(5,(jb->name.ptr,  
    424                           "jbuf optimizing, prefetch: %d, size=%d",  
    425                           jb->jb_prefetch, 
    426                           jb_framelist_size(&jb->jb_framelist))); 
    427                 jb->jb_op_count = 0; 
     418                jb->jb_stable_hist = 0; 
     419                jb->jb_max_hist_level = 0; 
    428420            } 
    429             */ 
    430  
    431421        } 
    432     } else { 
    433         jb->jb_prefetch = PJ_MIN(jb->jb_last_jitter, 
    434                                  (int)(jb->jb_max_count*4/5)); 
    435         if (jb->jb_prefetch > jb->jb_max_prefetch) 
    436             jb->jb_prefetch = jb->jb_max_prefetch; 
    437         jb->jb_stable_hist = 0; 
    438         jb->jb_max_hist_jitter = 0; 
    439422 
    440         TRACE__((THIS_FILE,"jb updated(2), prefetch=%d, size=%d",  
    441                  jb->jb_prefetch, jb_framelist_size(&jb->jb_framelist))); 
     423        /* Level is increasing */ 
     424        else if (jb->jb_level > jb->jb_prefetch) { 
    442425 
    443         /* These code is used to shorten the delay in the jitter buffer 
    444            when the current size is larger than the prefetch. But it does 
    445            not really work when the stream supports multiple frames, since 
    446            the size may grow only temporarily. 
     426            /* Instaneous set prefetch */ 
     427            jb->jb_prefetch = PJ_MIN(jb->jb_max_hist_level, 
     428                                     (int)(jb->jb_max_count*4/5)); 
     429            if (jb->jb_prefetch > jb->jb_max_prefetch) 
     430                jb->jb_prefetch = jb->jb_max_prefetch; 
     431            jb->jb_stable_hist = 0; 
     432            jb->jb_max_hist_level = 0; 
    447433 
    448         if (jb->jb_op_count >= stable_history_limit * 2) { 
    449             if ((int)jb_framelist_size(&jb->jb_framelist) > jb->jb_prefetch+2)  
    450             { 
    451                 jb_framelist_remove_head(&jb->jb_framelist,1); 
     434            TRACE__((jb->name.ptr,"jb updated(2), prefetch=%d, size=%d",  
     435                     jb->jb_prefetch, jb_framelist_size(&jb->jb_framelist))); 
     436        } 
    452437 
    453                 PJ_LOG(5,(jb->name.ptr,  
    454                           "jbuf optimizing prefetch: %d, size=%d", 
    455                           jb->jb_prefetch, 
    456                           jb_framelist_size(&jb->jb_framelist))); 
    457             } 
    458  
    459             jb->jb_op_count = 0; 
     438        /* Level is unchanged */ 
     439        else { 
     440            jb->jb_stable_hist = 0; 
    460441        } 
    461         */ 
    462442    } 
     443 
     444    /* These code is used for shortening the delay in the jitter buffer. */ 
     445    diff = jb_framelist_size(&jb->jb_framelist) - jb->jb_prefetch; 
     446    if (diff > SAFE_SHRINKING_DIFF) { 
     447         
     448        /* Drop some frames so jitter buffer size should be == jb_prefetch */ 
     449        jb_framelist_remove_head(&jb->jb_framelist, diff); 
     450 
     451        TRACE__((jb->name.ptr,  
     452                 "JB shrinking %d frames, size=%d", diff, 
     453                 jb_framelist_size(&jb->jb_framelist))); 
     454    } 
     455 
     456    jb->jb_level = 0; 
    463457} 
    464458 
    465 static void jbuf_update(pjmedia_jbuf *jb, int oper) 
     459PJ_INLINE(void) jbuf_update(pjmedia_jbuf *jb, int oper) 
    466460{ 
    467461    if(jb->jb_last_op != oper) { 
    468462        jbuf_calculate_jitter(jb); 
     
    489483    if(jb->jb_status == JB_STATUS_INITIALIZING) { 
    490484        jb->jb_status = JB_STATUS_PROCESSING; 
    491485        jb->jb_level = 0; 
    492         jb->jb_last_level = 0; 
    493         jb->jb_last_jitter = 0; 
    494486    } else { 
    495487        jbuf_update(jb, JB_OP_PUT); 
    496488    } 
     
    537529{ 
    538530    pjmedia_jb_frame_type ftype; 
    539531 
    540     jb->jb_level--; 
     532    jb->jb_level++; 
    541533 
    542534    jbuf_update(jb, JB_OP_GET); 
    543535 
     536#if USE_PREFETCH_BUFFERING 
     537 
    544538    if (jb_framelist_size(&jb->jb_framelist) == 0) { 
    545539        jb->jb_prefetch_cnt = 0; 
    546540    } 
     
    560554        return; 
    561555    } 
    562556 
     557#endif 
     558 
    563559    /* Retrieve a frame from frame list */ 
    564560    if (jb_framelist_get(&jb->jb_framelist,frame,size,&ftype) == PJ_FALSE) { 
    565561        /* Can't return frame because jitter buffer is empty! */ 
  • pjmedia/src/pjmedia/stream.c

     
    14581458    if (info->jb_min_pre >= 0) 
    14591459        jb_min_pre = info->jb_min_pre; 
    14601460    else 
    1461         jb_min_pre = 60 / stream->codec_param.info.frm_ptime; 
     1461        //jb_min_pre = 60 / stream->codec_param.info.frm_ptime; 
     1462        jb_min_pre = 1; 
    14621463 
    14631464    if (info->jb_max_pre > 0) 
    14641465        jb_max_pre = info->jb_max_pre; 
    14651466    else 
    1466         jb_max_pre = 240 / stream->codec_param.info.frm_ptime; 
     1467        //jb_max_pre = 240 / stream->codec_param.info.frm_ptime; 
     1468        jb_max_pre = jb_max * 4 / 5; 
    14671469 
    14681470    if (info->jb_init >= 0) 
    14691471        jb_init = info->jb_init; 
    14701472    else 
    1471         jb_init = (jb_min_pre + jb_max_pre) / 2; 
     1473        //jb_init = (jb_min_pre + jb_max_pre) / 2; 
     1474        jb_init = jb_min_pre; 
    14721475 
    14731476 
    14741477    /* Create jitter buffer */