Changeset 3814
- Timestamp:
- Oct 13, 2011 9:02:41 AM (13 years ago)
- Location:
- pjproject/branches/1.x/pjmedia
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/1.x/pjmedia/build/Jbtest.dat
r3569 r3814 20 20 # 3. Success conditions, started with '!', followed by condition name 21 21 # and its maximum tolerable value, in frames unit. Recognized condition 22 # names are: burst, discard, lost, empty, delay . These conditions will23 # be verified with jitter buffer statistics after all session test data24 # are executed.22 # names are: burst, discard, lost, empty, delay, delay_min. These 23 # conditions will be verified with jitter buffer statistics after all 24 # session test data are executed. 25 25 # Example: 26 # !delay 10 <- maximumaverage delay of jbuf is 10 frames26 # !delay 10 <- average delay of jbuf is 10 frames 27 27 # 28 28 # 4. Session test data, containing sequence of jitter buffer events, … … 296 296 !lost 50 <- ticket #1188, normal frame after discarded frame is flagged 'lost' to align signal 297 297 !empty 0 298 !delay 25 <- average delay, JB is able to adapt the delay 299 PPPPPPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPPPP PPPPPPPPPP 298 !delay_min 2 <- minimum delay, JB is able to adapt the delay 299 PPPPPPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPPPP PPPPPPPPPP 300 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 301 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 302 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 303 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 304 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 305 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 306 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 307 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 308 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 309 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 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 300 317 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG 301 318 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG … … 350 367 !lost 50 <- ticket #1188, normal frame after discarded frame is flagged 'lost' to align signal 351 368 !empty 0 352 !delay 20 <- averagedelay, twice of minimal prefetch369 !delay_min 20 <- minimum delay, twice of minimal prefetch 353 370 PPPPPPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPPPP PPPPPPPPPP 354 371 PGPGPGPGPGPGPGPGPGPG PGPGPGPGPGPGPGPGPGPG PGPGPGPGPG … … 370 387 = Large PUT burst at beginning, then normal with burst level 10 and periodic burst spikes 371 388 %adaptive 0 0 40 372 !burst 1 0389 !burst 12 373 390 !discard 300 <- not so relevant for long period session with many delay adjustments needed (i.e: for first burst and periodic spikes) 374 391 !lost 300 <- ticket #1188, normal frame after discarded frame is flagged 'lost' to align signal -
pjproject/branches/1.x/pjmedia/include/pjmedia/config.h
r3745 r3814 887 887 */ 888 888 #ifndef PJMEDIA_STREAM_KA_INTERVAL 889 # define PJMEDIA_STREAM_KA_INTERVAL 5 889 # define PJMEDIA_STREAM_KA_INTERVAL 5 890 #endif 891 892 893 /** 894 * Minimum gap between two consecutive discards in jitter buffer, 895 * in milliseconds. 896 * 897 * Default: 200 ms 898 */ 899 #ifndef PJMEDIA_JBUF_DISC_MIN_GAP 900 # define PJMEDIA_JBUF_DISC_MIN_GAP 200 901 #endif 902 903 904 /** 905 * Minimum burst level reference used for calculating discard duration 906 * in jitter buffer progressive discard algorithm, in frames. 907 * 908 * Default: 1 frame 909 */ 910 #ifndef PJMEDIA_JBUF_PRO_DISC_MIN_BURST 911 # define PJMEDIA_JBUF_PRO_DISC_MIN_BURST 1 912 #endif 913 914 915 /** 916 * Maximum burst level reference used for calculating discard duration 917 * in jitter buffer progressive discard algorithm, in frames. 918 * 919 * Default: 200 frames 920 */ 921 #ifndef PJMEDIA_JBUF_PRO_DISC_MAX_BURST 922 # define PJMEDIA_JBUF_PRO_DISC_MAX_BURST 100 923 #endif 924 925 926 /** 927 * Duration for progressive discard algotithm in jitter buffer to discard 928 * an excessive frame when burst is equal to or lower than 929 * PJMEDIA_JBUF_PRO_DISC_MIN_BURST, in milliseconds. 930 * 931 * Default: 2000 ms 932 */ 933 #ifndef PJMEDIA_JBUF_PRO_DISC_T1 934 # define PJMEDIA_JBUF_PRO_DISC_T1 2000 935 #endif 936 937 938 /** 939 * Duration for progressive discard algotithm in jitter buffer to discard 940 * an excessive frame when burst is equal to or lower than 941 * PJMEDIA_JBUF_PRO_DISC_MAX_BURST, in milliseconds. 942 * 943 * Default: 10000 ms 944 */ 945 #ifndef PJMEDIA_JBUF_PRO_DISC_T2 946 # define PJMEDIA_JBUF_PRO_DISC_T2 10000 890 947 #endif 891 948 -
pjproject/branches/1.x/pjmedia/include/pjmedia/jbuf.h
r3553 r3814 49 49 * Types of frame returned by the jitter buffer. 50 50 */ 51 enum pjmedia_jb_frame_type51 typedef enum pjmedia_jb_frame_type 52 52 { 53 53 PJMEDIA_JB_MISSING_FRAME = 0, /**< No frame because it's missing */ … … 57 57 PJMEDIA_JB_ZERO_EMPTY_FRAME = 3 /**< Zero frame is being returned 58 58 because JB is empty. */ 59 }; 60 61 62 /** 63 * @see pjmedia_jb_frame_type. 64 */ 65 typedef enum pjmedia_jb_frame_type pjmedia_jb_frame_type; 59 } pjmedia_jb_frame_type; 60 61 62 /** 63 * Enumeration of jitter buffer discard algorithm. The jitter buffer 64 * continuously calculates the jitter level to get the optimum latency at 65 * any time and in order to adjust the latency, the jitter buffer may need 66 * to discard some frames. 67 */ 68 typedef enum pjmedia_jb_discard_algo 69 { 70 /** 71 * Jitter buffer should not discard any frame, except when the jitter 72 * buffer is full and a new frame arrives, one frame will be discarded 73 * to make space for the new frame. 74 */ 75 PJMEDIA_JB_DISCARD_NONE = 0, 76 77 /** 78 * Only discard one frame in at least 200ms when the latency is considered 79 * much higher than it should be. When the jitter buffer is full and a new 80 * frame arrives, one frame will be discarded to make space for the new 81 * frame. 82 */ 83 PJMEDIA_JB_DISCARD_STATIC, 84 85 /** 86 * The discard rate is dynamically calculated based on actual parameters 87 * such as jitter level and latency. When the jitter buffer is full and 88 * a new frame arrives, one frame will be discarded to make space for the 89 * new frame. 90 */ 91 PJMEDIA_JB_DISCARD_PROGRESSIVE 92 93 } pjmedia_jb_discard_algo; 66 94 67 95 … … 69 97 * This structure describes jitter buffer state. 70 98 */ 71 struct pjmedia_jb_state99 typedef struct pjmedia_jb_state 72 100 { 73 101 /* Setting */ … … 90 118 unsigned discard; /**< Number of discarded frames. */ 91 119 unsigned empty; /**< Number of empty on GET events. */ 92 }; 93 94 95 /** 96 * @see pjmedia_jb_state 97 */ 98 typedef struct pjmedia_jb_state pjmedia_jb_state; 120 } pjmedia_jb_state; 99 121 100 122 … … 114 136 * Create an adaptive jitter buffer according to the specification. If 115 137 * application wants to have a fixed jitter buffer, it may call 116 * #pjmedia_jbuf_set_fixed() after the jitter buffer is created. 138 * #pjmedia_jbuf_set_fixed() after the jitter buffer is created. Also 139 * if application wants to alter the discard algorithm, which the default 140 * PJMEDIA_JB_DISCARD_PROGRESSIVE, it may call #pjmedia_jbuf_set_discard(). 117 141 * 118 142 * This function may allocate large chunk of memory to keep the frames in … … 178 202 unsigned min_prefetch, 179 203 unsigned max_prefetch); 204 205 206 /** 207 * Set the jitter buffer discard algorithm. The default discard algorithm, 208 * set in jitter buffer creation, is PJMEDIA_JB_DISCARD_PROGRESSIVE. 209 * 210 * @param jb The jitter buffer. 211 * @param algo The discard algorithm to be used. 212 * 213 * @return PJ_SUCCESS on success. 214 */ 215 PJ_DECL(pj_status_t) pjmedia_jbuf_set_discard(pjmedia_jbuf *jb, 216 pjmedia_jb_discard_algo algo); 180 217 181 218 -
pjproject/branches/1.x/pjmedia/src/pjmedia/jbuf.c
r3779 r3814 33 33 34 34 35 /* Minimal difference between JB size and 2*burst-level to perform36 * JB shrinking.37 */38 #define SAFE_SHRINKING_DIFF 139 40 /* Minimal gap (in ms) between JB shrinking */41 #define MIN_SHRINK_GAP_MSEC 20042 43 35 /* Invalid sequence number, used as the initial value. */ 44 36 #define INVALID_OFFSET -9999 … … 53 45 */ 54 46 #define INIT_CYCLE 10 47 48 49 /* Minimal difference between JB size and 2*burst-level to perform 50 * JB shrinking in static discard algorithm. 51 */ 52 #define STA_DISC_SAFE_SHRINKING_DIFF 1 55 53 56 54 … … 82 80 83 81 82 typedef void (*discard_algo)(pjmedia_jbuf *jb); 83 static void jbuf_discard_static(pjmedia_jbuf *jb); 84 static void jbuf_discard_progressive(pjmedia_jbuf *jb); 85 86 84 87 struct pjmedia_jbuf 85 88 { … … 98 101 calculation */ 99 102 int jb_min_shrink_gap; /**< How often can we shrink */ 103 discard_algo jb_discard_algo; /**< Discard algorithm */ 100 104 101 105 /* Buffer */ … … 125 129 int jb_init_cycle_cnt; /**< status is 'init' until the first 126 130 'put' operation */ 127 int jb_last_del_seq; /**< Seq # of last frame deleted */ 128 129 int jb_last_discard_seq;/**< Seq # of last frame discarded */ 131 132 int jb_discard_ref; /**< Seq # of last frame deleted or 133 discarded */ 134 unsigned jb_discard_dist; /**< Distance from jb_discard_ref 135 to perform discard (in frm) */ 130 136 131 137 /* Statistics */ … … 393 399 enum { MAX_DROPOUT = 3000 }; 394 400 395 assert(frame_size <= framelist->frame_size);401 PJ_ASSERT_RETURN(frame_size <= framelist->frame_size, PJ_EINVAL); 396 402 397 403 /* too late or sequence restart */ … … 448 454 pj_memcpy(framelist->content + pos * framelist->frame_size, 449 455 frame, frame_size); 450 return PJ_SUCCESS; 451 } else { 452 /* frame is being discarded */ 453 framelist->discarded_num++; 454 return PJ_EIGNORED; 455 } 456 } 457 456 } 457 458 return PJ_SUCCESS; 459 } 460 461 462 static pj_status_t jb_framelist_discard(jb_framelist_t *framelist, 463 int index) 464 { 465 unsigned pos; 466 467 PJ_ASSERT_RETURN(index >= framelist->origin && 468 index < framelist->origin + (int)framelist->size, 469 PJ_EINVAL); 470 471 /* Get the slot position */ 472 pos = (framelist->head + (index - framelist->origin)) % 473 framelist->max_count; 474 475 /* Discard the frame */ 476 framelist->frame_type[pos] = PJMEDIA_JB_DISCARDED_FRAME; 477 framelist->discarded_num++; 478 479 return PJ_SUCCESS; 480 } 458 481 459 482 … … 489 512 jb->jb_max_prefetch = max_count*4/5; 490 513 jb->jb_max_count = max_count; 491 jb->jb_min_shrink_gap= MIN_SHRINK_GAP_MSEC/ ptime;514 jb->jb_min_shrink_gap= PJMEDIA_JBUF_DISC_MIN_GAP / ptime; 492 515 jb->jb_max_burst = PJ_MAX(MAX_BURST_MSEC / ptime, max_count*3/4); 493 jb->jb_last_discard_seq = 0;494 516 495 517 pj_math_stat_init(&jb->jb_delay); 496 518 pj_math_stat_init(&jb->jb_burst); 497 519 520 pjmedia_jbuf_set_discard(jb, PJMEDIA_JB_DISCARD_PROGRESSIVE); 498 521 pjmedia_jbuf_reset(jb); 499 522 … … 538 561 jb->jb_min_prefetch = min_prefetch; 539 562 jb->jb_max_prefetch = max_prefetch; 563 564 return PJ_SUCCESS; 565 } 566 567 568 PJ_DEF(pj_status_t) pjmedia_jbuf_set_discard( pjmedia_jbuf *jb, 569 pjmedia_jb_discard_algo algo) 570 { 571 PJ_ASSERT_RETURN(jb, PJ_EINVAL); 572 PJ_ASSERT_RETURN(algo >= PJMEDIA_JB_DISCARD_NONE && 573 algo <= PJMEDIA_JB_DISCARD_PROGRESSIVE, 574 PJ_EINVAL); 575 576 switch(algo) { 577 case PJMEDIA_JB_DISCARD_PROGRESSIVE: 578 jb->jb_discard_algo = &jbuf_discard_progressive; 579 break; 580 case PJMEDIA_JB_DISCARD_STATIC: 581 jb->jb_discard_algo = &jbuf_discard_static; 582 break; 583 default: 584 jb->jb_discard_algo = NULL; 585 break; 586 } 540 587 541 588 return PJ_SUCCESS; … … 552 599 jb->jb_max_hist_level= 0; 553 600 jb->jb_prefetching = (jb->jb_prefetch != 0); 601 jb->jb_discard_dist = 0; 554 602 555 603 jb_framelist_reset(&jb->jb_framelist); … … 563 611 PJ_LOG(5, (jb->jb_name.ptr, "" 564 612 "JB summary:\n" 565 " size=%d prefetch=%d level=%d\n"613 " size=%d/eff=%d prefetch=%d level=%d\n" 566 614 " delay (min/max/avg/dev)=%d/%d/%d/%d ms\n" 567 615 " burst (min/max/avg/dev)=%d/%d/%d/%d frames\n" 568 616 " lost=%d discard=%d empty=%d", 569 jb->jb_framelist.size, jb->jb_prefetch, jb->jb_eff_level, 617 jb_framelist_size(&jb->jb_framelist), 618 jb_framelist_eff_size(&jb->jb_framelist), 619 jb->jb_prefetch, jb->jb_eff_level, 570 620 jb->jb_delay.min, jb->jb_delay.max, jb->jb_delay.mean, 571 621 pj_math_stat_get_stddev(&jb->jb_delay), … … 649 699 } 650 700 } 701 702 703 static void jbuf_discard_static(pjmedia_jbuf *jb) 704 { 705 /* These code is used for shortening the delay in the jitter buffer. 706 * It needs shrink only when there is possibility of drift. Drift 707 * detection is performed by inspecting the jitter buffer size, if 708 * its size is twice of current burst level, there can be drift. 709 * 710 * Moreover, normally drift level is quite low, so JB shouldn't need 711 * to shrink aggresively, it will shrink maximum one frame per 712 * PJMEDIA_JBUF_DISC_MIN_GAP ms. Theoritically, JB may handle drift level 713 * as much as = FRAME_PTIME/PJMEDIA_JBUF_DISC_MIN_GAP * 100% 714 * 715 * Whenever there is drift, where PUT > GET, this method will keep 716 * the latency (JB size) as much as twice of burst level. 717 */ 718 719 /* Shrinking due of drift will be implicitly done by progressive discard, 720 * so just disable it when progressive discard is active. 721 */ 722 int diff, burst_level; 723 724 burst_level = PJ_MAX(jb->jb_eff_level, jb->jb_level); 725 diff = jb_framelist_eff_size(&jb->jb_framelist) - burst_level*2; 726 727 if (diff >= STA_DISC_SAFE_SHRINKING_DIFF) { 728 int seq_origin; 729 730 /* Check and adjust jb_discard_ref, in case there was 731 * seq restart 732 */ 733 seq_origin = jb_framelist_origin(&jb->jb_framelist); 734 if (seq_origin < jb->jb_discard_ref) 735 jb->jb_discard_ref = seq_origin; 736 737 if (seq_origin - jb->jb_discard_ref >= jb->jb_min_shrink_gap) 738 { 739 /* Shrink slowly, one frame per cycle */ 740 diff = 1; 741 742 /* Drop frame(s)! */ 743 diff = jb_framelist_remove_head(&jb->jb_framelist, diff); 744 jb->jb_discard_ref = jb_framelist_origin(&jb->jb_framelist); 745 jb->jb_discard += diff; 746 747 TRACE__((jb->jb_name.ptr, 748 "JB shrinking %d frame(s), cur size=%d", diff, 749 jb_framelist_eff_size(&jb->jb_framelist))); 750 } 751 } 752 } 753 754 755 static void jbuf_discard_progressive(pjmedia_jbuf *jb) 756 { 757 unsigned cur_size, burst_level, overflow, T, discard_dist; 758 int last_seq; 759 760 /* Should be done in PUT operation */ 761 if (jb->jb_last_op != JB_OP_PUT) 762 return; 763 764 /* Check if latency is longer than burst */ 765 cur_size = jb_framelist_eff_size(&jb->jb_framelist); 766 burst_level = PJ_MAX(jb->jb_eff_level, jb->jb_level); 767 if (cur_size <= burst_level) { 768 /* Reset any scheduled discard */ 769 jb->jb_discard_dist = 0; 770 return; 771 } 772 773 /* Estimate discard duration needed for adjusting latency */ 774 if (burst_level <= PJMEDIA_JBUF_PRO_DISC_MIN_BURST) 775 T = PJMEDIA_JBUF_PRO_DISC_T1; 776 else if (burst_level >= PJMEDIA_JBUF_PRO_DISC_MAX_BURST) 777 T = PJMEDIA_JBUF_PRO_DISC_T2; 778 else 779 T = PJMEDIA_JBUF_PRO_DISC_T1 + 780 (PJMEDIA_JBUF_PRO_DISC_T2 - PJMEDIA_JBUF_PRO_DISC_T1) * 781 (burst_level - PJMEDIA_JBUF_PRO_DISC_MIN_BURST) / 782 (PJMEDIA_JBUF_PRO_DISC_MAX_BURST-PJMEDIA_JBUF_PRO_DISC_MIN_BURST); 783 784 /* Calculate current discard distance */ 785 overflow = cur_size - burst_level; 786 discard_dist = T / overflow / jb->jb_frame_ptime; 787 788 /* Get last seq number in the JB */ 789 last_seq = jb_framelist_origin(&jb->jb_framelist) + 790 jb_framelist_size(&jb->jb_framelist) - 1; 791 792 /* Setup new discard schedule if none, otherwise, update the existing 793 * discard schedule (can be delayed or accelerated). 794 */ 795 if (jb->jb_discard_dist == 0) { 796 /* Setup new discard schedule */ 797 jb->jb_discard_ref = last_seq; 798 } else if (last_seq < jb->jb_discard_ref) { 799 /* Seq restarted, update discard reference */ 800 jb->jb_discard_ref = last_seq; 801 } 802 jb->jb_discard_dist = PJ_MAX(jb->jb_min_shrink_gap, (int)discard_dist); 803 804 /* Check if we need to discard now */ 805 if (last_seq >= (jb->jb_discard_ref + (int)jb->jb_discard_dist)) { 806 int discard_seq; 807 808 discard_seq = jb->jb_discard_ref + jb->jb_discard_dist; 809 if (discard_seq < jb_framelist_origin(&jb->jb_framelist)) 810 discard_seq = jb_framelist_origin(&jb->jb_framelist); 811 812 jb_framelist_discard(&jb->jb_framelist, discard_seq); 813 814 TRACE__((jb->jb_name.ptr, 815 "Discard #%d: ref=#%d dist=%d orig=%d size=%d/%d " 816 "burst=%d/%d", 817 discard_seq, 818 jb->jb_discard_ref, 819 jb->jb_discard_dist, 820 jb_framelist_origin(&jb->jb_framelist), 821 cur_size, 822 jb_framelist_size(&jb->jb_framelist), 823 jb->jb_eff_level, 824 burst_level)); 825 826 /* Update discard reference */ 827 jb->jb_discard_ref = discard_seq; 828 } 829 } 830 651 831 652 832 PJ_INLINE(void) jbuf_update(pjmedia_jbuf *jb, int oper) … … 685 865 } 686 866 687 /* These code is used for shortening the delay in the jitter buffer. 688 * It needs shrink only when there is possibility of drift. Drift 689 * detection is performed by inspecting the jitter buffer size, if 690 * its size is twice of current burst level, there can be drift. 691 * 692 * Moreover, normally drift level is quite low, so JB shouldn't need 693 * to shrink aggresively, it will shrink maximum one frame per 694 * MIN_SHRINK_GAP_MSEC ms. Theoritically, JB may handle drift level 695 * as much as = FRAME_PTIME/MIN_SHRINK_GAP_MSEC * 100% 696 * 697 * Whenever there is drift, where PUT > GET, this method will keep 698 * the latency (JB size) as much as twice of burst level. 699 */ 700 701 /* Shrinking due of drift will be implicitly done by progressive discard, 702 * so just disable it when progressive discard is active. 703 */ 704 #if !PROGRESSIVE_DISCARD 705 706 if (jb->jb_status != JB_STATUS_PROCESSING) 707 return; 708 709 { 710 int diff, burst_level; 711 712 burst_level = PJ_MAX(jb->jb_eff_level, jb->jb_level); 713 diff = jb_framelist_eff_size(&jb->jb_framelist) - burst_level*2; 714 715 if (diff >= SAFE_SHRINKING_DIFF) { 716 int seq_origin; 717 718 /* Check and adjust jb_last_del_seq, in case there was 719 * seq restart 720 */ 721 seq_origin = jb_framelist_origin(&jb->jb_framelist); 722 if (seq_origin < jb->jb_last_del_seq) 723 jb->jb_last_del_seq = seq_origin; 724 725 if (seq_origin - jb->jb_last_del_seq >= jb->jb_min_shrink_gap) 726 { 727 /* Shrink slowly, one frame per cycle */ 728 diff = 1; 729 730 /* Drop frame(s)! */ 731 diff = jb_framelist_remove_head(&jb->jb_framelist, diff); 732 jb->jb_last_del_seq = jb_framelist_origin(&jb->jb_framelist); 733 jb->jb_discard += diff; 734 735 TRACE__((jb->jb_name.ptr, 736 "JB shrinking %d frame(s), cur size=%d", diff, 737 jb_framelist_eff_size(&jb->jb_framelist))); 738 } 739 } 740 } 741 742 #endif /* !PROGRESSIVE_DISCARD */ 743 867 /* Call discard algorithm */ 868 if (jb->jb_status == JB_STATUS_PROCESSING && jb->jb_discard_algo) { 869 (*jb->jb_discard_algo)(jb); 870 } 744 871 } 745 872 … … 760 887 { 761 888 pj_size_t min_frame_size; 762 int new_size, cur_size , frame_type = PJMEDIA_JB_NORMAL_FRAME;889 int new_size, cur_size; 763 890 pj_status_t status; 764 891 765 892 cur_size = jb_framelist_eff_size(&jb->jb_framelist); 766 767 #if PROGRESSIVE_DISCARD768 {769 unsigned interval, seq_delta;770 unsigned burst_level = 0, overflow_pct = 0;771 772 /* Calculating percentage of burst overflow */773 if (jb->jb_status == JB_STATUS_PROCESSING) {774 burst_level = PJ_MAX(jb->jb_eff_level, jb->jb_level);775 if (cur_size > (int)burst_level)776 overflow_pct = (cur_size - burst_level) * 100 / burst_level;777 }778 779 /* Deciding discard interval (aggressiveness) based on780 * burst overflow percentage.781 */782 if (burst_level <= 5 && overflow_pct < 200) {783 /* Tolerate spikes on relatively small burst level */784 interval = 0;785 } else if (overflow_pct >= 200) {786 /* Overflow >= 200% */787 interval = 4;788 } else if (overflow_pct >= 100) {789 /* Overflow >= 100% */790 interval = 5;791 } else if (overflow_pct >= 10) {792 /* Overflow >= 10% */793 interval = 7;794 } else {795 /* Overflow < 10%, tolerable */796 interval = 0;797 }798 799 /* Do the math now to see if we should discard this packet.800 * Calculate the distance from the last sequence801 * discarded. If negative, then this is an out of802 * order frame so just proceed with discard. Else803 * see if the delta is at least the intervals worth away804 * from the last frame discarded.805 */806 seq_delta = (pj_uint16_t)(frame_seq - jb->jb_last_discard_seq);807 if ((0 != interval) && (seq_delta >= interval)) {808 frame_type = PJMEDIA_JB_DISCARDED_FRAME;809 jb->jb_last_discard_seq = frame_seq;810 811 TRACE__((jb->jb_name.ptr,812 "Discarding frame #%d: eff=%d disc=%d orig:%d"813 " seq_delta:%d",814 frame_seq,815 cur_size,816 jb_framelist_size(&jb->jb_framelist) - cur_size,817 jb_framelist_origin(&jb->jb_framelist),818 (int)seq_delta));819 }820 }821 #endif /* PROGRESSIVE_DISCARD */822 823 893 824 894 /* Attempt to store the frame */ 825 895 min_frame_size = PJ_MIN(frame_size, jb->jb_frame_size); 826 896 status = jb_framelist_put_at(&jb->jb_framelist, frame_seq, frame, 827 min_frame_size, bit_info, frame_type); 897 min_frame_size, bit_info, 898 PJMEDIA_JB_NORMAL_FRAME); 828 899 829 900 /* Jitter buffer is full, remove some older frames */ … … 832 903 unsigned removed; 833 904 834 /* When progressive discard activated, just remove as few as possible 835 * just to make this frame in. 836 */ 837 #if PROGRESSIVE_DISCARD 838 /* The cases of seq-jump, out-of-order, and seq restart should have 905 /* Remove as few as possible just to make this frame in. Note that 906 * the cases of seq-jump, out-of-order, and seq restart should have 839 907 * been handled/normalized by previous call of jb_framelist_put_at(). 840 908 * So we're confident about 'distance' value here. … … 843 911 jb->jb_max_count + 1; 844 912 pj_assert(distance > 0); 845 #else 846 distance = PJ_MAX(jb->jb_max_count/4, 1); 847 #endif 913 848 914 removed = jb_framelist_remove_head(&jb->jb_framelist, distance); 849 915 status = jb_framelist_put_at(&jb->jb_framelist, frame_seq, frame, 850 min_frame_size, bit_info, frame_type); 916 min_frame_size, bit_info, 917 PJMEDIA_JB_NORMAL_FRAME); 851 918 852 919 jb->jb_discard += removed; -
pjproject/branches/1.x/pjmedia/src/test/jbuf_test.c
r3553 r3814 44 44 int lost; 45 45 int empty; 46 int delay; /**< Maximum delay, in frames. */ 46 int delay; /**< Average delay, in frames. */ 47 int delay_min; /**< Minimum delay, in frames. */ 47 48 } test_cond_t; 48 49 … … 70 71 else if (pj_ansi_stricmp(cond_st, "delay") == 0) 71 72 cond->delay = cond_val; 73 else if (pj_ansi_stricmp(cond_st, "delay_min") == 0) 74 cond->delay_min = cond_val; 72 75 else if (pj_ansi_stricmp(cond_st, "discard") == 0) 73 76 cond->discard = cond_val; … … 218 221 cond.burst = -1; 219 222 cond.delay = -1; 223 cond.delay_min = -1; 220 224 cond.discard = -1; 221 225 cond.empty = -1; … … 314 318 rc |= 2; 315 319 } 320 if (cond.delay_min >= 0 && (int)state.min_delay/JB_PTIME > cond.delay_min) { 321 printf("! 'Minimum delay' should be %d, it is %d\n", 322 cond.delay_min, state.min_delay/JB_PTIME); 323 rc |= 32; 324 } 316 325 if (cond.discard >= 0 && (int)state.discard > cond.discard) { 317 326 printf("! 'Discard' should be %d, it is %d\n",
Note: See TracChangeset
for help on using the changeset viewer.