Changeset 1887


Ignore:
Timestamp:
Mar 21, 2008 1:47:23 PM (11 years ago)
Author:
bennylp
Message:

Ticket #505: optimizing the jitter buffer delay

Location:
pjproject/trunk/pjmedia/src/pjmedia
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia/jbuf.c

    r1761 r1887  
    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 
     
    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 
     
    8483 * second. 
    8584 */ 
    86 #if 0 
     85#if 1 
    8786#  define TRACE__(args)     PJ_LOG(4,args) 
    8887#else 
     
    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); 
     
    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 
     
    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,  
     
    389384static void jbuf_calculate_jitter(pjmedia_jbuf *jb) 
    390385{ 
    391     unsigned stable_history_limit; 
    392  
    393     stable_history_limit = 1000 / jb->jb_frame_ptime; 
    394  
    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++; 
    399  
    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; 
    405  
    406             jb->jb_prefetch -= seq_diff; 
    407             if (jb->jb_prefetch < jb->jb_min_prefetch)  
    408                 jb->jb_prefetch = jb->jb_min_prefetch; 
    409  
     386    int diff; 
     387 
     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) { 
     392 
     393        jb->jb_max_hist_level = PJ_MAX(jb->jb_max_hist_level,jb->jb_level); 
     394 
     395        /* Level is decreasing */ 
     396        if (jb->jb_level < jb->jb_prefetch) { 
     397 
     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; 
     407 
     408                if (diff < 1) 
     409                    diff = 1; 
     410 
     411                jb->jb_prefetch -= diff; 
     412                if (jb->jb_prefetch < jb->jb_min_prefetch)  
     413                    jb->jb_prefetch = jb->jb_min_prefetch; 
     414 
     415                TRACE__((jb->name.ptr,"jb updated(1), prefetch=%d, size=%d",  
     416                         jb->jb_prefetch, jb_framelist_size(&jb->jb_framelist))); 
     417 
     418                jb->jb_stable_hist = 0; 
     419                jb->jb_max_hist_level = 0; 
     420            } 
     421        } 
     422 
     423        /* Level is increasing */ 
     424        else if (jb->jb_level > jb->jb_prefetch) { 
     425 
     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; 
    410431            jb->jb_stable_hist = 0; 
    411             jb->jb_max_hist_jitter = 0; 
    412  
    413             TRACE__((THIS_FILE,"jb updated(1), prefetch=%d, size=%d",  
     432            jb->jb_max_hist_level = 0; 
     433 
     434            TRACE__((jb->name.ptr,"jb updated(2), prefetch=%d, size=%d",  
    414435                     jb->jb_prefetch, jb_framelist_size(&jb->jb_framelist))); 
    415  
    416             /* These code is used to shorten the delay in the jitter buffer. 
    417  
    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; 
    428             } 
    429             */ 
    430  
    431         } 
    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; 
    439  
    440         TRACE__((THIS_FILE,"jb updated(2), prefetch=%d, size=%d",  
    441                  jb->jb_prefetch, jb_framelist_size(&jb->jb_framelist))); 
    442  
    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. 
    447  
    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); 
    452  
    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; 
    460         } 
    461         */ 
    462     } 
    463 } 
    464  
    465 static void jbuf_update(pjmedia_jbuf *jb, int oper) 
     436        } 
     437 
     438        /* Level is unchanged */ 
     439        else { 
     440            jb->jb_stable_hist = 0; 
     441        } 
     442    } 
     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; 
     457} 
     458 
     459PJ_INLINE(void) jbuf_update(pjmedia_jbuf *jb, int oper) 
    466460{ 
    467461    if(jb->jb_last_op != oper) { 
     
    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); 
     
    538530    pjmedia_jb_frame_type ftype; 
    539531 
    540     jb->jb_level--; 
     532    jb->jb_level++; 
    541533 
    542534    jbuf_update(jb, JB_OP_GET); 
     535 
     536#if USE_PREFETCH_BUFFERING 
    543537 
    544538    if (jb_framelist_size(&jb->jb_framelist) == 0) { 
     
    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) { 
  • pjproject/trunk/pjmedia/src/pjmedia/stream.c

    r1861 r1887  
    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 
Note: See TracChangeset for help on using the changeset viewer.