OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 /* | 11 /* |
12 * bandwidth_estimator.c | 12 * bandwidth_estimator.c |
13 * | 13 * |
14 * This file contains the code for the Bandwidth Estimator designed | 14 * This file contains the code for the Bandwidth Estimator designed |
15 * for iSAC. | 15 * for iSAC. |
16 * | 16 * |
17 * NOTE! Castings needed for C55, do not remove! | 17 * NOTE! Castings needed for C55, do not remove! |
18 * | 18 * |
19 */ | 19 */ |
20 | 20 |
21 #include "bandwidth_estimator.h" | 21 #include "bandwidth_estimator.h" |
22 | |
23 #include <assert.h> | |
22 #include "settings.h" | 24 #include "settings.h" |
23 | 25 |
24 | 26 |
25 /* array of quantization levels for bottle neck info; Matlab code: */ | 27 /* array of quantization levels for bottle neck info; Matlab code: */ |
26 /* sprintf('%4.1ff, ', logspace(log10(5000), log10(40000), 12)) */ | 28 /* sprintf('%4.1ff, ', logspace(log10(5000), log10(40000), 12)) */ |
27 static const int16_t kQRateTable[12] = { | 29 static const int16_t kQRateTable[12] = { |
28 10000, 11115, 12355, 13733, 15265, 16967, | 30 10000, 11115, 12355, 13733, 15265, 16967, |
29 18860, 20963, 23301, 25900, 28789, 32000 | 31 18860, 20963, 23301, 25900, 28789, 32000 |
30 }; | 32 }; |
31 | 33 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
109 bweStr->highSpeedSend = 0; | 111 bweStr->highSpeedSend = 0; |
110 bweStr->inWaitPeriod = 0; | 112 bweStr->inWaitPeriod = 0; |
111 | 113 |
112 /* Find the inverse of the max bw and min bw in Q30 | 114 /* Find the inverse of the max bw and min bw in Q30 |
113 * (1 / (MAX_ISAC_BW + INIT_HDR_RATE) in Q30 | 115 * (1 / (MAX_ISAC_BW + INIT_HDR_RATE) in Q30 |
114 * (1 / (MIN_ISAC_BW + INIT_HDR_RATE) in Q30 | 116 * (1 / (MIN_ISAC_BW + INIT_HDR_RATE) in Q30 |
115 */ | 117 */ |
116 bweStr->maxBwInv = kInvBandwidth[3]; | 118 bweStr->maxBwInv = kInvBandwidth[3]; |
117 bweStr->minBwInv = kInvBandwidth[2]; | 119 bweStr->minBwInv = kInvBandwidth[2]; |
118 | 120 |
121 bweStr->external_bw_info.in_use = 0; | |
122 | |
119 return 0; | 123 return 0; |
120 } | 124 } |
121 | 125 |
122 /**************************************************************************** | 126 /**************************************************************************** |
123 * WebRtcIsacfix_UpdateUplinkBwImpl(...) | 127 * WebRtcIsacfix_UpdateUplinkBwImpl(...) |
124 * | 128 * |
125 * This function updates bottle neck rate received from other side in payload | 129 * This function updates bottle neck rate received from other side in payload |
126 * and calculates a new bottle neck to send to the other side. | 130 * and calculates a new bottle neck to send to the other side. |
127 * | 131 * |
128 * Input/Output: | 132 * Input/Output: |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
169 int32_t sign; | 173 int32_t sign; |
170 | 174 |
171 uint32_t byteSecondsPerBit; | 175 uint32_t byteSecondsPerBit; |
172 uint32_t tempLower; | 176 uint32_t tempLower; |
173 uint32_t tempUpper; | 177 uint32_t tempUpper; |
174 int32_t recBwAvgInv; | 178 int32_t recBwAvgInv; |
175 int32_t numPktsExpected; | 179 int32_t numPktsExpected; |
176 | 180 |
177 int16_t errCode; | 181 int16_t errCode; |
178 | 182 |
183 assert(!bweStr->external_bw_info.in_use); | |
184 | |
179 /* UPDATE ESTIMATES FROM OTHER SIDE */ | 185 /* UPDATE ESTIMATES FROM OTHER SIDE */ |
180 | 186 |
181 /* The function also checks if Index has a valid value */ | 187 /* The function also checks if Index has a valid value */ |
182 errCode = WebRtcIsacfix_UpdateUplinkBwRec(bweStr, Index); | 188 errCode = WebRtcIsacfix_UpdateUplinkBwRec(bweStr, Index); |
183 if (errCode <0) { | 189 if (errCode <0) { |
184 return(errCode); | 190 return(errCode); |
185 } | 191 } |
186 | 192 |
187 | 193 |
188 /* UPDATE ESTIMATES ON THIS SIDE */ | 194 /* UPDATE ESTIMATES ON THIS SIDE */ |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
538 } | 544 } |
539 | 545 |
540 /* This function updates the send bottle neck rate */ | 546 /* This function updates the send bottle neck rate */ |
541 /* Index - integer (range 0...23) indicating bottle neck & jitter as est imated by other side */ | 547 /* Index - integer (range 0...23) indicating bottle neck & jitter as est imated by other side */ |
542 /* returns 0 if everything went fine, -1 otherwise */ | 548 /* returns 0 if everything went fine, -1 otherwise */ |
543 int16_t WebRtcIsacfix_UpdateUplinkBwRec(BwEstimatorstr *bweStr, | 549 int16_t WebRtcIsacfix_UpdateUplinkBwRec(BwEstimatorstr *bweStr, |
544 const int16_t Index) | 550 const int16_t Index) |
545 { | 551 { |
546 uint16_t RateInd; | 552 uint16_t RateInd; |
547 | 553 |
554 assert(!bweStr->external_bw_info.in_use); | |
555 | |
548 if ( (Index < 0) || (Index > 23) ) { | 556 if ( (Index < 0) || (Index > 23) ) { |
549 return -ISAC_RANGE_ERROR_BW_ESTIMATOR; | 557 return -ISAC_RANGE_ERROR_BW_ESTIMATOR; |
550 } | 558 } |
551 | 559 |
552 /* UPDATE ESTIMATES FROM OTHER SIDE */ | 560 /* UPDATE ESTIMATES FROM OTHER SIDE */ |
553 | 561 |
554 if ( Index > 11 ) { | 562 if ( Index > 11 ) { |
555 RateInd = Index - 12; | 563 RateInd = Index - 12; |
556 /* compute the jitter estimate as decoded on the other side in Q9 */ | 564 /* compute the jitter estimate as decoded on the other side in Q9 */ |
557 /* sendMaxDelayAvg = 0.9 * sendMaxDelayAvg + 0.1 * MAX_ISAC_MD */ | 565 /* sendMaxDelayAvg = 0.9 * sendMaxDelayAvg + 0.1 * MAX_ISAC_MD */ |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
609 int32_t maxDelay; | 617 int32_t maxDelay; |
610 uint16_t rateInd; | 618 uint16_t rateInd; |
611 uint16_t maxDelayBit; | 619 uint16_t maxDelayBit; |
612 int32_t tempTerm1; | 620 int32_t tempTerm1; |
613 int32_t tempTerm2; | 621 int32_t tempTerm2; |
614 int32_t tempTermX; | 622 int32_t tempTermX; |
615 int32_t tempTermY; | 623 int32_t tempTermY; |
616 int32_t tempMin; | 624 int32_t tempMin; |
617 int32_t tempMax; | 625 int32_t tempMax; |
618 | 626 |
627 if (bweStr->external_bw_info.in_use) | |
628 return bweStr->external_bw_info.bottleneck_idx; | |
629 | |
619 /* Get Rate Index */ | 630 /* Get Rate Index */ |
620 | 631 |
621 /* Get unquantized rate. Always returns 10000 <= rate <= 32000 */ | 632 /* Get unquantized rate. Always returns 10000 <= rate <= 32000 */ |
622 rate = WebRtcIsacfix_GetDownlinkBandwidth(bweStr); | 633 rate = WebRtcIsacfix_GetDownlinkBandwidth(bweStr); |
623 | 634 |
624 /* Compute the averaged BN estimate on this side */ | 635 /* Compute the averaged BN estimate on this side */ |
625 | 636 |
626 /* recBwAvg = 0.9 * recBwAvg + 0.1 * (rate + bweStr->recHeaderRate), 0.9 and 0 .1 in Q9 */ | 637 /* recBwAvg = 0.9 * recBwAvg + 0.1 * (rate + bweStr->recHeaderRate), 0.9 and 0 .1 in Q9 */ |
627 bweStr->recBwAvg = 922 * bweStr->recBwAvg + | 638 bweStr->recBwAvg = 922 * bweStr->recBwAvg + |
628 102 * (((uint32_t)rate + bweStr->recHeaderRate) << 5); | 639 102 * (((uint32_t)rate + bweStr->recHeaderRate) << 5); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
714 | 725 |
715 /* get the bottle neck rate from far side to here, as estimated on this side */ | 726 /* get the bottle neck rate from far side to here, as estimated on this side */ |
716 uint16_t WebRtcIsacfix_GetDownlinkBandwidth(const BwEstimatorstr *bweStr) | 727 uint16_t WebRtcIsacfix_GetDownlinkBandwidth(const BwEstimatorstr *bweStr) |
717 { | 728 { |
718 uint32_t recBw; | 729 uint32_t recBw; |
719 int32_t jitter_sign; /* Q8 */ | 730 int32_t jitter_sign; /* Q8 */ |
720 int32_t bw_adjust; /* Q16 */ | 731 int32_t bw_adjust; /* Q16 */ |
721 int32_t rec_jitter_short_term_abs_inv; /* Q18 */ | 732 int32_t rec_jitter_short_term_abs_inv; /* Q18 */ |
722 int32_t temp; | 733 int32_t temp; |
723 | 734 |
735 assert(!bweStr->external_bw_info.in_use); | |
736 | |
724 /* Q18 rec jitter short term abs is in Q13, multiply it by 2^13 to save preci sion | 737 /* Q18 rec jitter short term abs is in Q13, multiply it by 2^13 to save preci sion |
725 2^18 then needs to be shifted 13 bits to 2^31 */ | 738 2^18 then needs to be shifted 13 bits to 2^31 */ |
726 rec_jitter_short_term_abs_inv = 0x80000000u / bweStr->recJitterShortTermAbs; | 739 rec_jitter_short_term_abs_inv = 0x80000000u / bweStr->recJitterShortTermAbs; |
727 | 740 |
728 /* Q27 = 9 + 18 */ | 741 /* Q27 = 9 + 18 */ |
729 jitter_sign = (bweStr->recJitterShortTerm >> 4) * | 742 jitter_sign = (bweStr->recJitterShortTerm >> 4) * |
730 rec_jitter_short_term_abs_inv; | 743 rec_jitter_short_term_abs_inv; |
731 | 744 |
732 if (jitter_sign < 0) { | 745 if (jitter_sign < 0) { |
733 temp = -jitter_sign; | 746 temp = -jitter_sign; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
770 } | 783 } |
771 | 784 |
772 return (uint16_t) recBw; | 785 return (uint16_t) recBw; |
773 } | 786 } |
774 | 787 |
775 /* Returns the mmax delay (in ms) */ | 788 /* Returns the mmax delay (in ms) */ |
776 int16_t WebRtcIsacfix_GetDownlinkMaxDelay(const BwEstimatorstr *bweStr) | 789 int16_t WebRtcIsacfix_GetDownlinkMaxDelay(const BwEstimatorstr *bweStr) |
777 { | 790 { |
778 int16_t recMaxDelay = (int16_t)(bweStr->recMaxDelay >> 15); | 791 int16_t recMaxDelay = (int16_t)(bweStr->recMaxDelay >> 15); |
779 | 792 |
793 assert(!bweStr->external_bw_info.in_use); | |
794 | |
780 /* limit range of jitter estimate */ | 795 /* limit range of jitter estimate */ |
781 if (recMaxDelay < MIN_ISAC_MD) { | 796 if (recMaxDelay < MIN_ISAC_MD) { |
782 recMaxDelay = MIN_ISAC_MD; | 797 recMaxDelay = MIN_ISAC_MD; |
783 } else if (recMaxDelay > MAX_ISAC_MD) { | 798 } else if (recMaxDelay > MAX_ISAC_MD) { |
784 recMaxDelay = MAX_ISAC_MD; | 799 recMaxDelay = MAX_ISAC_MD; |
785 } | 800 } |
786 | 801 |
787 return recMaxDelay; | 802 return recMaxDelay; |
788 } | 803 } |
789 | 804 |
790 /* get the bottle neck rate from here to far side, as estimated by far side */ | 805 /* Clamp val to the closed interval [min,max]. */ |
791 int16_t WebRtcIsacfix_GetUplinkBandwidth(const BwEstimatorstr *bweStr) | 806 static int16_t clamp(int16_t val, int16_t min, int16_t max) { |
792 { | 807 assert(min <= max); |
793 int16_t send_bw; | 808 if (val <= min) |
hlundin-webrtc
2015/06/26 10:35:14
Consider
return val <= min ? min : (val >= max ? m
kwiberg-webrtc
2015/06/28 03:17:41
Done.
| |
794 | 809 return min; |
795 send_bw = (int16_t) WEBRTC_SPL_RSHIFT_U32(bweStr->sendBwAvg, 7); | 810 if (val >= max) |
796 | 811 return max; |
797 /* limit range of bottle neck rate */ | 812 return val; |
798 if (send_bw < MIN_ISAC_BW) { | |
799 send_bw = MIN_ISAC_BW; | |
800 } else if (send_bw > MAX_ISAC_BW) { | |
801 send_bw = MAX_ISAC_BW; | |
802 } | |
803 | |
804 return send_bw; | |
805 } | 813 } |
806 | 814 |
807 | 815 int16_t WebRtcIsacfix_GetUplinkBandwidth(const BwEstimatorstr* bweStr) { |
808 | 816 return bweStr->external_bw_info.in_use |
809 /* Returns the max delay value from the other side in ms */ | 817 ? bweStr->external_bw_info.send_bw_avg |
810 int16_t WebRtcIsacfix_GetUplinkMaxDelay(const BwEstimatorstr *bweStr) | 818 : clamp(bweStr->sendBwAvg >> 7, MIN_ISAC_BW, MAX_ISAC_BW); |
811 { | |
812 int16_t send_max_delay = (int16_t)(bweStr->sendMaxDelayAvg >> 9); | |
813 | |
814 /* limit range of jitter estimate */ | |
815 if (send_max_delay < MIN_ISAC_MD) { | |
816 send_max_delay = MIN_ISAC_MD; | |
817 } else if (send_max_delay > MAX_ISAC_MD) { | |
818 send_max_delay = MAX_ISAC_MD; | |
819 } | |
820 | |
821 return send_max_delay; | |
822 } | 819 } |
823 | 820 |
821 int16_t WebRtcIsacfix_GetUplinkMaxDelay(const BwEstimatorstr* bweStr) { | |
822 return bweStr->external_bw_info.in_use | |
823 ? bweStr->external_bw_info.send_max_delay_avg | |
824 : clamp(bweStr->sendMaxDelayAvg >> 9, MIN_ISAC_MD, MAX_ISAC_MD); | |
825 } | |
824 | 826 |
827 void WebRtcIsacfixBw_GetBandwidthInfo(BwEstimatorstr* bweStr, | |
828 IsacBandwidthInfo* bwinfo) { | |
829 assert(!bweStr->external_bw_info.in_use); | |
830 bwinfo->in_use = 1; | |
831 bwinfo->send_bw_avg = WebRtcIsacfix_GetUplinkBandwidth(bweStr); | |
832 bwinfo->send_max_delay_avg = WebRtcIsacfix_GetUplinkMaxDelay(bweStr); | |
833 bwinfo->bottleneck_idx = WebRtcIsacfix_GetDownlinkBwIndexImpl(bweStr); | |
834 bwinfo->jitter_info = 0; // Not used. | |
835 } | |
825 | 836 |
837 void WebRtcIsacfixBw_SetBandwidthInfo(BwEstimatorstr* bweStr, | |
838 const IsacBandwidthInfo* bwinfo) { | |
839 memcpy(&bweStr->external_bw_info, bwinfo, | |
840 sizeof bweStr->external_bw_info); | |
841 } | |
826 | 842 |
827 /* | 843 /* |
828 * update long-term average bitrate and amount of data in buffer | 844 * update long-term average bitrate and amount of data in buffer |
829 * returns minimum payload size (bytes) | 845 * returns minimum payload size (bytes) |
830 */ | 846 */ |
831 uint16_t WebRtcIsacfix_GetMinBytes(RateModel *State, | 847 uint16_t WebRtcIsacfix_GetMinBytes(RateModel *State, |
832 int16_t StreamSize, /* byt es in bitstream */ | 848 int16_t StreamSize, /* byt es in bitstream */ |
833 const int16_t FrameSamples, /* sam ples per frame */ | 849 const int16_t FrameSamples, /* sam ples per frame */ |
834 const int16_t BottleNeck, /* bottle ne ck rate; excl headers (bps) */ | 850 const int16_t BottleNeck, /* bottle ne ck rate; excl headers (bps) */ |
835 const int16_t DelayBuildUp) /* max delay from bottle neck buffering (ms) */ | 851 const int16_t DelayBuildUp) /* max delay from bottle neck buffering (ms) */ |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1017 /*s2nr = -1*(a_60 << 10) + ((b_60 * bottle_neck) >> 10);*/ | 1033 /*s2nr = -1*(a_60 << 10) + ((b_60 * bottle_neck) >> 10);*/ |
1018 s2nr = -22500 + (int16_t)(500 * bottle_neck >> 10); | 1034 s2nr = -22500 + (int16_t)(500 * bottle_neck >> 10); |
1019 break; | 1035 break; |
1020 default: | 1036 default: |
1021 s2nr = -1; /* Error */ | 1037 s2nr = -1; /* Error */ |
1022 } | 1038 } |
1023 | 1039 |
1024 return s2nr; //return in Q10 | 1040 return s2nr; //return in Q10 |
1025 | 1041 |
1026 } | 1042 } |
OLD | NEW |