Changeset 3065 for pjproject/trunk/pjmedia/src/pjmedia/jbuf.c
- Timestamp:
- Jan 20, 2010 1:02:37 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/jbuf.c
r3015 r3065 73 73 unsigned head; /**< index of head, pointed frame 74 74 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. */ 76 79 int origin; /**< original index of flist_head */ 80 77 81 } jb_framelist_t; 78 82 … … 86 90 pj_size_t jb_max_count; /**< capacity of jitter buffer, 87 91 in frames */ 88 int jb_ def_prefetch; /**< Defaultprefetch */92 int jb_init_prefetch; /**< Initial prefetch */ 89 93 int jb_min_prefetch; /**< Minimum allowable prefetch */ 90 94 int jb_max_prefetch; /**< Maximum allowable prefetch */ … … 109 113 int jb_last_op; /**< last operation executed 110 114 (put/get) */ 115 int jb_eff_level; /**< effective burst level */ 111 116 int jb_prefetch; /**< no. of frame to insert before 112 117 removing some (at the beginning … … 121 126 int jb_last_del_seq; /**< Seq # of last frame deleted */ 122 127 128 int jb_last_discard_seq;/**< Seq # of last frame discarded */ 129 123 130 /* Statistics */ 124 131 pj_math_stat jb_delay; /**< Delay statistics of jitter buffer … … 136 143 #define JB_STATUS_PREFETCHING 2 137 144 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 138 162 /* Enabling this would log the jitter buffer state about once per 139 163 * second. … … 146 170 147 171 static pj_status_t jb_framelist_reset(jb_framelist_t *framelist); 172 static unsigned jb_framelist_remove_head(jb_framelist_t *framelist, 173 unsigned count); 148 174 149 175 static pj_status_t jb_framelist_init( pj_pool_t *pool, … … 175 201 framelist->max_count); 176 202 203 177 204 return jb_framelist_reset(framelist); 178 205 … … 190 217 framelist->origin = INVALID_OFFSET; 191 218 framelist->size = 0; 219 framelist->discarded_num = 0; 220 192 221 193 222 //pj_bzero(framelist->content, … … 218 247 219 248 249 static unsigned jb_framelist_eff_size(const jb_framelist_t *framelist) 250 { 251 return (framelist->size - framelist->discarded_num); 252 } 253 254 static int jb_framelist_origin(const jb_framelist_t *framelist) 255 { 256 return framelist->origin; 257 } 258 259 220 260 static pj_bool_t jb_framelist_get(jb_framelist_t *framelist, 221 261 void *frame, pj_size_t *size, … … 224 264 { 225 265 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' */ 257 310 static unsigned jb_framelist_remove_head(jb_framelist_t *framelist, 258 311 unsigned count) … … 265 318 unsigned step1,step2; 266 319 unsigned tmp = framelist->head+count; 320 unsigned i; 267 321 268 322 if (tmp > framelist->max_count) { … … 272 326 step1 = count; 273 327 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 } 274 335 } 275 336 … … 281 342 step1*sizeof(framelist->frame_type[0])); 282 343 pj_bzero(framelist->content_len+framelist->head, 283 344 step1*sizeof(framelist->content_len[0])); 284 345 285 346 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 } 286 353 //pj_bzero( framelist->content, 287 354 // step2*framelist->frame_size); … … 307 374 const void *frame, 308 375 unsigned frame_size, 309 pj_uint32_t bit_info) 376 pj_uint32_t bit_info, 377 unsigned frame_type) 310 378 { 311 379 int distance; 312 unsigned where;380 unsigned pos; 313 381 enum { MAX_MISORDER = 100 }; 314 382 enum { MAX_DROPOUT = 3000 }; … … 316 384 assert(frame_size <= framelist->frame_size); 317 385 318 /* too late or duplicated orsequence restart */386 /* too late or sequence restart */ 319 387 if (index < framelist->origin) { 320 388 if (framelist->origin - index < MAX_MISORDER) { 321 /* too late or duplicated*/389 /* too late */ 322 390 return PJ_ETOOSMALL; 323 391 } else { … … 329 397 /* if jbuf is empty, just reset the origin */ 330 398 if (framelist->size == 0) { 399 pj_assert(framelist->discarded_num == 0); 331 400 framelist->origin = index; 332 401 } … … 349 418 350 419 /* get the slot position */ 351 where= (framelist->head + distance) % framelist->max_count;420 pos = (framelist->head + distance) % framelist->max_count; 352 421 353 422 /* 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) 355 424 return PJ_EEXISTS; 356 425 357 426 /* 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 */ 363 432 if (framelist->origin + (int)framelist->size <= index) 364 433 framelist->size = distance + 1; 365 434 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 } 367 445 } 368 446 … … 402 480 jb->jb_min_shrink_gap= MIN_SHRINK_GAP_MSEC / ptime; 403 481 jb->jb_max_burst = MAX_BURST_MSEC / ptime; 482 jb->jb_last_discard_seq = 0; 483 404 484 pj_math_stat_init(&jb->jb_delay); 405 485 pj_math_stat_init(&jb->jb_burst); … … 424 504 425 505 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; 427 507 428 508 return PJ_SUCCESS; … … 444 524 PJ_EINVAL); 445 525 446 jb->jb_prefetch = jb->jb_ def_prefetch = prefetch;526 jb->jb_prefetch = jb->jb_init_prefetch = prefetch; 447 527 jb->jb_min_prefetch = min_prefetch; 448 528 jb->jb_max_prefetch = max_prefetch; … … 469 549 PJ_DEF(pj_status_t) pjmedia_jbuf_destroy(pjmedia_jbuf *jb) 470 550 { 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)); 483 563 484 564 return jb_framelist_destroy(&jb->jb_framelist); … … 490 570 int diff, cur_size; 491 571 492 cur_size = jb_framelist_ size(&jb->jb_framelist);572 cur_size = jb_framelist_eff_size(&jb->jb_framelist); 493 573 pj_math_stat_update(&jb->jb_burst, jb->jb_level); 494 574 jb->jb_max_hist_level = PJ_MAX(jb->jb_max_hist_level, jb->jb_level); 495 575 496 576 /* 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 }; 500 580 501 581 jb->jb_stable_hist++; 502 582 503 /* Only update the prefetch if 'stable' condition is reached504 * (not just short time impulse)583 /* Only update the effective level (and prefetch) if 'stable' 584 * condition is reached (not just short time impulse) 505 585 */ 506 586 if (jb->jb_stable_hist > STABLE_HISTORY_LIMIT) { 507 587 508 diff = (jb->jb_ prefetch- jb->jb_max_hist_level) / 3;588 diff = (jb->jb_eff_level - jb->jb_max_hist_level) / 3; 509 589 510 590 if (diff < 1) 511 591 diff = 1; 512 592 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 } 516 602 517 603 /* Reset history */ … … 519 605 jb->jb_stable_hist = 0; 520 606 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)); 523 609 } 524 610 } 525 611 526 612 /* 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 } 534 625 535 626 jb->jb_stable_hist = 0; … … 537 628 //jb->jb_max_hist_level = 0; 538 629 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)); 541 632 } 542 633 … … 549 640 PJ_INLINE(void) jbuf_update(pjmedia_jbuf *jb, int oper) 550 641 { 551 int diff, burst_level;552 553 642 if(jb->jb_last_op != oper) { 554 643 jb->jb_last_op = oper; … … 594 683 */ 595 684 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 596 690 if (jb->jb_status != JB_STATUS_PROCESSING) 597 691 return; 598 692 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 623 728 } 624 729 … … 639 744 { 640 745 pj_size_t min_frame_size; 641 int prev_size, cur_size;746 int new_size, cur_size, frame_type = PJMEDIA_JB_NORMAL_FRAME; 642 747 pj_status_t status; 643 748 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 */ 646 807 808 647 809 /* Attempt to store the frame */ 648 810 min_frame_size = PJ_MIN(frame_size, jb->jb_frame_size); 649 811 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); 651 813 652 /* Jitter buffer is full, cannot store the frame*/814 /* Jitter buffer is full, remove some older frames */ 653 815 while (status == PJ_ETOOMANY) { 816 int distance; 654 817 unsigned removed; 655 818 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); 658 834 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); 660 836 661 837 jb->jb_discard += removed; 662 838 } 663 839 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); 666 842 667 843 /* Return the flag if this frame is discarded */ … … 672 848 if (jb->jb_status == JB_STATUS_PREFETCHING) { 673 849 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) 676 852 jb->jb_status = JB_STATUS_PROCESSING; 677 853 } 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); 679 855 jbuf_update(jb, JB_OP_PUT); 680 856 } else … … 701 877 pj_uint32_t *bit_info) 702 878 { 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) { 721 880 722 881 /* Can't return frame because jitter buffer is filling up … … 730 889 731 890 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)); 733 892 734 893 jb->jb_empty++; … … 736 895 } else { 737 896 738 pjmedia_jb_frame_type ftype = PJMEDIA_JB_ MISSING_FRAME;897 pjmedia_jb_frame_type ftype = PJMEDIA_JB_NORMAL_FRAME; 739 898 pj_bool_t res; 740 899 741 /* Retrieve a frame from frame list */900 /* Try to retrieve a frame from frame list */ 742 901 res = jb_framelist_get(&jb->jb_framelist, frame, size, &ftype, 743 902 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 } 751 923 } 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 } 759 935 } 760 936 … … 775 951 state->max_prefetch = jb->jb_max_prefetch; 776 952 953 state->burst = jb->jb_eff_level; 777 954 state->prefetch = jb->jb_prefetch; 778 state->size = jb_framelist_ size(&jb->jb_framelist);955 state->size = jb_framelist_eff_size(&jb->jb_framelist); 779 956 780 957 state->avg_delay = jb->jb_delay.mean; … … 790 967 return PJ_SUCCESS; 791 968 } 969
Note: See TracChangeset
for help on using the changeset viewer.