Changeset 3065


Ignore:
Timestamp:
Jan 20, 2010 1:02:37 AM (9 years ago)
Author:
nanang
Message:

Ticket #969:

  • implemented progressive discard algorithm, discard rate is calculated from ratio of effective size to effective burst level.
  • updated jbuf to clarify prefetch and burst level distinction, previously they are stored in same var, i.e: prefetch, while the semantic is actually different.
  • updated STABLE_HISTORY_LIMIT in jbuf, it is now 20 (was 100), to adjust burst level faster.
  • added test case of periodic-spike-burst-case in jbtest.dat for testing the new algorithm.
  • updated stream to limit the rate of jbuf empty/lost log messages, it will only log first empty/lost event, then log again once jbuf returning normal frame (also counter of previous empty/lost frames).
  • minor updates on jbuf.c: variable names, logs, added burst to jbuf state.
  • minor updates on jbuf_test.c: handle comment in test session header, seq jump is now 20 (was 5000).
Location:
pjproject/trunk/pjmedia
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/build/Jbtest.dat

    r2672 r3065  
     1# 
     2# ====================================================================== 
     3# Jitter Buffer test data, containing one or more test sessions 
     4# ====================================================================== 
     5# 
     6# A test session format: 
     7# 
     8# 1. Session title, started with '=', example: 
     9#    = Bursty environment 
     10#  
     11# 2. Session setting, started with '%', followed by params: 
     12#    - mode, possible values: 'adaptive' or 'fixed' 
     13#    - initial prefetch, in frames 
     14#    - minimum prefetch (for adaptive mode only), in frames 
     15#    - maximum prefetch (for adaptive mode only), in frames 
     16#    Example: 
     17#    %adaptive 0 0 40 
     18#    %fixed 10 
     19# 
     20# 3. Success conditions, started with '!', followed by condition name  
     21#    and its maximum tolerable value, in frames unit. Recognized condition  
     22#    names are: burst, discard, lost, empty, delay. These conditions will 
     23#    be verified with jitter buffer statistics after all session test data 
     24#    are executed. 
     25#    Example: 
     26#    !delay 10  <- maximum average delay of jbuf is 10 frames 
     27# 
     28# 4. Session test data, containing sequence of jitter buffer events, 
     29#    an event is represented by a character as follow: 
     30#    - P: PUT a frame into jitter buffer 
     31#    - G: GET a frame from jitter buffer 
     32#    - L: generate a Lost frame, i.e: sequence jump by 1 
     33#    - R: sequence Restart 
     34#    - J: sequence Jump by 20 
     35#    - D: generate a Duplicated frame 
     36#    - O: generate an Old/late (and perhaps also duplicated) frame 
     37#    Example: 
     38#    PGPGPGPGPG <- ideal condition, PUT and GET one after another 
     39# 
     40# 5. End of session test data, marked by '.' 
     41# 
     42# ====================================================================== 
     43# 
     44 
    145= Ideal condition 
    246%adaptive 0 0 10 
     
    303347%fixed 10 
    304348!burst      1 
    305 !discard    35 <- frames discarded for delay adaptation 
     349!discard    50 <- frames discarded for delay adaptation 
    306350!lost       0 
    307351!empty      0 
    308 !delay      30 <- average delay 
    309 PPPPPPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPPPP PPPPPPPPPP 
    310 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
    311 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
    312 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
    313 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
    314 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
    315 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
    316 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
    317 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
    318 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
    319 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
    320 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
    321 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
    322 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
    323 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
    324 . 
     352!delay      20 <- average delay, twice of minimal prefetch 
     353PPPPPPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPPPP PPPPPPPPPP 
     354PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
     355PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
     356PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
     357PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
     358PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
     359PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
     360PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
     361PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
     362PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
     363PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
     364PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
     365PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
     366PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
     367PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 
     368. 
     369 
     370= Large PUT burst at beginning, then normal with burst level 10 and periodic burst spikes 
     371%adaptive 0 0 40 
     372!burst      10 
     373!discard    300 <- not so relevant for long period session with many delay adjustments needed (i.e: for first burst and periodic spikes) 
     374!lost       0 
     375!empty      60 <- delay adjustment effect, as there is actually no drift 
     376!delay      20 <- twice of burst level average 
     377PPPPPPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPPPP PPPPPPPPPP 
     378PPPPPPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPPPP PPPPPPPPPP 
     379PPPPPPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPPPP PPPPPPPPPP 
     380PPPPPPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPPPP PPPPPPPPPP 
     381PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     382PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     383PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     384PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     385PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     386PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     387PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     388PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     389PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     390PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     391PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     392PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     393PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     394PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     395PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     396PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     397PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     398PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     399PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     400PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     401PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     402PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     403PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     404PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     405PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     406PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     407PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     408PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     409PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     410PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     411PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     412PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     413PPPPPPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPPPP PPPPPPPPPP 
     414GGGGGGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGGGGGG GGGGGGGGGG 
     415PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     416PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     417PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     418PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     419PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     420PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     421PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     422PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     423PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     424PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     425PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     426PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     427PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     428PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     429PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     430PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     431PPPPPPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPPPP PPPPPPPPPP 
     432GGGGGGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGGGGGG GGGGGGGGGG 
     433PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     434PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     435PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     436PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     437PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     438PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     439PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     440PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     441PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     442PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     443PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     444PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     445PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     446PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     447PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     448PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     449PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     450PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     451PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     452PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     453PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     454PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     455PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     456PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     457PPPPPPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPPPP PPPPPPPPPP 
     458GGGGGGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGGGGGG GGGGGGGGGG 
     459PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     460PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     461PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     462PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     463PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     464PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     465PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     466PPPPPPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPPPP PPPPPPPPPP 
     467GGGGGGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGGGGGG GGGGGGGGGG 
     468PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     469PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     470PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     471PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     472PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     473PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     474PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     475PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     476PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     477PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     478PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     479PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     480PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     481PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     482PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     483PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     484PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     485PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     486PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     487PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     488PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     489PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     490PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     491PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     492PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     493PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     494PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     495PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     496PPPPPPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPPPP PPPPPPPPPP 
     497GGGGGGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGGGGGG GGGGGGGGGG 
     498PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     499PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     500PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     501PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     502PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     503PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     504PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     505PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     506PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     507PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     508PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     509PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     510PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     511PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     512PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     513PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     514PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     515PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     516PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     517PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     518PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     519PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     520PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     521PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     522PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     523PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     524PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     525PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     526PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     527PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     528PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     529PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     530PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     531PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     532PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     533PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     534PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     535PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     536PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     537PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     538PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     539PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     540PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     541PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     542PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     543PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     544PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     545PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     546PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     547PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     548PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     549PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     550PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     551PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     552PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     553PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     554PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     555PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     556PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     557PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     558PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     559PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     560PPPPPPPPPP GGGGGGGGGG PPPPPPPPPP GGGGGGGGGG 
     561. 
  • pjproject/trunk/pjmedia/include/pjmedia/jbuf.h

    r2844 r3065  
    7777 
    7878    /* Status */ 
     79    unsigned    burst;              /**< Current burst level, in frames     */ 
    7980    unsigned    prefetch;           /**< Current prefetch value, in frames  */ 
    8081    unsigned    size;               /**< Current buffer size, in frames.    */ 
  • pjproject/trunk/pjmedia/src/pjmedia/jbuf.c

    r3015 r3065  
    7373    unsigned         head;              /**< index of head, pointed frame 
    7474                                             will be returned by next GET   */ 
    75     unsigned         size;              /**< current size of framelist.     */ 
     75    unsigned         size;              /**< current size of framelist,  
     76                                             including discarded frames.    */ 
     77    unsigned         discarded_num;     /**< current number of discarded  
     78                                             frames.                        */ 
    7679    int              origin;            /**< original index of flist_head   */ 
     80 
    7781} jb_framelist_t; 
    7882 
     
    8690    pj_size_t       jb_max_count;       /**< capacity of jitter buffer,  
    8791                                             in frames                      */ 
    88     int             jb_def_prefetch;    /**< Default prefetch               */ 
     92    int             jb_init_prefetch;   /**< Initial prefetch               */ 
    8993    int             jb_min_prefetch;    /**< Minimum allowable prefetch     */ 
    9094    int             jb_max_prefetch;    /**< Maximum allowable prefetch     */ 
     
    109113    int             jb_last_op;         /**< last operation executed  
    110114                                             (put/get)                      */ 
     115    int             jb_eff_level;       /**< effective burst level          */ 
    111116    int             jb_prefetch;        /**< no. of frame to insert before  
    112117                                             removing some (at the beginning  
     
    121126    int             jb_last_del_seq;    /**< Seq # of last frame deleted    */ 
    122127 
     128    int             jb_last_discard_seq;/**< Seq # of last frame discarded  */ 
     129 
    123130    /* Statistics */ 
    124131    pj_math_stat    jb_delay;           /**< Delay statistics of jitter buffer  
     
    136143#define JB_STATUS_PREFETCHING   2 
    137144 
     145 
     146/* === Experimental feature === */ 
     147 
     148/* Progressive discard algorithm introduced to reduce JB latency 
     149 * by discarding incoming frames with adaptive aggressiveness based on 
     150 * actual burst level. 
     151 */ 
     152#define PROGRESSIVE_DISCARD 1 
     153 
     154/* Internal JB frame flag, discarded frame will not be returned by JB to 
     155 * application, it's just simply discarded. 
     156 */ 
     157#define PJMEDIA_JB_DISCARDED_FRAME 1024 
     158 
     159/* == End of experimental feature == */ 
     160 
     161 
    138162/* Enabling this would log the jitter buffer state about once per  
    139163 * second. 
     
    146170 
    147171static pj_status_t jb_framelist_reset(jb_framelist_t *framelist); 
     172static unsigned jb_framelist_remove_head(jb_framelist_t *framelist, 
     173                                         unsigned count); 
    148174 
    149175static pj_status_t jb_framelist_init( pj_pool_t *pool, 
     
    175201                                            framelist->max_count); 
    176202 
     203 
    177204    return jb_framelist_reset(framelist); 
    178205 
     
    190217    framelist->origin = INVALID_OFFSET; 
    191218    framelist->size = 0; 
     219    framelist->discarded_num = 0; 
     220 
    192221 
    193222    //pj_bzero(framelist->content,  
     
    218247 
    219248 
     249static unsigned jb_framelist_eff_size(const jb_framelist_t *framelist)  
     250{ 
     251    return (framelist->size - framelist->discarded_num); 
     252} 
     253 
     254static int jb_framelist_origin(const jb_framelist_t *framelist)  
     255{ 
     256    return framelist->origin; 
     257} 
     258 
     259 
    220260static pj_bool_t jb_framelist_get(jb_framelist_t *framelist, 
    221261                                  void *frame, pj_size_t *size, 
     
    224264{ 
    225265    if (framelist->size) { 
    226         pj_memcpy(frame,  
    227                   framelist->content +  
    228                   framelist->head * framelist->frame_size, 
    229                   framelist->frame_size); 
    230         *p_type = (pjmedia_jb_frame_type)  
    231                   framelist->frame_type[framelist->head]; 
    232         if (size) 
    233             *size   = framelist->content_len[framelist->head]; 
    234         if (bit_info) 
    235             *bit_info = framelist->bit_info[framelist->head]; 
    236  
    237         //pj_bzero(framelist->content +  
    238         //       framelist->head * framelist->frame_size, 
    239         //       framelist->frame_size); 
    240         framelist->frame_type[framelist->head] = PJMEDIA_JB_MISSING_FRAME; 
    241         framelist->content_len[framelist->head] = 0; 
    242         framelist->bit_info[framelist->head] = 0; 
    243  
    244         framelist->origin++; 
    245         framelist->head = (framelist->head + 1) % framelist->max_count; 
    246         framelist->size--; 
    247          
    248         return PJ_TRUE; 
    249     } else { 
    250         pj_bzero(frame, framelist->frame_size); 
    251  
    252         return PJ_FALSE; 
    253     } 
    254 } 
    255  
    256  
     266 
     267        /* Skip discarded frames */ 
     268        while (framelist->frame_type[framelist->head] == 
     269               PJMEDIA_JB_DISCARDED_FRAME) 
     270        { 
     271            jb_framelist_remove_head(framelist, 1); 
     272        } 
     273 
     274        /* Return the head frame if any */ 
     275        if (framelist->size) { 
     276            pj_memcpy(frame,  
     277                      framelist->content +  
     278                      framelist->head * framelist->frame_size, 
     279                      framelist->frame_size); 
     280            *p_type = (pjmedia_jb_frame_type)  
     281                      framelist->frame_type[framelist->head]; 
     282            if (size) 
     283                *size   = framelist->content_len[framelist->head]; 
     284            if (bit_info) 
     285                *bit_info = framelist->bit_info[framelist->head]; 
     286 
     287            //pj_bzero(framelist->content +  
     288            //   framelist->head * framelist->frame_size, 
     289            //   framelist->frame_size); 
     290            framelist->frame_type[framelist->head] = PJMEDIA_JB_MISSING_FRAME; 
     291            framelist->content_len[framelist->head] = 0; 
     292            framelist->bit_info[framelist->head] = 0; 
     293 
     294            framelist->origin++; 
     295            framelist->head = (framelist->head + 1) % framelist->max_count; 
     296            framelist->size--; 
     297         
     298            return PJ_TRUE; 
     299        } 
     300    } 
     301 
     302    /* No frame available */ 
     303    pj_bzero(frame, framelist->frame_size); 
     304 
     305    return PJ_FALSE; 
     306} 
     307 
     308 
     309/* Remove oldest frames as many as param 'count' */ 
    257310static unsigned jb_framelist_remove_head(jb_framelist_t *framelist, 
    258311                                         unsigned count)  
     
    265318        unsigned step1,step2; 
    266319        unsigned tmp = framelist->head+count; 
     320        unsigned i; 
    267321 
    268322        if (tmp > framelist->max_count) { 
     
    272326            step1 = count; 
    273327            step2 = 0; 
     328        } 
     329 
     330        for (i = framelist->head; i < (framelist->head + step1); ++i) { 
     331            if (framelist->frame_type[i] == PJMEDIA_JB_DISCARDED_FRAME) { 
     332                pj_assert(framelist->discarded_num > 0); 
     333                framelist->discarded_num--; 
     334            } 
    274335        } 
    275336 
     
    281342                  step1*sizeof(framelist->frame_type[0])); 
    282343        pj_bzero(framelist->content_len+framelist->head, 
    283                   step1*sizeof(framelist->content_len[0])); 
     344                 step1*sizeof(framelist->content_len[0])); 
    284345 
    285346        if (step2) { 
     347            for (i = 0; i < step2; ++i) { 
     348                if (framelist->frame_type[i] == PJMEDIA_JB_DISCARDED_FRAME) { 
     349                    pj_assert(framelist->discarded_num > 0); 
     350                    framelist->discarded_num--; 
     351                } 
     352            } 
    286353            //pj_bzero( framelist->content, 
    287354            //        step2*framelist->frame_size); 
     
    307374                                       const void *frame, 
    308375                                       unsigned frame_size, 
    309                                        pj_uint32_t bit_info) 
     376                                       pj_uint32_t bit_info, 
     377                                       unsigned frame_type) 
    310378{ 
    311379    int distance; 
    312     unsigned where; 
     380    unsigned pos; 
    313381    enum { MAX_MISORDER = 100 }; 
    314382    enum { MAX_DROPOUT = 3000 }; 
     
    316384    assert(frame_size <= framelist->frame_size); 
    317385 
    318     /* too late or duplicated or sequence restart */ 
     386    /* too late or sequence restart */ 
    319387    if (index < framelist->origin) { 
    320388        if (framelist->origin - index < MAX_MISORDER) { 
    321             /* too late or duplicated */ 
     389            /* too late */ 
    322390            return PJ_ETOOSMALL; 
    323391        } else { 
     
    329397    /* if jbuf is empty, just reset the origin */ 
    330398    if (framelist->size == 0) { 
     399        pj_assert(framelist->discarded_num == 0); 
    331400        framelist->origin = index; 
    332401    } 
     
    349418 
    350419    /* get the slot position */ 
    351     where = (framelist->head + distance) % framelist->max_count; 
     420    pos = (framelist->head + distance) % framelist->max_count; 
    352421 
    353422    /* if the slot is occupied, it must be duplicated frame, ignore it. */ 
    354     if (framelist->frame_type[where] != PJMEDIA_JB_MISSING_FRAME) 
     423    if (framelist->frame_type[pos] != PJMEDIA_JB_MISSING_FRAME) 
    355424        return PJ_EEXISTS; 
    356425 
    357426    /* put the frame into the slot */ 
    358     pj_memcpy(framelist->content + where * framelist->frame_size, 
    359               frame, frame_size); 
    360     framelist->frame_type[where] = PJMEDIA_JB_NORMAL_FRAME; 
    361     framelist->content_len[where] = frame_size; 
    362     framelist->bit_info[where] = bit_info; 
     427    framelist->frame_type[pos] = frame_type; 
     428    framelist->content_len[pos] = frame_size; 
     429    framelist->bit_info[pos] = bit_info; 
     430 
     431    /* update framelist size */ 
    363432    if (framelist->origin + (int)framelist->size <= index) 
    364433        framelist->size = distance + 1; 
    365434 
    366     return PJ_SUCCESS; 
     435    if(PJMEDIA_JB_NORMAL_FRAME == frame_type) { 
     436        /* copy frame content */ 
     437        pj_memcpy(framelist->content + pos * framelist->frame_size, 
     438                  frame, frame_size); 
     439        return PJ_SUCCESS; 
     440    } else { 
     441        /* frame is being discarded */ 
     442        framelist->discarded_num++; 
     443        return PJ_EIGNORED; 
     444    } 
    367445} 
    368446 
     
    402480    jb->jb_min_shrink_gap= MIN_SHRINK_GAP_MSEC / ptime; 
    403481    jb->jb_max_burst     = MAX_BURST_MSEC / ptime; 
     482    jb->jb_last_discard_seq = 0; 
     483 
    404484    pj_math_stat_init(&jb->jb_delay); 
    405485    pj_math_stat_init(&jb->jb_burst); 
     
    424504 
    425505    jb->jb_min_prefetch = jb->jb_max_prefetch =  
    426         jb->jb_prefetch = jb->jb_def_prefetch = prefetch; 
     506        jb->jb_prefetch = jb->jb_init_prefetch = prefetch; 
    427507 
    428508    return PJ_SUCCESS; 
     
    444524                     PJ_EINVAL); 
    445525 
    446     jb->jb_prefetch = jb->jb_def_prefetch = prefetch; 
     526    jb->jb_prefetch = jb->jb_init_prefetch = prefetch; 
    447527    jb->jb_min_prefetch = min_prefetch; 
    448528    jb->jb_max_prefetch = max_prefetch; 
     
    469549PJ_DEF(pj_status_t) pjmedia_jbuf_destroy(pjmedia_jbuf *jb) 
    470550{ 
    471     TRACE__((jb->jb_name.ptr, "" 
    472             "JB summary:" 
    473             " size=%d prefetch=%d," 
    474             " delay (min/max/avg/dev)=%d/%d/%d/%d ms," 
    475             " burst (min/max/avg/dev)=%d/%d/%d/%d frames," 
    476             " lost=%d discard=%d empty=%d", 
    477             jb->jb_framelist.size, jb->jb_prefetch, 
    478             jb->jb_delay.min, jb->jb_delay.max, jb->jb_delay.mean,  
    479             pj_math_stat_get_stddev(&jb->jb_delay), 
    480             jb->jb_burst.min, jb->jb_burst.max, jb->jb_burst.mean,  
    481             pj_math_stat_get_stddev(&jb->jb_burst), 
    482             jb->jb_lost, jb->jb_discard, jb->jb_empty)); 
     551    PJ_LOG(5, (jb->jb_name.ptr, "" 
     552               "JB summary:\n" 
     553               "  size=%d prefetch=%d level=%d\n" 
     554               "  delay (min/max/avg/dev)=%d/%d/%d/%d ms\n" 
     555               "  burst (min/max/avg/dev)=%d/%d/%d/%d frames\n" 
     556               " lost=%d discard=%d empty=%d", 
     557               jb->jb_framelist.size, jb->jb_prefetch, jb->jb_eff_level, 
     558               jb->jb_delay.min, jb->jb_delay.max, jb->jb_delay.mean,  
     559               pj_math_stat_get_stddev(&jb->jb_delay), 
     560               jb->jb_burst.min, jb->jb_burst.max, jb->jb_burst.mean,  
     561               pj_math_stat_get_stddev(&jb->jb_burst), 
     562               jb->jb_lost, jb->jb_discard, jb->jb_empty)); 
    483563 
    484564    return jb_framelist_destroy(&jb->jb_framelist); 
     
    490570    int diff, cur_size; 
    491571 
    492     cur_size = jb_framelist_size(&jb->jb_framelist); 
     572    cur_size = jb_framelist_eff_size(&jb->jb_framelist); 
    493573    pj_math_stat_update(&jb->jb_burst, jb->jb_level); 
    494574    jb->jb_max_hist_level = PJ_MAX(jb->jb_max_hist_level, jb->jb_level); 
    495575 
    496576    /* Burst level is decreasing */ 
    497     if (jb->jb_level < jb->jb_prefetch) { 
    498  
    499         enum { STABLE_HISTORY_LIMIT = 100 }; 
     577    if (jb->jb_level < jb->jb_eff_level) { 
     578 
     579        enum { STABLE_HISTORY_LIMIT = 20 }; 
    500580         
    501581        jb->jb_stable_hist++; 
    502582         
    503         /* Only update the prefetch if 'stable' condition is reached  
    504          * (not just short time impulse) 
     583        /* Only update the effective level (and prefetch) if 'stable'  
     584         * condition is reached (not just short time impulse) 
    505585         */ 
    506586        if (jb->jb_stable_hist > STABLE_HISTORY_LIMIT) { 
    507587         
    508             diff = (jb->jb_prefetch - jb->jb_max_hist_level) / 3; 
     588            diff = (jb->jb_eff_level - jb->jb_max_hist_level) / 3; 
    509589 
    510590            if (diff < 1) 
    511591                diff = 1; 
    512592 
    513             jb->jb_prefetch -= diff; 
    514             if (jb->jb_prefetch < jb->jb_min_prefetch)  
    515                 jb->jb_prefetch = jb->jb_min_prefetch; 
     593            /* Update effective burst level */ 
     594            jb->jb_eff_level -= diff; 
     595 
     596            /* Update prefetch based on level */ 
     597            if (jb->jb_init_prefetch) { 
     598                jb->jb_prefetch = jb->jb_eff_level; 
     599                if (jb->jb_prefetch < jb->jb_min_prefetch)  
     600                    jb->jb_prefetch = jb->jb_min_prefetch; 
     601            } 
    516602 
    517603            /* Reset history */ 
     
    519605            jb->jb_stable_hist = 0; 
    520606 
    521             TRACE__((jb->jb_name.ptr,"jb updated(1), prefetch=%d, size=%d", 
    522                      jb->jb_prefetch, cur_size)); 
     607            TRACE__((jb->jb_name.ptr,"jb updated(1), lvl=%d pre=%d, size=%d", 
     608                     jb->jb_eff_level, jb->jb_prefetch, cur_size)); 
    523609        } 
    524610    } 
    525611 
    526612    /* Burst level is increasing */ 
    527     else if (jb->jb_level > jb->jb_prefetch) { 
    528  
    529         /* Instaneous set prefetch to recent maximum level (max_hist_level) */ 
    530         jb->jb_prefetch = PJ_MIN(jb->jb_max_hist_level, 
    531                                  (int)(jb->jb_max_count*4/5)); 
    532         if (jb->jb_prefetch > jb->jb_max_prefetch) 
    533             jb->jb_prefetch = jb->jb_max_prefetch; 
     613    else if (jb->jb_level > jb->jb_eff_level) { 
     614 
     615        /* Instaneous set effective burst level to recent maximum level */ 
     616        jb->jb_eff_level = PJ_MIN(jb->jb_max_hist_level, 
     617                                  (int)(jb->jb_max_count*4/5)); 
     618 
     619        /* Update prefetch based on level */ 
     620        if (jb->jb_init_prefetch) { 
     621            jb->jb_prefetch = jb->jb_eff_level; 
     622            if (jb->jb_prefetch > jb->jb_max_prefetch) 
     623                jb->jb_prefetch = jb->jb_max_prefetch; 
     624        } 
    534625 
    535626        jb->jb_stable_hist = 0; 
     
    537628        //jb->jb_max_hist_level = 0; 
    538629 
    539         TRACE__((jb->jb_name.ptr,"jb updated(2), prefetch=%d, size=%d",  
    540                  jb->jb_prefetch, cur_size)); 
     630        TRACE__((jb->jb_name.ptr,"jb updated(2), lvl=%d pre=%d, size=%d",  
     631                 jb->jb_eff_level, jb->jb_prefetch, cur_size)); 
    541632    } 
    542633 
     
    549640PJ_INLINE(void) jbuf_update(pjmedia_jbuf *jb, int oper) 
    550641{ 
    551     int diff, burst_level; 
    552  
    553642    if(jb->jb_last_op != oper) { 
    554643        jb->jb_last_op = oper; 
     
    594683     */ 
    595684 
     685    /* Shrinking due of drift will be implicitly done by progressive discard, 
     686     * so just disable it when progressive discard is active. 
     687     */ 
     688#if !PROGRESSIVE_DISCARD 
     689 
    596690    if (jb->jb_status != JB_STATUS_PROCESSING) 
    597691        return; 
    598692 
    599     burst_level = PJ_MAX(jb->jb_prefetch, jb->jb_level); 
    600     diff = jb_framelist_size(&jb->jb_framelist) - burst_level*2; 
    601  
    602     if (diff >= SAFE_SHRINKING_DIFF) { 
    603         /* Check and adjust jb_last_del_seq, in case there was seq restart */ 
    604         if (jb->jb_framelist.origin < jb->jb_last_del_seq) 
    605             jb->jb_last_del_seq = jb->jb_framelist.origin; 
    606  
    607         if (jb->jb_framelist.origin - jb->jb_last_del_seq >= 
    608             jb->jb_min_shrink_gap) 
    609         { 
    610             /* Shrink slowly, one frame per cycle */ 
    611             diff = 1; 
    612  
    613             /* Drop frame(s)! */ 
    614             diff = jb_framelist_remove_head(&jb->jb_framelist, diff); 
    615             jb->jb_last_del_seq = jb->jb_framelist.origin; 
    616             jb->jb_discard += diff; 
    617  
    618             TRACE__((jb->jb_name.ptr,  
    619                      "JB shrinking %d frame(s), cur size=%d", diff, 
    620                      jb_framelist_size(&jb->jb_framelist))); 
    621         } 
    622     } 
     693    { 
     694        int diff, burst_level; 
     695 
     696        burst_level = PJ_MAX(jb->jb_eff_level, jb->jb_level); 
     697        diff = jb_framelist_eff_size(&jb->jb_framelist) - burst_level*2; 
     698 
     699        if (diff >= SAFE_SHRINKING_DIFF) { 
     700            int seq_origin; 
     701 
     702            /* Check and adjust jb_last_del_seq, in case there was  
     703             * seq restart  
     704             */ 
     705            seq_origin = jb_framelist_origin(&jb->jb_framelist); 
     706            if (seq_origin < jb->jb_last_del_seq) 
     707                jb->jb_last_del_seq = seq_origin; 
     708 
     709            if (seq_origin - jb->jb_last_del_seq >= jb->jb_min_shrink_gap) 
     710            { 
     711                /* Shrink slowly, one frame per cycle */ 
     712                diff = 1; 
     713 
     714                /* Drop frame(s)! */ 
     715                diff = jb_framelist_remove_head(&jb->jb_framelist, diff); 
     716                jb->jb_last_del_seq = jb_framelist_origin(&jb->jb_framelist); 
     717                jb->jb_discard += diff; 
     718 
     719                TRACE__((jb->jb_name.ptr,  
     720                         "JB shrinking %d frame(s), cur size=%d", diff, 
     721                         jb_framelist_eff_size(&jb->jb_framelist))); 
     722            } 
     723        } 
     724    } 
     725 
     726#endif /* !PROGRESSIVE_DISCARD */ 
     727 
    623728} 
    624729 
     
    639744{ 
    640745    pj_size_t min_frame_size; 
    641     int prev_size, cur_size; 
     746    int new_size, cur_size, frame_type = PJMEDIA_JB_NORMAL_FRAME; 
    642747    pj_status_t status; 
    643748 
    644     /* Get JB size before PUT */ 
    645     prev_size = jb_framelist_size(&jb->jb_framelist); 
     749    cur_size = jb_framelist_eff_size(&jb->jb_framelist); 
     750 
     751#if PROGRESSIVE_DISCARD 
     752    { 
     753        unsigned interval, seq_delta; 
     754        unsigned burst_level, burst_factor; 
     755 
     756        /* Calculating discard interval (aggressiveness) based on 
     757         * (current size / burst level). 
     758         */ 
     759        if (jb->jb_status == JB_STATUS_PROCESSING) { 
     760            burst_level = PJ_MAX(jb->jb_eff_level, jb->jb_level); 
     761            burst_factor = cur_size / burst_level; 
     762            /* Tolerate small spikes */ 
     763            if ((burst_level <= 5) && (burst_factor < 3)) 
     764                burst_factor = 0; 
     765        } else { 
     766            burst_factor = 0; 
     767        } 
     768 
     769        switch (burst_factor) { 
     770        case 0: 
     771            interval = 0; 
     772            break; 
     773        case 1: 
     774            interval = 7; 
     775            break; 
     776        case 2: 
     777            interval = 5; 
     778            break; 
     779        default: 
     780            interval = 4; 
     781            break; 
     782        } 
     783 
     784        /* Do the math now to see if we should discard this packet. 
     785         * Calculate the distance from the last sequence 
     786         * discarded. If negative, then this is an out of 
     787         * order frame so just proceed with discard. Else 
     788         * see if the delta is at least the intervals worth away 
     789         * from the last frame discarded. 
     790         */ 
     791        seq_delta = (pj_uint16_t)(frame_seq - jb->jb_last_discard_seq); 
     792        if ((0 != interval) && (seq_delta >= interval)) { 
     793            frame_type = PJMEDIA_JB_DISCARDED_FRAME; 
     794            jb->jb_last_discard_seq = frame_seq; 
     795 
     796            TRACE__((jb->jb_name.ptr,  
     797                    "Discarding frame #%d: eff=%d disc=%d orig:%d" 
     798                    " seq_delta:%d", 
     799                    frame_seq, 
     800                    cur_size, 
     801                    jb_framelist_size(&jb->jb_framelist) - cur_size, 
     802                    jb_framelist_origin(&jb->jb_framelist), 
     803                    (int)seq_delta)); 
     804        } 
     805    } 
     806#endif /* PROGRESSIVE_DISCARD */ 
    646807     
     808 
    647809    /* Attempt to store the frame */ 
    648810    min_frame_size = PJ_MIN(frame_size, jb->jb_frame_size); 
    649811    status = jb_framelist_put_at(&jb->jb_framelist, frame_seq, frame, 
    650                                  min_frame_size, bit_info); 
     812                                 min_frame_size, bit_info, frame_type); 
    651813     
    652     /* Jitter buffer is full, cannot store the frame */ 
     814    /* Jitter buffer is full, remove some older frames */ 
    653815    while (status == PJ_ETOOMANY) { 
     816        int distance; 
    654817        unsigned removed; 
    655818 
    656         removed = jb_framelist_remove_head(&jb->jb_framelist, 
    657                                            PJ_MAX(jb->jb_max_count/4, 1)); 
     819        /* When progressive discard activated, just remove as few as possible 
     820         * just to make this frame in. 
     821         */ 
     822#if PROGRESSIVE_DISCARD 
     823        /* The cases of seq-jump, out-of-order, and seq restart should have 
     824         * been handled/normalized by previous call of jb_framelist_put_at(). 
     825         * So we're confident about 'distance' value here. 
     826         */ 
     827        distance = (frame_seq - jb_framelist_origin(&jb->jb_framelist)) - 
     828                   jb->jb_max_count + 1; 
     829        pj_assert(distance > 0); 
     830#else 
     831        distance = PJ_MAX(jb->jb_max_count/4, 1); 
     832#endif 
     833        removed = jb_framelist_remove_head(&jb->jb_framelist, distance); 
    658834        status = jb_framelist_put_at(&jb->jb_framelist, frame_seq, frame, 
    659                                      min_frame_size, bit_info); 
     835                                     min_frame_size, bit_info, frame_type); 
    660836 
    661837        jb->jb_discard += removed; 
    662838    } 
    663839 
    664     /* Get JB size after PUT */ 
    665     cur_size = jb_framelist_size(&jb->jb_framelist); 
     840    /* Get new JB size after PUT */ 
     841    new_size = jb_framelist_eff_size(&jb->jb_framelist); 
    666842 
    667843    /* Return the flag if this frame is discarded */ 
     
    672848        if (jb->jb_status == JB_STATUS_PREFETCHING) { 
    673849            TRACE__((jb->jb_name.ptr, "PUT prefetch_cnt=%d/%d",  
    674                      cur_size, jb->jb_prefetch)); 
    675             if (cur_size >= jb->jb_prefetch) 
     850                     new_size, jb->jb_prefetch)); 
     851            if (new_size >= jb->jb_prefetch) 
    676852                jb->jb_status = JB_STATUS_PROCESSING; 
    677853        } 
    678         jb->jb_level += (cur_size > prev_size ? cur_size-prev_size : 1); 
     854        jb->jb_level += (new_size > cur_size ? new_size-cur_size : 1); 
    679855        jbuf_update(jb, JB_OP_PUT); 
    680856    } else 
     
    701877                                     pj_uint32_t *bit_info) 
    702878{ 
    703     int cur_size; 
    704  
    705     cur_size = jb_framelist_size(&jb->jb_framelist); 
    706  
    707     if (cur_size == 0) { 
    708         /* jitter buffer empty */ 
    709  
    710         if (jb->jb_def_prefetch) 
    711             jb->jb_status = JB_STATUS_PREFETCHING; 
    712  
    713         //pj_bzero(frame, jb->jb_frame_size); 
    714         *p_frame_type = PJMEDIA_JB_ZERO_EMPTY_FRAME; 
    715         if (size) 
    716             *size = 0; 
    717  
    718         jb->jb_empty++; 
    719  
    720     } else if (jb->jb_status == JB_STATUS_PREFETCHING) { 
     879    if (jb->jb_status == JB_STATUS_PREFETCHING) { 
    721880 
    722881        /* Can't return frame because jitter buffer is filling up 
     
    730889 
    731890        TRACE__((jb->jb_name.ptr, "GET prefetch_cnt=%d/%d", 
    732                  cur_size, jb->jb_prefetch)); 
     891                 jb_framelist_eff_size(&jb->jb_framelist), jb->jb_prefetch)); 
    733892 
    734893        jb->jb_empty++; 
     
    736895    } else { 
    737896 
    738         pjmedia_jb_frame_type ftype = PJMEDIA_JB_MISSING_FRAME; 
     897        pjmedia_jb_frame_type ftype = PJMEDIA_JB_NORMAL_FRAME; 
    739898        pj_bool_t res; 
    740899 
    741         /* Retrieve a frame from frame list */ 
     900        /* Try to retrieve a frame from frame list */ 
    742901        res = jb_framelist_get(&jb->jb_framelist, frame, size, &ftype,  
    743902                               bit_info); 
    744         pj_assert(res); 
    745  
    746         /* We've successfully retrieved a frame from the frame list, but 
    747          * the frame could be a blank frame! 
    748          */ 
    749         if (ftype == PJMEDIA_JB_NORMAL_FRAME) { 
    750             *p_frame_type = PJMEDIA_JB_NORMAL_FRAME; 
     903        if (res) { 
     904            /* We've successfully retrieved a frame from the frame list, but 
     905             * the frame could be a blank frame! 
     906             */ 
     907            if (ftype == PJMEDIA_JB_NORMAL_FRAME) { 
     908                *p_frame_type = PJMEDIA_JB_NORMAL_FRAME; 
     909            } else { 
     910                *p_frame_type = PJMEDIA_JB_MISSING_FRAME; 
     911                jb->jb_lost++; 
     912            } 
     913 
     914            /* Store delay history at the first GET */ 
     915            if (jb->jb_last_op == JB_OP_PUT) { 
     916                unsigned cur_size; 
     917 
     918                /* We've just retrieved one frame, so add one to cur_size */ 
     919                cur_size = jb_framelist_eff_size(&jb->jb_framelist) + 1; 
     920                pj_math_stat_update(&jb->jb_delay,  
     921                                    cur_size*jb->jb_frame_ptime); 
     922            } 
    751923        } else { 
    752             *p_frame_type = PJMEDIA_JB_MISSING_FRAME; 
    753             jb->jb_lost++; 
    754         } 
    755  
    756         /* Calculate delay on the first GET */ 
    757         if (jb->jb_last_op == JB_OP_PUT) 
    758             pj_math_stat_update(&jb->jb_delay, cur_size * jb->jb_frame_ptime); 
     924            /* Jitter buffer is empty */ 
     925            if (jb->jb_prefetch) 
     926                jb->jb_status = JB_STATUS_PREFETCHING; 
     927 
     928            //pj_bzero(frame, jb->jb_frame_size); 
     929            *p_frame_type = PJMEDIA_JB_ZERO_EMPTY_FRAME; 
     930            if (size) 
     931                *size = 0; 
     932 
     933            jb->jb_empty++; 
     934        } 
    759935    } 
    760936 
     
    775951    state->max_prefetch = jb->jb_max_prefetch; 
    776952     
     953    state->burst = jb->jb_eff_level; 
    777954    state->prefetch = jb->jb_prefetch; 
    778     state->size = jb_framelist_size(&jb->jb_framelist); 
     955    state->size = jb_framelist_eff_size(&jb->jb_framelist); 
    779956     
    780957    state->avg_delay = jb->jb_delay.mean; 
     
    790967    return PJ_SUCCESS; 
    791968} 
     969 
  • pjproject/trunk/pjmedia/src/pjmedia/stream.c

    r3061 r3065  
    121121    pjmedia_jbuf            *jb;            /**< Jitter buffer.             */ 
    122122    char                     jb_last_frm;   /**< Last frame type from jb    */ 
     123    unsigned                 jb_last_frm_cnt;/**< Last JB frame type counter*/ 
    123124 
    124125    pjmedia_rtcp_session     rtcp;          /**< RTCP for incoming RTP.     */ 
     
    326327                pjmedia_zero_samples(p_out_samp + samples_count, 
    327328                                     samples_required - samples_count); 
    328                 PJ_LOG(5,(stream->port.info.name.ptr,  "Frame lost!")); 
    329  
     329            } 
     330 
     331            if (frame_type != stream->jb_last_frm) { 
     332                /* Report changing frame type event */ 
     333                PJ_LOG(5,(stream->port.info.name.ptr, "Frame lost%s!", 
     334                          (status == PJ_SUCCESS? ", recovered":""))); 
     335 
     336                stream->jb_last_frm = frame_type; 
     337                stream->jb_last_frm_cnt = 1; 
    330338            } else { 
    331                 PJ_LOG(5,(stream->port.info.name.ptr,  
    332                           "Lost frame recovered")); 
     339                stream->jb_last_frm_cnt++; 
    333340            } 
    334341 
    335342        } else if (frame_type == PJMEDIA_JB_ZERO_EMPTY_FRAME) { 
     343 
     344            const char *with_plc = ""; 
    336345 
    337346            /* Jitter buffer is empty. If this is the first "empty" state, 
     
    343352            //if (frame_type != stream->jb_last_frm) { 
    344353            if (1) { 
    345                 pjmedia_jb_state jb_state; 
    346                 const char *with_plc = ""; 
    347  
    348354                /* Activate PLC to smoothen the missing frame */ 
    349355                if (stream->codec->op->recover &&  
     
    370376                    with_plc = ", plc invoked"; 
    371377                }  
    372  
    373                 /* Report the state of jitter buffer */ 
    374                 pjmedia_jbuf_get_state(stream->jb, &jb_state); 
    375                 PJ_LOG(5,(stream->port.info.name.ptr,  
    376                           "Jitter buffer empty (prefetch=%d)%s",  
    377                           jb_state.prefetch, with_plc)); 
    378  
    379378            } 
    380379 
     
    385384            } 
    386385 
    387             stream->jb_last_frm = frame_type; 
     386            if (stream->jb_last_frm != frame_type) { 
     387                pjmedia_jb_state jb_state; 
     388 
     389                /* Report changing frame type event */ 
     390                pjmedia_jbuf_get_state(stream->jb, &jb_state); 
     391                PJ_LOG(5,(stream->port.info.name.ptr,  
     392                          "Jitter buffer empty (prefetch=%d)%s",  
     393                          jb_state.prefetch, with_plc)); 
     394 
     395                stream->jb_last_frm = frame_type; 
     396                stream->jb_last_frm_cnt = 1; 
     397            } else { 
     398                stream->jb_last_frm_cnt++; 
     399            } 
    388400            break; 
    389401 
    390402        } else if (frame_type != PJMEDIA_JB_NORMAL_FRAME) { 
    391403 
    392             pjmedia_jb_state jb_state; 
     404            const char *with_plc = ""; 
    393405 
    394406            /* It can only be PJMEDIA_JB_ZERO_PREFETCH frame */ 
    395407            pj_assert(frame_type == PJMEDIA_JB_ZERO_PREFETCH_FRAME); 
    396  
    397             /* Get the state of jitter buffer */ 
    398             pjmedia_jbuf_get_state(stream->jb, &jb_state); 
    399408 
    400409            /* Always activate PLC when it's available.. */ 
     
    420429                         stream->plc_cnt < stream->max_plc_cnt); 
    421430 
    422                 //if (stream->jb_last_frm != frame_type) { 
    423                 if (1) { 
    424                     PJ_LOG(5,(stream->port.info.name.ptr,  
    425                               "Jitter buffer is bufferring with plc (prefetch=%d)", 
    426                               jb_state.prefetch)); 
    427                 } 
    428  
     431                with_plc = ", plc invoked"; 
    429432            }  
    430433 
     
    433436                                     samples_required - samples_count); 
    434437                samples_count = samples_required; 
     438            } 
     439 
     440            if (stream->jb_last_frm != frame_type) { 
     441                pjmedia_jb_state jb_state; 
     442 
     443                /* Report changing frame type event */ 
     444                pjmedia_jbuf_get_state(stream->jb, &jb_state); 
    435445                PJ_LOG(5,(stream->port.info.name.ptr,  
    436                           "Jitter buffer is bufferring (prefetch=%d)..",  
    437                           jb_state.prefetch)); 
     446                          "Jitter buffer is bufferring (prefetch=%d)%s",  
     447                          jb_state.prefetch, with_plc)); 
     448 
     449                stream->jb_last_frm = frame_type; 
     450                stream->jb_last_frm_cnt = 1; 
     451            } else { 
     452                stream->jb_last_frm_cnt++; 
    438453            } 
    439  
    440             stream->jb_last_frm = frame_type; 
    441454            break; 
    442455 
     
    464477                                     samples_per_frame); 
    465478            } 
     479 
     480            if (stream->jb_last_frm != frame_type) { 
     481                /* Report changing frame type event */ 
     482                PJ_LOG(5,(stream->port.info.name.ptr,  
     483                          "Jitter buffer starts returning normal frames " 
     484                          "(after %d empty/lost)", 
     485                          stream->jb_last_frm_cnt, stream->jb_last_frm)); 
     486 
     487                stream->jb_last_frm = frame_type; 
     488                stream->jb_last_frm_cnt = 1; 
     489            } else { 
     490                stream->jb_last_frm_cnt++; 
     491            } 
    466492        } 
    467  
    468         stream->jb_last_frm = frame_type; 
    469493    } 
    470494 
     
    552576                                            (pj_uint16_t)samples_per_frame); 
    553577            } 
     578 
     579            if (stream->jb_last_frm != frame_type) { 
     580                /* Report changing frame type event */ 
     581                PJ_LOG(5,(stream->port.info.name.ptr,  
     582                          "Jitter buffer starts returning normal frames " 
     583                          "(after %d empty/lost)", 
     584                          stream->jb_last_frm_cnt, stream->jb_last_frm)); 
     585 
     586                stream->jb_last_frm = frame_type; 
     587                stream->jb_last_frm_cnt = 1; 
     588            } else { 
     589                stream->jb_last_frm_cnt++; 
     590            } 
     591 
    554592        } else { 
    555593            status = (*stream->codec->op->recover)(stream->codec, 
     
    561599 
    562600            if (frame_type == PJMEDIA_JB_MISSING_FRAME) { 
    563                 PJ_LOG(5,(stream->port.info.name.ptr,  "Frame lost!")); 
     601                if (frame_type != stream->jb_last_frm) { 
     602                    /* Report changing frame type event */ 
     603                    PJ_LOG(5,(stream->port.info.name.ptr, "Frame lost!")); 
     604 
     605                    stream->jb_last_frm = frame_type; 
     606                    stream->jb_last_frm_cnt = 1; 
     607                } else { 
     608                    stream->jb_last_frm_cnt++; 
     609                } 
    564610            } else if (frame_type == PJMEDIA_JB_ZERO_EMPTY_FRAME) { 
    565                 /* Jitter buffer is empty. Check if this is the first "empty"  
    566                  * state. 
    567                  */ 
    568611                if (frame_type != stream->jb_last_frm) { 
    569612                    pjmedia_jb_state jb_state; 
    570613 
    571                     /* Report the state of jitter buffer */ 
     614                    /* Report changing frame type event */ 
    572615                    pjmedia_jbuf_get_state(stream->jb, &jb_state); 
    573616                    PJ_LOG(5,(stream->port.info.name.ptr,  
    574617                              "Jitter buffer empty (prefetch=%d)",  
    575618                              jb_state.prefetch)); 
     619 
     620                    stream->jb_last_frm = frame_type; 
     621                    stream->jb_last_frm_cnt = 1; 
     622                } else { 
     623                    stream->jb_last_frm_cnt++; 
    576624                } 
    577625            } else { 
    578                 pjmedia_jb_state jb_state; 
    579626 
    580627                /* It can only be PJMEDIA_JB_ZERO_PREFETCH frame */ 
    581628                pj_assert(frame_type == PJMEDIA_JB_ZERO_PREFETCH_FRAME); 
    582629 
    583                 /* Get the state of jitter buffer */ 
    584                 pjmedia_jbuf_get_state(stream->jb, &jb_state); 
    585  
    586630                if (stream->jb_last_frm != frame_type) { 
     631                    pjmedia_jb_state jb_state; 
     632 
     633                    /* Report changing frame type event */ 
     634                    pjmedia_jbuf_get_state(stream->jb, &jb_state); 
    587635                    PJ_LOG(5,(stream->port.info.name.ptr,  
    588636                              "Jitter buffer is bufferring (prefetch=%d)", 
    589637                              jb_state.prefetch)); 
     638 
     639                    stream->jb_last_frm = frame_type; 
     640                    stream->jb_last_frm_cnt = 1; 
     641                } else { 
     642                    stream->jb_last_frm_cnt++; 
    590643                } 
    591644            } 
    592645        } 
    593  
    594         stream->jb_last_frm = frame_type; 
    595646    } 
    596647 
     
    17161767    stream->rx_event_pt = info->rx_event_pt ? info->rx_event_pt : -1; 
    17171768    stream->last_dtmf = -1; 
     1769    stream->jb_last_frm = PJMEDIA_JB_NORMAL_FRAME; 
    17181770 
    17191771    /* Build random RTCP CNAME. CNAME has user@host format */ 
  • pjproject/trunk/pjmedia/src/test/jbuf_test.c

    r2882 r3065  
    8282        while (*p && isspace(*p)) ++p; 
    8383        printf("%s", p); 
     84 
     85    } else if (*p == '#') { 
     86        /* Ignore comment line. */ 
     87 
    8488    } else { 
    8589        /* Unknown header, perhaps this is the test data */ 
     
    123127        break; 
    124128    case 'J': /* Sequence jumps */ 
    125         (*seq) += 5000; 
     129        (*seq) += 20; 
    126130        printf("Sequence jumping, from %u to %u\n", *last_seq, *seq); 
    127131        break; 
Note: See TracChangeset for help on using the changeset viewer.