CongestionControl.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. //
  2. // libtgvoip is free and unencumbered public domain software.
  3. // For more information, see http://unlicense.org or the UNLICENSE file
  4. // you should have received with this source code distribution.
  5. //
  6. #include "CongestionControl.h"
  7. #include "VoIPController.h"
  8. #include "logging.h"
  9. #include "VoIPServerConfig.h"
  10. #include "PrivateDefines.h"
  11. #include <math.h>
  12. #include <assert.h>
  13. using namespace tgvoip;
  14. CongestionControl::CongestionControl(){
  15. memset(inflightPackets, 0, sizeof(inflightPackets));
  16. tmpRtt=0;
  17. tmpRttCount=0;
  18. lastSentSeq=0;
  19. lastActionTime=0;
  20. lastActionRtt=0;
  21. stateTransitionTime=0;
  22. inflightDataSize=0;
  23. lossCount=0;
  24. cwnd=(size_t) ServerConfig::GetSharedInstance()->GetInt("audio_congestion_window", 1024);
  25. }
  26. CongestionControl::~CongestionControl(){
  27. }
  28. size_t CongestionControl::GetAcknowledgedDataSize(){
  29. return 0;
  30. }
  31. double CongestionControl::GetAverageRTT(){
  32. return rttHistory.NonZeroAverage();
  33. }
  34. size_t CongestionControl::GetInflightDataSize(){
  35. return inflightHistory.Average();
  36. }
  37. size_t CongestionControl::GetCongestionWindow(){
  38. return cwnd;
  39. }
  40. double CongestionControl::GetMinimumRTT(){
  41. return rttHistory.Min();
  42. }
  43. void CongestionControl::PacketAcknowledged(uint32_t seq){
  44. MutexGuard sync(mutex);
  45. int i;
  46. for(i=0;i<100;i++){
  47. if(inflightPackets[i].seq==seq && inflightPackets[i].sendTime>0){
  48. tmpRtt+=(VoIPController::GetCurrentTime()-inflightPackets[i].sendTime);
  49. tmpRttCount++;
  50. inflightPackets[i].sendTime=0;
  51. inflightDataSize-=inflightPackets[i].size;
  52. break;
  53. }
  54. }
  55. }
  56. void CongestionControl::PacketSent(uint32_t seq, size_t size){
  57. if(!seqgt(seq, lastSentSeq) || seq==lastSentSeq){
  58. LOGW("Duplicate outgoing seq %u", seq);
  59. return;
  60. }
  61. lastSentSeq=seq;
  62. MutexGuard sync(mutex);
  63. double smallestSendTime=INFINITY;
  64. tgvoip_congestionctl_packet_t* slot=NULL;
  65. int i;
  66. for(i=0;i<100;i++){
  67. if(inflightPackets[i].sendTime==0){
  68. slot=&inflightPackets[i];
  69. break;
  70. }
  71. if(smallestSendTime>inflightPackets[i].sendTime){
  72. slot=&inflightPackets[i];
  73. smallestSendTime=slot->sendTime;
  74. }
  75. }
  76. assert(slot!=NULL);
  77. if(slot->sendTime>0){
  78. inflightDataSize-=slot->size;
  79. lossCount++;
  80. LOGD("Packet with seq %u was not acknowledged", slot->seq);
  81. }
  82. slot->seq=seq;
  83. slot->size=size;
  84. slot->sendTime=VoIPController::GetCurrentTime();
  85. inflightDataSize+=size;
  86. }
  87. void CongestionControl::Tick(){
  88. tickCount++;
  89. MutexGuard sync(mutex);
  90. if(tmpRttCount>0){
  91. rttHistory.Add(tmpRtt/tmpRttCount);
  92. tmpRtt=0;
  93. tmpRttCount=0;
  94. }
  95. int i;
  96. for(i=0;i<100;i++){
  97. if(inflightPackets[i].sendTime!=0 && VoIPController::GetCurrentTime()-inflightPackets[i].sendTime>2){
  98. inflightPackets[i].sendTime=0;
  99. inflightDataSize-=inflightPackets[i].size;
  100. lossCount++;
  101. LOGD("Packet with seq %u was not acknowledged", inflightPackets[i].seq);
  102. }
  103. }
  104. inflightHistory.Add(inflightDataSize);
  105. }
  106. int CongestionControl::GetBandwidthControlAction(){
  107. if(VoIPController::GetCurrentTime()-lastActionTime<1)
  108. return TGVOIP_CONCTL_ACT_NONE;
  109. size_t inflightAvg=GetInflightDataSize();
  110. size_t max=cwnd+cwnd/10;
  111. size_t min=cwnd-cwnd/10;
  112. if(inflightAvg<min){
  113. lastActionTime=VoIPController::GetCurrentTime();
  114. return TGVOIP_CONCTL_ACT_INCREASE;
  115. }
  116. if(inflightAvg>max){
  117. lastActionTime=VoIPController::GetCurrentTime();
  118. return TGVOIP_CONCTL_ACT_DECREASE;
  119. }
  120. return TGVOIP_CONCTL_ACT_NONE;
  121. }
  122. uint32_t CongestionControl::GetSendLossCount(){
  123. return lossCount;
  124. }