Changeset 2578 for pjproject/trunk
- Timestamp:
- Apr 6, 2009 5:05:34 PM (16 years ago)
- Location:
- pjproject/trunk/pjmedia
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/include/pjmedia/jbuf.h
r2394 r2578 67 67 68 68 /** 69 * This structure describes jitter buffer current status.69 * This structure describes jitter buffer state. 70 70 */ 71 71 struct pjmedia_jb_state 72 72 { 73 /* Setting */ 73 74 unsigned frame_size; /**< Individual frame size, in bytes. */ 74 unsigned prefetch; /**< Current prefetch value, in frames */75 75 unsigned min_prefetch; /**< Minimum allowed prefetch, in frms. */ 76 76 unsigned max_prefetch; /**< Maximum allowed prefetch, in frms. */ 77 78 /* Status */ 79 unsigned prefetch; /**< Current prefetch value, in frames */ 77 80 unsigned size; /**< Current buffer size, in frames. */ 81 82 /* Statistic */ 78 83 unsigned avg_delay; /**< Average delay, in ms. */ 79 84 unsigned min_delay; /**< Minimum delay, in ms. */ 80 85 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. */ 82 91 }; 83 92 -
pjproject/trunk/pjmedia/src/pjmedia/jbuf.c
r2485 r2578 32 32 #define THIS_FILE "jbuf.c" 33 33 34 35 /* Minimal difference between JB size and 2*burst-level to perform 36 * JB shrinking. 37 */ 34 38 #define SAFE_SHRINKING_DIFF 1 39 40 /* Minimal gap (in ms) between JB shrinking */ 35 41 #define MIN_SHRINK_GAP_MSEC 200 36 42 43 /* Invalid sequence number, used as the initial value. */ 44 #define INVALID_OFFSET -9999 45 46 /* Maximum burst length, whenever an operation is bursting longer than 47 * this value, JB will assume that the opposite operation was idle. 48 */ 49 #define MAX_BURST_MSEC 1000 50 51 /* Number of OP switches to be performed in JB_STATUS_INITIALIZING, before 52 * JB can switch its states to JB_STATUS_PROCESSING. 53 */ 54 #define INIT_CYCLE 10 55 56 57 /* Struct of JB internal buffer, represented in a circular buffer containing 58 * frame content, frame type, frame length, and frame bit info. 59 */ 37 60 typedef struct jb_framelist_t 38 61 { 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 */ 49 77 } jb_framelist_t; 50 78 … … 52 80 struct pjmedia_jbuf 53 81 { 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. */ 77 131 }; 78 132 … … 91 145 #endif 92 146 147 static pj_status_t jb_framelist_reset(jb_framelist_t *framelist); 93 148 94 149 static pj_status_t jb_framelist_init( pj_pool_t *pool, … … 101 156 pj_bzero(framelist, sizeof(jb_framelist_t)); 102 157 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); 125 178 126 179 } … … 132 185 } 133 186 187 static 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 134 213 135 214 static unsigned jb_framelist_size(jb_framelist_t *framelist) 136 215 { 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 219 static unsigned jb_framelist_origin(jb_framelist_t *framelist) 220 { 221 return framelist->origin; 143 222 } 144 223 … … 149 228 pj_uint32_t *bit_info) 150 229 { 151 if ( !framelist->flist_empty) {230 if (framelist->size) { 152 231 pj_memcpy(frame, 153 framelist-> flist_buffer+154 framelist->flist_head * framelist->flist_frame_size,155 framelist->f list_frame_size);232 framelist->content + 233 framelist->head * framelist->frame_size, 234 framelist->frame_size); 156 235 *p_type = (pjmedia_jb_frame_type) 157 framelist->f list_frame_type[framelist->flist_head];236 framelist->frame_type[framelist->head]; 158 237 if (size) 159 *size = framelist-> flist_content_len[framelist->flist_head];238 *size = framelist->content_len[framelist->head]; 160 239 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--; 175 252 176 253 return PJ_TRUE; 177 178 254 } else { 179 pj_bzero(frame, framelist->flist_frame_size); 255 pj_bzero(frame, framelist->frame_size); 256 180 257 return PJ_FALSE; 181 258 } … … 183 260 184 261 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; 262 static unsigned jb_framelist_remove_head(jb_framelist_t *framelist, 263 unsigned count) 264 { 265 if (count > framelist->size) 266 count = framelist->size; 193 267 194 268 if (count) { 195 / / may be done in two steps if overlapping269 /* may be done in two steps if overlapping */ 196 270 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; 201 275 step2 = count-step1; 202 276 } else { … … 205 279 } 206 280 207 pj_bzero(framelist->flist_buffer+208 framelist->flist_head * framelist->flist_frame_size,209 step1*framelist->flist_frame_size);210 pj_memset(framelist->f list_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, 211 285 PJMEDIA_JB_MISSING_FRAME, 212 step1*sizeof(framelist->f list_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])); 215 289 216 290 if (step2) { 217 pj_bzero( framelist->flist_buffer,218 step2*framelist->flist_frame_size);219 pj_memset(framelist->f list_frame_type,291 //pj_bzero( framelist->content, 292 // step2*framelist->frame_size); 293 pj_memset(framelist->frame_type, 220 294 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 310 static 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; 242 317 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, 285 361 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; 292 369 } 293 370 … … 318 395 return status; 319 396 320 pj_strdup_with_null(pool, &jb-> name, name);397 pj_strdup_with_null(pool, &jb->jb_name, name); 321 398 jb->jb_frame_size = frame_size; 322 399 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;326 400 jb->jb_prefetch = PJ_MIN(PJMEDIA_JB_DEFAULT_INIT_DELAY,max_count*4/5); 327 jb->jb_prefetch_cnt = 0;328 401 jb->jb_min_prefetch = 0; 329 402 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;333 403 jb->jb_max_count = max_count; 334 404 jb->jb_min_shrink_gap= MIN_SHRINK_GAP_MSEC / ptime; 335 405 jb->jb_max_burst = MAX_BURST_MSEC / ptime; 336 406 pj_math_stat_init(&jb->jb_delay); 407 pj_math_stat_init(&jb->jb_burst); 408 409 pjmedia_jbuf_reset(jb); 337 410 338 411 *p_jb = jb; … … 383 456 PJ_DEF(pj_status_t) pjmedia_jbuf_reset(pjmedia_jbuf *jb) 384 457 { 385 jb->jb_last_seq_no = -1;386 458 jb->jb_level = 0; 387 459 jb->jb_last_op = JB_OP_INIT; 388 jb->jb_prefetch_cnt = 0;389 460 jb->jb_stable_hist = 0; 390 461 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 398 467 return PJ_SUCCESS; 399 468 } … … 411 480 412 481 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 538 PJ_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. 416 583 */ 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 } 506 611 } 507 612 } … … 523 628 { 524 629 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); 539 668 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++; 578 671 } 579 672 … … 597 690 pj_uint32_t *bit_info) 598 691 { 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 607 699 if (jb->jb_def_prefetch) 608 700 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 614 711 /* Can't return frame because jitter buffer is filling up 615 712 * minimum prefetch. 616 713 */ 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; 623 717 if (size) 624 718 *size = 0; 625 719 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); 651 749 } 652 750 … … 660 758 661 759 state->frame_size = jb->jb_frame_size; 662 state->prefetch = jb->jb_prefetch;663 760 state->min_prefetch = jb->jb_min_prefetch; 664 761 state->max_prefetch = jb->jb_max_prefetch; 762 763 state->prefetch = jb->jb_prefetch; 665 764 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; 671 775 672 776 return PJ_SUCCESS;
Note: See TracChangeset
for help on using the changeset viewer.