LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/audio_coding/codecs/isac/main/source - bandwidth_estimator.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 410 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 17 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
       3             :  *
       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
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS.  All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : 
      11             : /*
      12             :  * BwEstimator.c
      13             :  *
      14             :  * This file contains the code for the Bandwidth Estimator designed
      15             :  * for iSAC.
      16             :  *
      17             :  */
      18             : 
      19             : #include "bandwidth_estimator.h"
      20             : #include "settings.h"
      21             : #include "isac.h"
      22             : #include "webrtc/base/checks.h"
      23             : 
      24             : #include <math.h>
      25             : #include <string.h>
      26             : 
      27             : /* array of quantization levels for bottle neck info; Matlab code: */
      28             : /* sprintf('%4.1ff, ', logspace(log10(5000), log10(40000), 12)) */
      29             : static const float kQRateTableWb[12] =
      30             : {
      31             :   10000.0f, 11115.3f, 12355.1f, 13733.1f, 15264.8f, 16967.3f,
      32             :   18859.8f, 20963.3f, 23301.4f, 25900.3f, 28789.0f, 32000.0f};
      33             : 
      34             : 
      35             : static const float kQRateTableSwb[24] =
      36             : {
      37             :   10000.0f, 11115.3f, 12355.1f, 13733.1f, 15264.8f, 16967.3f,
      38             :   18859.8f, 20963.3f, 23153.1f, 25342.9f, 27532.7f, 29722.5f,
      39             :   31912.3f, 34102.1f, 36291.9f, 38481.7f, 40671.4f, 42861.2f,
      40             :   45051.0f, 47240.8f, 49430.6f, 51620.4f, 53810.2f, 56000.0f,
      41             : };
      42             : 
      43             : 
      44             : 
      45             : 
      46           0 : int32_t WebRtcIsac_InitBandwidthEstimator(
      47             :     BwEstimatorstr*              bwest_str,
      48             :     enum IsacSamplingRate encoderSampRate,
      49             :     enum IsacSamplingRate decoderSampRate)
      50             : {
      51           0 :   switch(encoderSampRate)
      52             :   {
      53             :     case kIsacWideband:
      54             :       {
      55           0 :         bwest_str->send_bw_avg       = INIT_BN_EST_WB;
      56           0 :         break;
      57             :       }
      58             :     case kIsacSuperWideband:
      59             :       {
      60           0 :         bwest_str->send_bw_avg       = INIT_BN_EST_SWB;
      61           0 :         break;
      62             :       }
      63             :   }
      64             : 
      65           0 :   switch(decoderSampRate)
      66             :   {
      67             :     case kIsacWideband:
      68             :       {
      69           0 :         bwest_str->prev_frame_length = INIT_FRAME_LEN_WB;
      70           0 :         bwest_str->rec_bw_inv        = 1.0f /
      71             :             (INIT_BN_EST_WB + INIT_HDR_RATE_WB);
      72           0 :         bwest_str->rec_bw            = (int32_t)INIT_BN_EST_WB;
      73           0 :         bwest_str->rec_bw_avg_Q      = INIT_BN_EST_WB;
      74           0 :         bwest_str->rec_bw_avg        = INIT_BN_EST_WB + INIT_HDR_RATE_WB;
      75           0 :         bwest_str->rec_header_rate   = INIT_HDR_RATE_WB;
      76           0 :         break;
      77             :       }
      78             :     case kIsacSuperWideband:
      79             :       {
      80           0 :         bwest_str->prev_frame_length = INIT_FRAME_LEN_SWB;
      81           0 :         bwest_str->rec_bw_inv        = 1.0f /
      82             :             (INIT_BN_EST_SWB + INIT_HDR_RATE_SWB);
      83           0 :         bwest_str->rec_bw            = (int32_t)INIT_BN_EST_SWB;
      84           0 :         bwest_str->rec_bw_avg_Q      = INIT_BN_EST_SWB;
      85           0 :         bwest_str->rec_bw_avg        = INIT_BN_EST_SWB + INIT_HDR_RATE_SWB;
      86           0 :         bwest_str->rec_header_rate   = INIT_HDR_RATE_SWB;
      87           0 :         break;
      88             :       }
      89             :   }
      90             : 
      91           0 :   bwest_str->prev_rec_rtp_number       = 0;
      92           0 :   bwest_str->prev_rec_arr_ts           = 0;
      93           0 :   bwest_str->prev_rec_send_ts          = 0;
      94           0 :   bwest_str->prev_rec_rtp_rate         = 1.0f;
      95           0 :   bwest_str->last_update_ts            = 0;
      96           0 :   bwest_str->last_reduction_ts         = 0;
      97           0 :   bwest_str->count_tot_updates_rec     = -9;
      98           0 :   bwest_str->rec_jitter                = 10.0f;
      99           0 :   bwest_str->rec_jitter_short_term     = 0.0f;
     100           0 :   bwest_str->rec_jitter_short_term_abs = 5.0f;
     101           0 :   bwest_str->rec_max_delay             = 10.0f;
     102           0 :   bwest_str->rec_max_delay_avg_Q       = 10.0f;
     103           0 :   bwest_str->num_pkts_rec              = 0;
     104             : 
     105           0 :   bwest_str->send_max_delay_avg        = 10.0f;
     106             : 
     107           0 :   bwest_str->hsn_detect_rec = 0;
     108             : 
     109           0 :   bwest_str->num_consec_rec_pkts_over_30k = 0;
     110             : 
     111           0 :   bwest_str->hsn_detect_snd = 0;
     112             : 
     113           0 :   bwest_str->num_consec_snt_pkts_over_30k = 0;
     114             : 
     115           0 :   bwest_str->in_wait_period = 0;
     116             : 
     117           0 :   bwest_str->change_to_WB = 0;
     118             : 
     119           0 :   bwest_str->numConsecLatePkts = 0;
     120           0 :   bwest_str->consecLatency = 0;
     121           0 :   bwest_str->inWaitLatePkts = 0;
     122           0 :   bwest_str->senderTimestamp = 0;
     123           0 :   bwest_str->receiverTimestamp = 0;
     124             : 
     125           0 :   bwest_str->external_bw_info.in_use = 0;
     126             : 
     127           0 :   return 0;
     128             : }
     129             : 
     130             : /* This function updates both bottle neck rates                                                      */
     131             : /* Parameters:                                                                                       */
     132             : /* rtp_number    - value from RTP packet, from NetEq                                                 */
     133             : /* frame length  - length of signal frame in ms, from iSAC decoder                                   */
     134             : /* send_ts       - value in RTP header giving send time in samples                                     */
     135             : /* arr_ts        - value given by timeGetTime() time of arrival in samples of packet from NetEq      */
     136             : /* pksize        - size of packet in bytes, from NetEq                                               */
     137             : /* Index         - integer (range 0...23) indicating bottle neck & jitter as estimated by other side */
     138             : /* returns 0 if everything went fine, -1 otherwise                                                   */
     139           0 : int16_t WebRtcIsac_UpdateBandwidthEstimator(
     140             :     BwEstimatorstr* bwest_str,
     141             :     const uint16_t rtp_number,
     142             :     const int32_t frame_length,
     143             :     const uint32_t send_ts,
     144             :     const uint32_t arr_ts,
     145             :     const size_t pksize
     146             :     /*,    const uint16_t Index*/)
     147             : {
     148           0 :   float weight = 0.0f;
     149           0 :   float curr_bw_inv = 0.0f;
     150             :   float rec_rtp_rate;
     151             :   float t_diff_proj;
     152             :   float arr_ts_diff;
     153             :   float send_ts_diff;
     154             :   float arr_time_noise;
     155             :   float arr_time_noise_abs;
     156             : 
     157           0 :   float delay_correction_factor = 1;
     158           0 :   float late_diff = 0.0f;
     159           0 :   int immediate_set = 0;
     160             :   int num_pkts_expected;
     161             : 
     162           0 :   RTC_DCHECK(!bwest_str->external_bw_info.in_use);
     163             : 
     164             :   // We have to adjust the header-rate if the first packet has a
     165             :   // frame-size different than the initialized value.
     166           0 :   if ( frame_length != bwest_str->prev_frame_length )
     167             :   {
     168           0 :     bwest_str->rec_header_rate = (float)HEADER_SIZE * 8.0f *
     169           0 :         1000.0f / (float)frame_length;     /* bits/s */
     170             :   }
     171             : 
     172             :   /* UPDATE ESTIMATES ON THIS SIDE */
     173             :   /* compute far-side transmission rate */
     174           0 :   rec_rtp_rate = ((float)pksize * 8.0f * 1000.0f / (float)frame_length) +
     175           0 :       bwest_str->rec_header_rate;
     176             :   // rec_rtp_rate packet bits/s + header bits/s
     177             : 
     178             :   /* check for timer wrap-around */
     179           0 :   if (arr_ts < bwest_str->prev_rec_arr_ts)
     180             :   {
     181           0 :     bwest_str->prev_rec_arr_ts   = arr_ts;
     182           0 :     bwest_str->last_update_ts    = arr_ts;
     183           0 :     bwest_str->last_reduction_ts = arr_ts + 3*FS;
     184           0 :     bwest_str->num_pkts_rec      = 0;
     185             : 
     186             :     /* store frame length */
     187           0 :     bwest_str->prev_frame_length = frame_length;
     188             : 
     189             :     /* store far-side transmission rate */
     190           0 :     bwest_str->prev_rec_rtp_rate = rec_rtp_rate;
     191             : 
     192             :     /* store far-side RTP time stamp */
     193           0 :     bwest_str->prev_rec_rtp_number = rtp_number;
     194             : 
     195           0 :     return 0;
     196             :   }
     197             : 
     198           0 :   bwest_str->num_pkts_rec++;
     199             : 
     200             :   /* check that it's not one of the first 9 packets */
     201           0 :   if ( bwest_str->count_tot_updates_rec > 0 )
     202             :   {
     203           0 :     if(bwest_str->in_wait_period > 0 )
     204             :     {
     205           0 :       bwest_str->in_wait_period--;
     206             :     }
     207             : 
     208           0 :     bwest_str->inWaitLatePkts -= ((bwest_str->inWaitLatePkts > 0)? 1:0);
     209           0 :     send_ts_diff = (float)(send_ts - bwest_str->prev_rec_send_ts);
     210             : 
     211           0 :     if (send_ts_diff <= (16 * frame_length)*2)
     212             :       //doesn't allow for a dropped packet, not sure necessary to be
     213             :       // that strict -DH
     214             :     {
     215             :       /* if not been updated for a long time, reduce the BN estimate */
     216           0 :       if((uint32_t)(arr_ts - bwest_str->last_update_ts) *
     217           0 :          1000.0f / FS > 3000)
     218             :       {
     219             :         //how many frames should have been received since the last
     220             :         // update if too many have been dropped or there have been
     221             :         // big delays won't allow this reduction may no longer need
     222             :         // the send_ts_diff here
     223           0 :         num_pkts_expected = (int)(((float)(arr_ts -
     224           0 :                                            bwest_str->last_update_ts) * 1000.0f /(float) FS) /
     225           0 :                                   (float)frame_length);
     226             : 
     227           0 :         if(((float)bwest_str->num_pkts_rec/(float)num_pkts_expected) >
     228             :            0.9)
     229             :         {
     230           0 :           float inv_bitrate = (float) pow( 0.99995,
     231           0 :                                            (double)((uint32_t)(arr_ts -
     232           0 :                                                                      bwest_str->last_reduction_ts)*1000.0f/FS) );
     233             : 
     234           0 :           if ( inv_bitrate )
     235             :           {
     236           0 :             bwest_str->rec_bw_inv /= inv_bitrate;
     237             : 
     238             :             //precautionary, likely never necessary
     239           0 :             if (bwest_str->hsn_detect_snd &&
     240           0 :                 bwest_str->hsn_detect_rec)
     241             :             {
     242           0 :               if (bwest_str->rec_bw_inv > 0.000066f)
     243             :               {
     244           0 :                 bwest_str->rec_bw_inv = 0.000066f;
     245             :               }
     246             :             }
     247             :           }
     248             :           else
     249             :           {
     250           0 :             bwest_str->rec_bw_inv = 1.0f /
     251             :                 (INIT_BN_EST_WB + INIT_HDR_RATE_WB);
     252             :           }
     253             :           /* reset time-since-update counter */
     254           0 :           bwest_str->last_reduction_ts = arr_ts;
     255             :         }
     256             :         else
     257             :           //reset here?
     258             :         {
     259           0 :           bwest_str->last_reduction_ts = arr_ts + 3*FS;
     260           0 :           bwest_str->last_update_ts = arr_ts;
     261           0 :           bwest_str->num_pkts_rec = 0;
     262             :         }
     263             :       }
     264             :     }
     265             :     else
     266             :     {
     267           0 :       bwest_str->last_reduction_ts = arr_ts + 3*FS;
     268           0 :       bwest_str->last_update_ts = arr_ts;
     269           0 :       bwest_str->num_pkts_rec = 0;
     270             :     }
     271             : 
     272             : 
     273             :     /* temporarily speed up adaptation if frame length has changed */
     274           0 :     if ( frame_length != bwest_str->prev_frame_length )
     275             :     {
     276           0 :       bwest_str->count_tot_updates_rec = 10;
     277           0 :       bwest_str->rec_header_rate = (float)HEADER_SIZE * 8.0f *
     278           0 :           1000.0f / (float)frame_length;     /* bits/s */
     279             : 
     280           0 :       bwest_str->rec_bw_inv = 1.0f /((float)bwest_str->rec_bw +
     281           0 :                                      bwest_str->rec_header_rate);
     282             :     }
     283             : 
     284             :     ////////////////////////
     285           0 :     arr_ts_diff = (float)(arr_ts - bwest_str->prev_rec_arr_ts);
     286             : 
     287           0 :     if (send_ts_diff > 0 )
     288             :     {
     289           0 :       late_diff = arr_ts_diff - send_ts_diff;
     290             :     }
     291             :     else
     292             :     {
     293           0 :       late_diff = arr_ts_diff - (float)(16 * frame_length);
     294             :     }
     295             : 
     296           0 :     if((late_diff > 0) && !bwest_str->inWaitLatePkts)
     297             :     {
     298           0 :       bwest_str->numConsecLatePkts++;
     299           0 :       bwest_str->consecLatency += late_diff;
     300             :     }
     301             :     else
     302             :     {
     303           0 :       bwest_str->numConsecLatePkts = 0;
     304           0 :       bwest_str->consecLatency = 0;
     305             :     }
     306           0 :     if(bwest_str->numConsecLatePkts > 50)
     307             :     {
     308           0 :       float latencyMs = bwest_str->consecLatency/(FS/1000);
     309           0 :       float averageLatencyMs = latencyMs / bwest_str->numConsecLatePkts;
     310           0 :       delay_correction_factor = frame_length / (frame_length + averageLatencyMs);
     311           0 :       immediate_set = 1;
     312           0 :       bwest_str->inWaitLatePkts = (int16_t)((bwest_str->consecLatency/(FS/1000)) / 30);// + 150;
     313           0 :       bwest_str->start_wait_period = arr_ts;
     314             :     }
     315             :     ///////////////////////////////////////////////
     316             : 
     317             : 
     318             : 
     319             :     /*   update only if previous packet was not lost */
     320           0 :     if ( rtp_number == bwest_str->prev_rec_rtp_number + 1 )
     321             :     {
     322             : 
     323             : 
     324           0 :       if (!(bwest_str->hsn_detect_snd && bwest_str->hsn_detect_rec))
     325             :       {
     326           0 :         if ((arr_ts_diff > (float)(16 * frame_length)))
     327             :         {
     328             :           //1/2 second
     329           0 :           if ((late_diff > 8000.0f) && !bwest_str->in_wait_period)
     330             :           {
     331           0 :             delay_correction_factor = 0.7f;
     332           0 :             bwest_str->in_wait_period = 55;
     333           0 :             bwest_str->start_wait_period = arr_ts;
     334           0 :             immediate_set = 1;
     335             :           }
     336             :           //320 ms
     337           0 :           else if (late_diff > 5120.0f && !bwest_str->in_wait_period)
     338             :           {
     339           0 :             delay_correction_factor = 0.8f;
     340           0 :             immediate_set = 1;
     341           0 :             bwest_str->in_wait_period = 44;
     342           0 :             bwest_str->start_wait_period = arr_ts;
     343             :           }
     344             :         }
     345             :       }
     346             : 
     347             : 
     348           0 :       if ((bwest_str->prev_rec_rtp_rate > bwest_str->rec_bw_avg) &&
     349           0 :           (rec_rtp_rate > bwest_str->rec_bw_avg)                 &&
     350           0 :           !bwest_str->in_wait_period)
     351             :       {
     352             :         /* test if still in initiation period and increment counter */
     353           0 :         if (bwest_str->count_tot_updates_rec++ > 99)
     354             :         {
     355             :           /* constant weight after initiation part */
     356           0 :           weight = 0.01f;
     357             :         }
     358             :         else
     359             :         {
     360             :           /* weight decreases with number of updates */
     361           0 :           weight = 1.0f / (float) bwest_str->count_tot_updates_rec;
     362             :         }
     363             :         /* Bottle Neck Estimation */
     364             : 
     365             :         /* limit outliers */
     366             :         /* if more than 25 ms too much */
     367           0 :         if (arr_ts_diff > frame_length * FS/1000 + 400.0f)
     368             :         {
     369             :           // in samples,  why 25ms??
     370           0 :           arr_ts_diff = frame_length * FS/1000 + 400.0f;
     371             :         }
     372           0 :         if(arr_ts_diff < (frame_length * FS/1000) - 160.0f)
     373             :         {
     374             :           /* don't allow it to be less than frame rate - 10 ms */
     375           0 :           arr_ts_diff = (float)frame_length * FS/1000 - 160.0f;
     376             :         }
     377             : 
     378             :         /* compute inverse receiving rate for last packet */
     379           0 :         curr_bw_inv = arr_ts_diff / ((float)(pksize + HEADER_SIZE) *
     380           0 :                                      8.0f * FS); // (180+35)*8*16000 = 27.5 Mbit....
     381             : 
     382             : 
     383           0 :         if(curr_bw_inv <
     384           0 :            (1.0f / (MAX_ISAC_BW + bwest_str->rec_header_rate)))
     385             :         {
     386             :           // don't allow inv rate to be larger than MAX
     387           0 :           curr_bw_inv = (1.0f /
     388           0 :                          (MAX_ISAC_BW + bwest_str->rec_header_rate));
     389             :         }
     390             : 
     391             :         /* update bottle neck rate estimate */
     392           0 :         bwest_str->rec_bw_inv = weight * curr_bw_inv +
     393           0 :             (1.0f - weight) * bwest_str->rec_bw_inv;
     394             : 
     395             :         /* reset time-since-update counter */
     396           0 :         bwest_str->last_update_ts    = arr_ts;
     397           0 :         bwest_str->last_reduction_ts = arr_ts + 3 * FS;
     398           0 :         bwest_str->num_pkts_rec = 0;
     399             : 
     400             :         /* Jitter Estimation */
     401             :         /* projected difference between arrival times */
     402           0 :         t_diff_proj = ((float)(pksize + HEADER_SIZE) * 8.0f *
     403           0 :                        1000.0f) / bwest_str->rec_bw_avg;
     404             : 
     405             : 
     406             :         // difference between projected and actual
     407             :         //   arrival time differences
     408           0 :         arr_time_noise = (float)(arr_ts_diff*1000.0f/FS) -
     409             :             t_diff_proj;
     410           0 :         arr_time_noise_abs = (float) fabs( arr_time_noise );
     411             : 
     412             :         /* long term averaged absolute jitter */
     413           0 :         bwest_str->rec_jitter = weight * arr_time_noise_abs +
     414           0 :             (1.0f - weight) * bwest_str->rec_jitter;
     415           0 :         if (bwest_str->rec_jitter > 10.0f)
     416             :         {
     417           0 :           bwest_str->rec_jitter = 10.0f;
     418             :         }
     419             :         /* short term averaged absolute jitter */
     420           0 :         bwest_str->rec_jitter_short_term_abs = 0.05f *
     421           0 :             arr_time_noise_abs + 0.95f *
     422           0 :             bwest_str->rec_jitter_short_term_abs;
     423             : 
     424             :         /* short term averaged jitter */
     425           0 :         bwest_str->rec_jitter_short_term = 0.05f * arr_time_noise +
     426           0 :             0.95f * bwest_str->rec_jitter_short_term;
     427             :       }
     428             :     }
     429             :   }
     430             :   else
     431             :   {
     432             :     // reset time-since-update counter when
     433             :     // receiving the first 9 packets
     434           0 :     bwest_str->last_update_ts    = arr_ts;
     435           0 :     bwest_str->last_reduction_ts = arr_ts + 3*FS;
     436           0 :     bwest_str->num_pkts_rec = 0;
     437             : 
     438           0 :     bwest_str->count_tot_updates_rec++;
     439             :   }
     440             : 
     441             :   /* limit minimum bottle neck rate */
     442           0 :   if (bwest_str->rec_bw_inv > 1.0f / ((float)MIN_ISAC_BW +
     443           0 :                                       bwest_str->rec_header_rate))
     444             :   {
     445           0 :     bwest_str->rec_bw_inv = 1.0f / ((float)MIN_ISAC_BW +
     446           0 :                                     bwest_str->rec_header_rate);
     447             :   }
     448             : 
     449             :   // limit maximum bitrate
     450           0 :   if (bwest_str->rec_bw_inv < 1.0f / ((float)MAX_ISAC_BW +
     451           0 :                                       bwest_str->rec_header_rate))
     452             :   {
     453           0 :     bwest_str->rec_bw_inv = 1.0f / ((float)MAX_ISAC_BW +
     454           0 :                                     bwest_str->rec_header_rate);
     455             :   }
     456             : 
     457             :   /* store frame length */
     458           0 :   bwest_str->prev_frame_length = frame_length;
     459             : 
     460             :   /* store far-side transmission rate */
     461           0 :   bwest_str->prev_rec_rtp_rate = rec_rtp_rate;
     462             : 
     463             :   /* store far-side RTP time stamp */
     464           0 :   bwest_str->prev_rec_rtp_number = rtp_number;
     465             : 
     466             :   // Replace bwest_str->rec_max_delay by the new
     467             :   // value (atomic operation)
     468           0 :   bwest_str->rec_max_delay = 3.0f * bwest_str->rec_jitter;
     469             : 
     470             :   /* store send and arrival time stamp */
     471           0 :   bwest_str->prev_rec_arr_ts = arr_ts ;
     472           0 :   bwest_str->prev_rec_send_ts = send_ts;
     473             : 
     474             :   /* Replace bwest_str->rec_bw by the new value (atomic operation) */
     475           0 :   bwest_str->rec_bw = (int32_t)(1.0f / bwest_str->rec_bw_inv -
     476           0 :                                       bwest_str->rec_header_rate);
     477             : 
     478           0 :   if (immediate_set)
     479             :   {
     480           0 :     bwest_str->rec_bw = (int32_t) (delay_correction_factor *
     481           0 :                                          (float) bwest_str->rec_bw);
     482             : 
     483           0 :     if (bwest_str->rec_bw < (int32_t) MIN_ISAC_BW)
     484             :     {
     485           0 :       bwest_str->rec_bw = (int32_t) MIN_ISAC_BW;
     486             :     }
     487             : 
     488           0 :     bwest_str->rec_bw_avg = bwest_str->rec_bw +
     489           0 :         bwest_str->rec_header_rate;
     490             : 
     491           0 :     bwest_str->rec_bw_avg_Q = (float) bwest_str->rec_bw;
     492             : 
     493           0 :     bwest_str->rec_jitter_short_term = 0.0f;
     494             : 
     495           0 :     bwest_str->rec_bw_inv = 1.0f / (bwest_str->rec_bw +
     496           0 :                                     bwest_str->rec_header_rate);
     497             : 
     498           0 :     bwest_str->count_tot_updates_rec = 1;
     499             : 
     500           0 :     immediate_set = 0;
     501           0 :     bwest_str->consecLatency = 0;
     502           0 :     bwest_str->numConsecLatePkts = 0;
     503             :   }
     504             : 
     505           0 :   return 0;
     506             : }
     507             : 
     508             : 
     509             : /* This function updates the send bottle neck rate                                                   */
     510             : /* Index         - integer (range 0...23) indicating bottle neck & jitter as estimated by other side */
     511             : /* returns 0 if everything went fine, -1 otherwise                                                   */
     512           0 : int16_t WebRtcIsac_UpdateUplinkBwImpl(
     513             :     BwEstimatorstr*           bwest_str,
     514             :     int16_t               index,
     515             :     enum IsacSamplingRate encoderSamplingFreq)
     516             : {
     517           0 :   RTC_DCHECK(!bwest_str->external_bw_info.in_use);
     518             : 
     519           0 :   if((index < 0) || (index > 23))
     520             :   {
     521           0 :     return -ISAC_RANGE_ERROR_BW_ESTIMATOR;
     522             :   }
     523             : 
     524             :   /* UPDATE ESTIMATES FROM OTHER SIDE */
     525           0 :   if(encoderSamplingFreq == kIsacWideband)
     526             :   {
     527           0 :     if(index > 11)
     528             :     {
     529           0 :       index -= 12;   
     530             :       /* compute the jitter estimate as decoded on the other side */
     531           0 :       bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg +
     532             :           0.1f * (float)MAX_ISAC_MD;
     533             :     }
     534             :     else
     535             :     {
     536             :       /* compute the jitter estimate as decoded on the other side */
     537           0 :       bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg +
     538             :           0.1f * (float)MIN_ISAC_MD;
     539             :     }
     540             : 
     541             :     /* compute the BN estimate as decoded on the other side */
     542           0 :     bwest_str->send_bw_avg = 0.9f * bwest_str->send_bw_avg +
     543           0 :         0.1f * kQRateTableWb[index];
     544             :   }
     545             :   else
     546             :   {
     547             :     /* compute the BN estimate as decoded on the other side */
     548           0 :     bwest_str->send_bw_avg = 0.9f * bwest_str->send_bw_avg +
     549           0 :         0.1f * kQRateTableSwb[index];
     550             :   }
     551             : 
     552           0 :   if (bwest_str->send_bw_avg > (float) 28000 && !bwest_str->hsn_detect_snd)
     553             :   {
     554           0 :     bwest_str->num_consec_snt_pkts_over_30k++;
     555             : 
     556           0 :     if (bwest_str->num_consec_snt_pkts_over_30k >= 66)
     557             :     {
     558             :       //approx 2 seconds with 30ms frames
     559           0 :       bwest_str->hsn_detect_snd = 1;
     560             :     }
     561             :   }
     562           0 :   else if (!bwest_str->hsn_detect_snd)
     563             :   {
     564           0 :     bwest_str->num_consec_snt_pkts_over_30k = 0;
     565             :   }
     566           0 :   return 0;
     567             : }
     568             : 
     569             : // called when there is upper-band bit-stream to update jitter
     570             : // statistics.
     571           0 : int16_t WebRtcIsac_UpdateUplinkJitter(
     572             :     BwEstimatorstr*              bwest_str,
     573             :     int32_t                  index)
     574             : {
     575           0 :   RTC_DCHECK(!bwest_str->external_bw_info.in_use);
     576             : 
     577           0 :   if((index < 0) || (index > 23))
     578             :   {
     579           0 :     return -ISAC_RANGE_ERROR_BW_ESTIMATOR;
     580             :   }
     581             : 
     582           0 :   if(index > 0)
     583             :   {
     584             :     /* compute the jitter estimate as decoded on the other side */
     585           0 :     bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg +
     586             :         0.1f * (float)MAX_ISAC_MD;
     587             :   }
     588             :   else
     589             :   {
     590             :     /* compute the jitter estimate as decoded on the other side */
     591           0 :     bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg +
     592             :         0.1f * (float)MIN_ISAC_MD;
     593             :   }
     594             : 
     595           0 :   return 0;
     596             : }
     597             : 
     598             : 
     599             : 
     600             : // Returns the bandwidth/jitter estimation code (integer 0...23)
     601             : // to put in the sending iSAC payload
     602             : void
     603           0 : WebRtcIsac_GetDownlinkBwJitIndexImpl(
     604             :     BwEstimatorstr*           bwest_str,
     605             :     int16_t*              bottleneckIndex,
     606             :     int16_t*              jitterInfo,
     607             :     enum IsacSamplingRate decoderSamplingFreq)
     608             : {
     609             :   float MaxDelay;
     610             :   //uint16_t MaxDelayBit;
     611             : 
     612             :   float rate;
     613             :   float r;
     614             :   float e1, e2;
     615           0 :   const float weight = 0.1f;
     616             :   const float* ptrQuantizationTable;
     617             :   int16_t addJitterInfo;
     618             :   int16_t minInd;
     619             :   int16_t maxInd;
     620             :   int16_t midInd;
     621             : 
     622           0 :   if (bwest_str->external_bw_info.in_use) {
     623           0 :     *bottleneckIndex = bwest_str->external_bw_info.bottleneck_idx;
     624           0 :     *jitterInfo = bwest_str->external_bw_info.jitter_info;
     625           0 :     return;
     626             :   }
     627             : 
     628             :   /* Get Max Delay Bit */
     629             :   /* get unquantized max delay */
     630           0 :   MaxDelay = (float)WebRtcIsac_GetDownlinkMaxDelay(bwest_str);
     631             : 
     632           0 :   if ( ((1.f - weight) * bwest_str->rec_max_delay_avg_Q + weight *
     633           0 :         MAX_ISAC_MD - MaxDelay) > (MaxDelay - (1.f-weight) *
     634           0 :                                    bwest_str->rec_max_delay_avg_Q - weight * MIN_ISAC_MD) )
     635             :   {
     636           0 :     jitterInfo[0] = 0;
     637             :     /* update quantized average */
     638           0 :     bwest_str->rec_max_delay_avg_Q =
     639           0 :         (1.f - weight) * bwest_str->rec_max_delay_avg_Q + weight *
     640             :         (float)MIN_ISAC_MD;
     641             :   }
     642             :   else
     643             :   {
     644           0 :     jitterInfo[0] = 1;
     645             :     /* update quantized average */
     646           0 :     bwest_str->rec_max_delay_avg_Q =
     647           0 :         (1.f-weight) * bwest_str->rec_max_delay_avg_Q + weight *
     648             :         (float)MAX_ISAC_MD;
     649             :   }
     650             : 
     651             :   // Get unquantized rate.
     652           0 :   rate = (float)WebRtcIsac_GetDownlinkBandwidth(bwest_str);
     653             : 
     654             :   /* Get Rate Index */
     655           0 :   if(decoderSamplingFreq == kIsacWideband)
     656             :   {
     657           0 :     ptrQuantizationTable = kQRateTableWb;
     658           0 :     addJitterInfo = 1;
     659           0 :     maxInd = 11;
     660             :   }
     661             :   else
     662             :   {
     663           0 :     ptrQuantizationTable = kQRateTableSwb;
     664           0 :     addJitterInfo = 0;
     665           0 :     maxInd = 23;
     666             :   }
     667             : 
     668           0 :   minInd = 0;
     669           0 :   while(maxInd > minInd + 1)
     670             :   {
     671           0 :     midInd = (maxInd + minInd) >> 1;
     672           0 :     if(rate > ptrQuantizationTable[midInd])
     673             :     {
     674           0 :       minInd = midInd;
     675             :     }
     676             :     else
     677             :     {
     678           0 :       maxInd = midInd;
     679             :     }
     680             :   }
     681             :   // Chose the index which gives results an average which is closest
     682             :   // to rate
     683           0 :   r = (1 - weight) * bwest_str->rec_bw_avg_Q - rate;
     684           0 :   e1 = weight * ptrQuantizationTable[minInd] + r;
     685           0 :   e2 = weight * ptrQuantizationTable[maxInd] + r;
     686           0 :   e1 = (e1 > 0)? e1:-e1;
     687           0 :   e2 = (e2 > 0)? e2:-e2;
     688           0 :   if(e1 < e2)
     689             :   {
     690           0 :     bottleneckIndex[0] = minInd;
     691             :   }
     692             :   else
     693             :   {
     694           0 :     bottleneckIndex[0] = maxInd;
     695             :   }
     696             : 
     697           0 :   bwest_str->rec_bw_avg_Q = (1 - weight) * bwest_str->rec_bw_avg_Q +
     698           0 :       weight * ptrQuantizationTable[bottleneckIndex[0]];
     699           0 :   bottleneckIndex[0] += jitterInfo[0] * 12 * addJitterInfo;
     700             : 
     701           0 :   bwest_str->rec_bw_avg = (1 - weight) * bwest_str->rec_bw_avg + weight *
     702           0 :       (rate + bwest_str->rec_header_rate);
     703             : }
     704             : 
     705             : 
     706             : 
     707             : /* get the bottle neck rate from far side to here, as estimated on this side */
     708           0 : int32_t WebRtcIsac_GetDownlinkBandwidth( const BwEstimatorstr *bwest_str)
     709             : {
     710             :   int32_t  rec_bw;
     711             :   float   jitter_sign;
     712             :   float   bw_adjust;
     713             : 
     714           0 :   RTC_DCHECK(!bwest_str->external_bw_info.in_use);
     715             : 
     716             :   /* create a value between -1.0 and 1.0 indicating "average sign" of jitter */
     717           0 :   jitter_sign = bwest_str->rec_jitter_short_term /
     718           0 :       bwest_str->rec_jitter_short_term_abs;
     719             : 
     720             :   /* adjust bw proportionally to negative average jitter sign */
     721           0 :   bw_adjust = 1.0f - jitter_sign * (0.15f + 0.15f * jitter_sign * jitter_sign);
     722             : 
     723             :   /* adjust Rate if jitter sign is mostly constant */
     724           0 :   rec_bw = (int32_t)(bwest_str->rec_bw * bw_adjust);
     725             : 
     726             :   /* limit range of bottle neck rate */
     727           0 :   if (rec_bw < MIN_ISAC_BW)
     728             :   {
     729           0 :     rec_bw = MIN_ISAC_BW;
     730             :   }
     731           0 :   else if (rec_bw > MAX_ISAC_BW)
     732             :   {
     733           0 :     rec_bw = MAX_ISAC_BW;
     734             :   }
     735           0 :   return rec_bw;
     736             : }
     737             : 
     738             : /* Returns the max delay (in ms) */
     739             : int32_t
     740           0 : WebRtcIsac_GetDownlinkMaxDelay(const BwEstimatorstr *bwest_str)
     741             : {
     742             :   int32_t rec_max_delay;
     743             : 
     744           0 :   RTC_DCHECK(!bwest_str->external_bw_info.in_use);
     745             : 
     746           0 :   rec_max_delay = (int32_t)(bwest_str->rec_max_delay);
     747             : 
     748             :   /* limit range of jitter estimate */
     749           0 :   if (rec_max_delay < MIN_ISAC_MD)
     750             :   {
     751           0 :     rec_max_delay = MIN_ISAC_MD;
     752             :   }
     753           0 :   else if (rec_max_delay > MAX_ISAC_MD)
     754             :   {
     755           0 :     rec_max_delay = MAX_ISAC_MD;
     756             :   }
     757           0 :   return rec_max_delay;
     758             : }
     759             : 
     760             : /* Clamp val to the closed interval [min,max]. */
     761           0 : static int32_t clamp(int32_t val, int32_t min, int32_t max) {
     762           0 :   RTC_DCHECK_LE(min, max);
     763           0 :   return val < min ? min : (val > max ? max : val);
     764             : }
     765             : 
     766           0 : int32_t WebRtcIsac_GetUplinkBandwidth(const BwEstimatorstr* bwest_str) {
     767           0 :   return bwest_str->external_bw_info.in_use
     768             :              ? bwest_str->external_bw_info.send_bw_avg
     769           0 :              : clamp(bwest_str->send_bw_avg, MIN_ISAC_BW, MAX_ISAC_BW);
     770             : }
     771             : 
     772           0 : int32_t WebRtcIsac_GetUplinkMaxDelay(const BwEstimatorstr* bwest_str) {
     773           0 :   return bwest_str->external_bw_info.in_use
     774             :              ? bwest_str->external_bw_info.send_max_delay_avg
     775           0 :              : clamp(bwest_str->send_max_delay_avg, MIN_ISAC_MD, MAX_ISAC_MD);
     776             : }
     777             : 
     778           0 : void WebRtcIsacBw_GetBandwidthInfo(BwEstimatorstr* bwest_str,
     779             :                                    enum IsacSamplingRate decoder_sample_rate_hz,
     780             :                                    IsacBandwidthInfo* bwinfo) {
     781           0 :   RTC_DCHECK(!bwest_str->external_bw_info.in_use);
     782           0 :   bwinfo->in_use = 1;
     783           0 :   bwinfo->send_bw_avg = WebRtcIsac_GetUplinkBandwidth(bwest_str);
     784           0 :   bwinfo->send_max_delay_avg = WebRtcIsac_GetUplinkMaxDelay(bwest_str);
     785           0 :   WebRtcIsac_GetDownlinkBwJitIndexImpl(bwest_str, &bwinfo->bottleneck_idx,
     786             :                                        &bwinfo->jitter_info,
     787             :                                        decoder_sample_rate_hz);
     788           0 : }
     789             : 
     790           0 : void WebRtcIsacBw_SetBandwidthInfo(BwEstimatorstr* bwest_str,
     791             :                                    const IsacBandwidthInfo* bwinfo) {
     792           0 :   memcpy(&bwest_str->external_bw_info, bwinfo,
     793             :          sizeof bwest_str->external_bw_info);
     794           0 : }
     795             : 
     796             : /*
     797             :  * update long-term average bitrate and amount of data in buffer
     798             :  * returns minimum payload size (bytes)
     799             :  */
     800           0 : int WebRtcIsac_GetMinBytes(
     801             :     RateModel*         State,
     802             :     int                StreamSize,    /* bytes in bitstream */
     803             :     const int          FrameSamples,  /* samples per frame */
     804             :     const double       BottleNeck,    /* bottle neck rate; excl headers (bps) */
     805             :     const double       DelayBuildUp,  /* max delay from bottleneck buffering (ms) */
     806             :     enum ISACBandwidth bandwidth
     807             :     /*,int16_t        frequentLargePackets*/)
     808             : {
     809           0 :   double MinRate = 0.0;
     810             :   int    MinBytes;
     811             :   double TransmissionTime;
     812           0 :   int    burstInterval = BURST_INTERVAL;
     813             : 
     814             :   // first 10 packets @ low rate, then INIT_BURST_LEN packets @
     815             :   // fixed rate of INIT_RATE bps
     816           0 :   if (State->InitCounter > 0)
     817             :   {
     818           0 :     if (State->InitCounter-- <= INIT_BURST_LEN)
     819             :     {
     820           0 :       if(bandwidth == isac8kHz)
     821             :       {
     822           0 :         MinRate = INIT_RATE_WB;
     823             :       }
     824             :       else
     825             :       {
     826           0 :         MinRate = INIT_RATE_SWB;
     827             :       }
     828             :     }
     829             :     else
     830             :     {
     831           0 :       MinRate = 0;
     832             :     }
     833             :   }
     834             :   else
     835             :   {
     836             :     /* handle burst */
     837           0 :     if (State->BurstCounter)
     838             :     {
     839           0 :       if (State->StillBuffered < (1.0 - 1.0/BURST_LEN) * DelayBuildUp)
     840             :       {
     841             :         /* max bps derived from BottleNeck and DelayBuildUp values */
     842           0 :         MinRate = (1.0 + (FS/1000) * DelayBuildUp /
     843           0 :                    (double)(BURST_LEN * FrameSamples)) * BottleNeck;
     844             :       }
     845             :       else
     846             :       {
     847             :         // max bps derived from StillBuffered and DelayBuildUp
     848             :         // values
     849           0 :         MinRate = (1.0 + (FS/1000) * (DelayBuildUp -
     850           0 :                                       State->StillBuffered) / (double)FrameSamples) * BottleNeck;
     851           0 :         if (MinRate < 1.04 * BottleNeck)
     852             :         {
     853           0 :           MinRate = 1.04 * BottleNeck;
     854             :         }
     855             :       }
     856           0 :       State->BurstCounter--;
     857             :     }
     858             :   }
     859             : 
     860             : 
     861             :   /* convert rate from bits/second to bytes/packet */
     862           0 :   MinBytes = (int) (MinRate * FrameSamples / (8.0 * FS));
     863             : 
     864             :   /* StreamSize will be adjusted if less than MinBytes */
     865           0 :   if (StreamSize < MinBytes)
     866             :   {
     867           0 :     StreamSize = MinBytes;
     868             :   }
     869             : 
     870             :   /* keep track of when bottle neck was last exceeded by at least 1% */
     871           0 :   if (StreamSize * 8.0 * FS / FrameSamples > 1.01 * BottleNeck) {
     872           0 :     if (State->PrevExceed) {
     873             :       /* bottle_neck exceded twice in a row, decrease ExceedAgo */
     874           0 :       State->ExceedAgo -= /*BURST_INTERVAL*/ burstInterval / (BURST_LEN - 1);
     875           0 :       if (State->ExceedAgo < 0)
     876           0 :         State->ExceedAgo = 0;
     877             :     }
     878             :     else
     879             :     {
     880           0 :       State->ExceedAgo += (FrameSamples * 1000) / FS; /* ms */
     881           0 :       State->PrevExceed = 1;
     882             :     }
     883             :   }
     884             :   else
     885             :   {
     886           0 :     State->PrevExceed = 0;
     887           0 :     State->ExceedAgo += (FrameSamples * 1000) / FS;     /* ms */
     888             :   }
     889             : 
     890             :   /* set burst flag if bottle neck not exceeded for long time */
     891           0 :   if ((State->ExceedAgo > burstInterval) &&
     892           0 :       (State->BurstCounter == 0))
     893             :   {
     894           0 :     if (State->PrevExceed)
     895             :     {
     896           0 :       State->BurstCounter = BURST_LEN - 1;
     897             :     }
     898             :     else
     899             :     {
     900           0 :       State->BurstCounter = BURST_LEN;
     901             :     }
     902             :   }
     903             : 
     904             : 
     905             :   /* Update buffer delay */
     906           0 :   TransmissionTime = StreamSize * 8.0 * 1000.0 / BottleNeck;  /* ms */
     907           0 :   State->StillBuffered += TransmissionTime;
     908           0 :   State->StillBuffered -= (FrameSamples * 1000) / FS;     /* ms */
     909           0 :   if (State->StillBuffered < 0.0)
     910             :   {
     911           0 :     State->StillBuffered = 0.0;
     912             :   }
     913             : 
     914           0 :   return MinBytes;
     915             : }
     916             : 
     917             : 
     918             : /*
     919             :  * update long-term average bitrate and amount of data in buffer
     920             :  */
     921           0 : void WebRtcIsac_UpdateRateModel(
     922             :     RateModel *State,
     923             :     int StreamSize,                    /* bytes in bitstream */
     924             :     const int FrameSamples,            /* samples per frame */
     925             :     const double BottleNeck)        /* bottle neck rate; excl headers (bps) */
     926             : {
     927             :   double TransmissionTime;
     928             : 
     929             :   /* avoid the initial "high-rate" burst */
     930           0 :   State->InitCounter = 0;
     931             : 
     932             :   /* Update buffer delay */
     933           0 :   TransmissionTime = StreamSize * 8.0 * 1000.0 / BottleNeck;  /* ms */
     934           0 :   State->StillBuffered += TransmissionTime;
     935           0 :   State->StillBuffered -= (FrameSamples * 1000) / FS;     /* ms */
     936           0 :   if (State->StillBuffered < 0.0)
     937           0 :     State->StillBuffered = 0.0;
     938             : 
     939           0 : }
     940             : 
     941             : 
     942           0 : void WebRtcIsac_InitRateModel(
     943             :     RateModel *State)
     944             : {
     945           0 :   State->PrevExceed      = 0;                        /* boolean */
     946           0 :   State->ExceedAgo       = 0;                        /* ms */
     947           0 :   State->BurstCounter    = 0;                        /* packets */
     948           0 :   State->InitCounter     = INIT_BURST_LEN + 10;    /* packets */
     949           0 :   State->StillBuffered   = 1.0;                    /* ms */
     950           0 : }
     951             : 
     952           0 : int WebRtcIsac_GetNewFrameLength(
     953             :     double bottle_neck,
     954             :     int    current_framesamples)
     955             : {
     956             :   int new_framesamples;
     957             : 
     958           0 :   const int Thld_20_30 = 20000;
     959             : 
     960             :   //const int Thld_30_20 = 30000;
     961           0 :   const int Thld_30_20 = 1000000;   // disable 20 ms frames
     962             : 
     963           0 :   const int Thld_30_60 = 18000;
     964             :   //const int Thld_30_60 = 0;      // disable 60 ms frames
     965             : 
     966           0 :   const int Thld_60_30 = 27000;
     967             : 
     968             : 
     969           0 :   new_framesamples = current_framesamples;
     970             : 
     971             :   /* find new framelength */
     972           0 :   switch(current_framesamples) {
     973             :     case 320:
     974           0 :       if (bottle_neck < Thld_20_30)
     975           0 :         new_framesamples = 480;
     976           0 :       break;
     977             :     case 480:
     978           0 :       if (bottle_neck < Thld_30_60)
     979           0 :         new_framesamples = 960;
     980           0 :       else if (bottle_neck > Thld_30_20)
     981           0 :         new_framesamples = 320;
     982           0 :       break;
     983             :     case 960:
     984           0 :       if (bottle_neck >= Thld_60_30)
     985           0 :         new_framesamples = 480;
     986           0 :       break;
     987             :   }
     988             : 
     989           0 :   return new_framesamples;
     990             : }
     991             : 
     992           0 : double WebRtcIsac_GetSnr(
     993             :     double bottle_neck,
     994             :     int    framesamples)
     995             : {
     996             :   double s2nr;
     997             : 
     998           0 :   const double a_20 = -30.0;
     999           0 :   const double b_20 = 0.8;
    1000           0 :   const double c_20 = 0.0;
    1001             : 
    1002           0 :   const double a_30 = -23.0;
    1003           0 :   const double b_30 = 0.48;
    1004           0 :   const double c_30 = 0.0;
    1005             : 
    1006           0 :   const double a_60 = -23.0;
    1007           0 :   const double b_60 = 0.53;
    1008           0 :   const double c_60 = 0.0;
    1009             : 
    1010             : 
    1011             :   /* find new SNR value */
    1012           0 :   switch(framesamples) {
    1013             :     case 320:
    1014           0 :       s2nr = a_20 + b_20 * bottle_neck * 0.001 + c_20 * bottle_neck *
    1015           0 :           bottle_neck * 0.000001;
    1016           0 :       break;
    1017             :     case 480:
    1018           0 :       s2nr = a_30 + b_30 * bottle_neck * 0.001 + c_30 * bottle_neck *
    1019           0 :           bottle_neck * 0.000001;
    1020           0 :       break;
    1021             :     case 960:
    1022           0 :       s2nr = a_60 + b_60 * bottle_neck * 0.001 + c_60 * bottle_neck *
    1023           0 :           bottle_neck * 0.000001;
    1024           0 :       break;
    1025             :     default:
    1026           0 :       s2nr = 0;
    1027             :   }
    1028             : 
    1029           0 :   return s2nr;
    1030             : 
    1031             : }

Generated by: LCOV version 1.13