mediasoup 3.28.0 → 3.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/node/lib/PipeTransportTypes.d.ts +6 -1
  3. package/node/lib/PipeTransportTypes.d.ts.map +1 -1
  4. package/node/lib/PlainTransportTypes.d.ts +6 -1
  5. package/node/lib/PlainTransportTypes.d.ts.map +1 -1
  6. package/node/lib/Router.d.ts +4 -4
  7. package/node/lib/Router.d.ts.map +1 -1
  8. package/node/lib/Router.js +10 -7
  9. package/node/lib/RouterTypes.d.ts +7 -1
  10. package/node/lib/RouterTypes.d.ts.map +1 -1
  11. package/node/lib/Transport.d.ts +2 -1
  12. package/node/lib/Transport.d.ts.map +1 -1
  13. package/node/lib/Transport.js +17 -6
  14. package/node/lib/TransportTypes.d.ts +12 -2
  15. package/node/lib/TransportTypes.d.ts.map +1 -1
  16. package/node/lib/WebRtcTransportTypes.d.ts +6 -1
  17. package/node/lib/WebRtcTransportTypes.d.ts.map +1 -1
  18. package/node/lib/fbs/transport/options.d.ts +6 -2
  19. package/node/lib/fbs/transport/options.d.ts.map +1 -1
  20. package/node/lib/fbs/transport/options.js +19 -7
  21. package/node/lib/fbs/transport/sctp-zero-checksum.d.ts +6 -0
  22. package/node/lib/fbs/transport/sctp-zero-checksum.d.ts.map +1 -0
  23. package/node/lib/fbs/transport/sctp-zero-checksum.js +11 -0
  24. package/node/lib/fbs/transport/stats.d.ts +2 -8
  25. package/node/lib/fbs/transport/stats.d.ts.map +1 -1
  26. package/node/lib/fbs/transport/stats.js +5 -29
  27. package/node/lib/fbs/transport.d.ts +1 -0
  28. package/node/lib/fbs/transport.d.ts.map +1 -1
  29. package/node/lib/fbs/transport.js +4 -2
  30. package/npm-scripts.mjs +35 -44
  31. package/package.json +10 -6
  32. package/worker/fbs/transport.fbs +9 -2
  33. package/worker/fuzzer/src/RTC/RTP/FuzzerRetransmissionBuffer.cpp +14 -1
  34. package/worker/fuzzer/src/RTC/RTP/FuzzerRtpStreamSend.cpp +17 -4
  35. package/worker/include/RTC/BWE/AimdRateControl.hpp +9 -9
  36. package/worker/include/RTC/BWE/BweTypes.hpp +54 -17
  37. package/worker/include/RTC/BWE/DelayBasedBwe.hpp +3 -3
  38. package/worker/include/RTC/BWE/FeedbackAdapter.hpp +2 -2
  39. package/worker/include/RTC/BWE/LossBasedController.hpp +4 -4
  40. package/worker/include/RTC/BWE/OveruseDetector.hpp +5 -4
  41. package/worker/include/RTC/BWE/ProbeBitrateEstimator.hpp +1 -1
  42. package/worker/include/RTC/BWE/ProbeController.hpp +6 -6
  43. package/worker/include/RTC/BWE/ProbePacketGenerator.hpp +2 -6
  44. package/worker/include/RTC/BWE/ProbingScheduler.hpp +3 -7
  45. package/worker/include/RTC/BWE/ReceiverTransportCongestionController.hpp +148 -0
  46. package/worker/include/RTC/BWE/RembGenerator.hpp +4 -3
  47. package/worker/include/RTC/BWE/RemoteBitrateEstimatorAbsSendTime.hpp +1 -1
  48. package/worker/include/RTC/BWE/SenderTransportCongestionController.hpp +343 -0
  49. package/worker/include/RTC/BWE/TargetRateController.hpp +4 -1
  50. package/worker/include/RTC/BWE/TransportWideCcFeedbackGenerator.hpp +5 -4
  51. package/worker/include/RTC/BWE/TrendlineEstimator.hpp +3 -3
  52. package/worker/include/RTC/Consumer.hpp +8 -1
  53. package/worker/include/RTC/RTP/RetransmissionBuffer.hpp +36 -10
  54. package/worker/include/RTC/RTP/RtpStream.hpp +21 -0
  55. package/worker/include/RTC/RTP/RtpStreamRecv.hpp +1 -0
  56. package/worker/include/RTC/RTP/RtpStreamSend.hpp +122 -9
  57. package/worker/include/RTC/SCTP/packet/parameters/ZeroChecksumAcceptableParameter.hpp +12 -3
  58. package/worker/include/RTC/TransportCongestionControlClient.hpp +0 -5
  59. package/worker/include/RTC/TransportCongestionControlServer.hpp +0 -5
  60. package/worker/include/Utils.hpp +9 -2
  61. package/worker/meson.build +4 -0
  62. package/worker/src/RTC/BWE/AimdRateControl.cpp +22 -22
  63. package/worker/src/RTC/BWE/DelayBasedBwe.cpp +16 -20
  64. package/worker/src/RTC/BWE/FeedbackAdapter.cpp +1 -1
  65. package/worker/src/RTC/BWE/OveruseDetector.cpp +8 -8
  66. package/worker/src/RTC/BWE/ProbeBitrateEstimator.cpp +2 -2
  67. package/worker/src/RTC/BWE/ProbeController.cpp +1 -1
  68. package/worker/src/RTC/BWE/ProbePacketGenerator.cpp +1 -6
  69. package/worker/src/RTC/BWE/ProbingScheduler.cpp +2 -7
  70. package/worker/src/RTC/BWE/ReceiverTransportCongestionController.cpp +207 -0
  71. package/worker/src/RTC/BWE/RembGenerator.cpp +1 -1
  72. package/worker/src/RTC/BWE/RemoteBitrateEstimatorAbsSendTime.cpp +1 -1
  73. package/worker/src/RTC/BWE/SenderTransportCongestionController.cpp +599 -0
  74. package/worker/src/RTC/BWE/TransportWideCcFeedbackGenerator.cpp +2 -3
  75. package/worker/src/RTC/BWE/TrendlineEstimator.cpp +5 -5
  76. package/worker/src/RTC/Consumer.cpp +3 -2
  77. package/worker/src/RTC/DataConsumer.cpp +2 -2
  78. package/worker/src/RTC/RTP/RetransmissionBuffer.cpp +21 -8
  79. package/worker/src/RTC/RTP/RtpStream.cpp +0 -3
  80. package/worker/src/RTC/RTP/RtpStreamRecv.cpp +57 -71
  81. package/worker/src/RTC/RTP/RtpStreamSend.cpp +428 -244
  82. package/worker/src/RTC/RTP/RtxStream.cpp +14 -19
  83. package/worker/src/RTC/SCTP/association/Association.cpp +3 -2
  84. package/worker/src/RTC/SCTP/association/StateCookie.cpp +26 -6
  85. package/worker/src/RTC/SCTP/packet/parameters/ZeroChecksumAcceptableParameter.cpp +4 -3
  86. package/worker/src/RTC/SCTP/rx/ReassemblyQueue.cpp +2 -1
  87. package/worker/src/RTC/SCTP/tx/RetransmissionQueue.cpp +4 -2
  88. package/worker/src/RTC/Transport.cpp +49 -20
  89. package/worker/src/RTC/TransportCongestionControlClient.cpp +0 -66
  90. package/worker/src/RTC/TransportCongestionControlServer.cpp +0 -55
  91. package/worker/src/Utils/Crypto.cpp +114 -98
  92. package/worker/subprojects/catch2.wrap +6 -6
  93. package/worker/subprojects/openssl.wrap +11 -12
  94. package/worker/subprojects/packagefiles/ankerl-unordered-dense/meson.build +1 -1
  95. package/worker/subprojects/unordered-dense.wrap +4 -4
  96. package/worker/test/src/RTC/BWE/TestDelayBasedBwe.cpp +5 -5
  97. package/worker/test/src/RTC/BWE/TestFeedbackAdapter.cpp +26 -23
  98. package/worker/test/src/RTC/BWE/TestInterArrivalDelta.cpp +8 -8
  99. package/worker/test/src/RTC/BWE/TestOveruseDetector.cpp +4 -4
  100. package/worker/test/src/RTC/BWE/TestProbeController.cpp +35 -32
  101. package/worker/test/src/RTC/BWE/TestProbePacketGenerator.cpp +2 -17
  102. package/worker/test/src/RTC/BWE/TestProbingScheduler.cpp +1 -25
  103. package/worker/test/src/RTC/BWE/TestReceiverTransportCongestionController.cpp +346 -0
  104. package/worker/test/src/RTC/BWE/TestRembGenerator.cpp +1 -1
  105. package/worker/test/src/RTC/BWE/TestRemoteBitrateEstimatorAbsSendTime.cpp +9 -9
  106. package/worker/test/src/RTC/BWE/TestSenderTransportCongestionController.cpp +510 -0
  107. package/worker/test/src/RTC/BWE/TestTransportWideCcFeedbackGenerator.cpp +16 -14
  108. package/worker/test/src/RTC/BWE/TestTrendlineEstimator.cpp +6 -6
  109. package/worker/test/src/RTC/BWE/helpers/RemoteBitrateEstimatorAbsSendTimeTestHelper.cpp +1 -2
  110. package/worker/test/src/RTC/RTCP/TestBye.cpp +1 -1
  111. package/worker/test/src/RTC/RTCP/TestFeedbackPsAfb.cpp +1 -1
  112. package/worker/test/src/RTC/RTCP/TestFeedbackPsFir.cpp +1 -1
  113. package/worker/test/src/RTC/RTCP/TestFeedbackPsLei.cpp +1 -1
  114. package/worker/test/src/RTC/RTCP/TestFeedbackPsPli.cpp +1 -1
  115. package/worker/test/src/RTC/RTCP/TestFeedbackPsRemb.cpp +1 -1
  116. package/worker/test/src/RTC/RTCP/TestFeedbackPsRpsi.cpp +1 -1
  117. package/worker/test/src/RTC/RTCP/TestFeedbackPsSli.cpp +1 -1
  118. package/worker/test/src/RTC/RTCP/TestFeedbackPsTst.cpp +1 -1
  119. package/worker/test/src/RTC/RTCP/TestFeedbackPsVbcm.cpp +1 -1
  120. package/worker/test/src/RTC/RTCP/TestFeedbackRtpEcn.cpp +1 -1
  121. package/worker/test/src/RTC/RTCP/TestFeedbackRtpNack.cpp +1 -1
  122. package/worker/test/src/RTC/RTCP/TestFeedbackRtpSrReq.cpp +1 -1
  123. package/worker/test/src/RTC/RTCP/TestFeedbackRtpTllei.cpp +1 -1
  124. package/worker/test/src/RTC/RTCP/TestFeedbackRtpTmmb.cpp +1 -1
  125. package/worker/test/src/RTC/RTCP/TestFeedbackRtpTransport.cpp +1 -1
  126. package/worker/test/src/RTC/RTCP/TestReceiverReport.cpp +1 -1
  127. package/worker/test/src/RTC/RTCP/TestSenderReport.cpp +1 -1
  128. package/worker/test/src/RTC/RTP/TestRetransmissionBuffer.cpp +60 -28
  129. package/worker/test/src/RTC/RTP/TestRtpStreamRecv.cpp +1 -1
  130. package/worker/test/src/RTC/RTP/TestRtpStreamSend.cpp +746 -24
  131. package/worker/test/src/RTC/RTP/TestSharedPacket.cpp +1 -1
  132. package/worker/test/src/RTC/SCTP/association/TestAssociation.cpp +42 -0
  133. package/worker/test/src/RTC/SCTP/association/TestNegotiatedCapabilities.cpp +54 -5
  134. package/worker/test/src/RTC/SCTP/association/TestStateCookie.cpp +80 -15
  135. package/worker/test/src/RTC/SCTP/association/TestStreamResetHandler.cpp +410 -3
  136. package/worker/test/src/RTC/SCTP/association/TestTransmissionControlBlock.cpp +1 -1
  137. package/worker/test/src/RTC/SCTP/packet/parameters/TestZeroChecksumAcceptableParameter.cpp +37 -5
  138. package/worker/test/src/RTC/SCTP/rx/TestDataTracker.cpp +5 -4
  139. package/worker/test/src/RTC/SCTP/rx/TestInterleavedReassemblyStreams.cpp +1 -1
  140. package/worker/test/src/RTC/SCTP/rx/TestReassemblyQueue.cpp +1 -1
  141. package/worker/test/src/RTC/SCTP/rx/TestTraditionalReassemblyStreams.cpp +1 -1
  142. package/worker/test/src/RTC/SCTP/tx/TestOutstandingData.cpp +1 -1
  143. package/worker/test/src/RTC/SCTP/tx/TestRetransmissionQueue.cpp +11 -10
  144. package/worker/test/src/RTC/SCTP/tx/TestRetransmissionTimeout.cpp +1 -1
  145. package/worker/test/src/RTC/TestNackGenerator.cpp +1 -1
  146. package/worker/test/src/RTC/TestPortManager.cpp +2 -2
  147. package/worker/test/src/RTC/TestRateCalculator.cpp +1 -1
  148. package/worker/test/src/RTC/TestRemoteCaptureTimeEstimator.cpp +21 -15
  149. package/worker/test/src/RTC/TestRemoteClockOffsetEstimator.cpp +13 -13
  150. package/worker/test/src/RTC/TestRtpEncodingParameters.cpp +1 -1
  151. package/worker/test/src/RTC/TestSubchannelsCodec.cpp +2 -2
  152. package/worker/test/src/RTC/TestTransportCongestionControlServer.cpp +1 -1
  153. package/worker/test/src/RTC/TestTransportTuple.cpp +3 -2
  154. package/worker/test/src/Utils/TestCrypto.cpp +71 -2
  155. package/worker/test/src/Utils/TestTime.cpp +2 -2
@@ -637,11 +637,12 @@ SCENARIO("BWE ProbeController", "[bwe][probecontroller]")
637
637
 
638
638
  SECTION("while not filling the link a burst goes out every five seconds")
639
639
  {
640
- RTC::BWE::ProbeController probeController;
640
+ const RTC::BWE::ProbeController::ProbeControllerOptions options{ .enablePeriodicAlrProbing =
641
+ true };
641
642
 
642
- REQUIRE(probeController.OnNetworkAvailability(/*networkAvailable*/ true, nowUs).empty());
643
+ RTC::BWE::ProbeController probeController(options);
643
644
 
644
- probeController.EnablePeriodicAlrProbing(true);
645
+ REQUIRE(probeController.OnNetworkAvailability(/*networkAvailable*/ true, nowUs).empty());
645
646
 
646
647
  auto probes = probeController.SetBitrates(MinBitrate, StartBitrate, MaxBitrate, nowUs);
647
648
 
@@ -691,12 +692,14 @@ SCENARIO("BWE ProbeController", "[bwe][probecontroller]")
691
692
 
692
693
  SECTION("and starting over leaves nothing to probe until there are bitrates again")
693
694
  {
694
- RTC::BWE::ProbeController probeController;
695
+ const RTC::BWE::ProbeController::ProbeControllerOptions options{ .enablePeriodicAlrProbing =
696
+ true };
697
+
698
+ RTC::BWE::ProbeController probeController(options);
695
699
 
696
700
  REQUIRE(probeController.OnNetworkAvailability(/*networkAvailable*/ true, nowUs).empty());
697
701
 
698
702
  probeController.SetAlrStartTimeUs(nowUs);
699
- probeController.EnablePeriodicAlrProbing(true);
700
703
 
701
704
  auto probes = probeController.SetBitrates(MinBitrate, StartBitrate, MaxBitrate, nowUs);
702
705
 
@@ -724,9 +727,10 @@ SCENARIO("BWE ProbeController", "[bwe][probecontroller]")
724
727
 
725
728
  SECTION("nothing is probed while nothing can be sent")
726
729
  {
727
- RTC::BWE::ProbeController probeController;
730
+ const RTC::BWE::ProbeController::ProbeControllerOptions options{ .enablePeriodicAlrProbing =
731
+ true };
728
732
 
729
- probeController.EnablePeriodicAlrProbing(true);
733
+ RTC::BWE::ProbeController probeController(options);
730
734
 
731
735
  REQUIRE(probeController.OnNetworkAvailability(/*networkAvailable*/ false, nowUs).empty());
732
736
  REQUIRE(probeController.SetBitrates(MinBitrate, StartBitrate, MaxBitrate, nowUs).empty());
@@ -771,13 +775,15 @@ SCENARIO("BWE ProbeController", "[bwe][probecontroller]")
771
775
 
772
776
  SECTION("nor above twice what the application wants to send")
773
777
  {
774
- RTC::BWE::ProbeController probeController;
778
+ const RTC::BWE::ProbeController::ProbeControllerOptions options{ .enablePeriodicAlrProbing =
779
+ true };
780
+
781
+ RTC::BWE::ProbeController probeController(options);
775
782
 
776
783
  REQUIRE(probeController.OnNetworkAvailability(/*networkAvailable*/ true, nowUs).empty());
777
784
 
778
785
  auto probes = probeController.SetBitrates(MinBitrate, 10000000, 100000000, nowUs);
779
786
 
780
- probeController.EnablePeriodicAlrProbing(true);
781
787
  probeController.SetAlrStartTimeUs(nowUs);
782
788
 
783
789
  probes = probeController.SetEstimatedBitrate(
@@ -858,11 +864,12 @@ SCENARIO("BWE ProbeController", "[bwe][probecontroller]")
858
864
 
859
865
  SECTION("while loss is what holds the estimate back a burst barely goes above it")
860
866
  {
861
- RTC::BWE::ProbeController probeController;
867
+ const RTC::BWE::ProbeController::ProbeControllerOptions options{ .enablePeriodicAlrProbing =
868
+ true };
862
869
 
863
- REQUIRE(probeController.OnNetworkAvailability(/*networkAvailable*/ true, nowUs).empty());
870
+ RTC::BWE::ProbeController probeController(options);
864
871
 
865
- probeController.EnablePeriodicAlrProbing(true);
872
+ REQUIRE(probeController.OnNetworkAvailability(/*networkAvailable*/ true, nowUs).empty());
866
873
 
867
874
  auto probes = probeController.SetBitrates(MinBitrate, StartBitrate, MaxBitrate, nowUs);
868
875
 
@@ -969,15 +976,13 @@ SCENARIO("BWE ProbeController", "[bwe][probecontroller]")
969
976
  SECTION("and it bounds the periodic bursts as soon as there is one")
970
977
  {
971
978
  const RTC::BWE::ProbeController::ProbeControllerOptions options{
972
- .networkStateEstimateProbingIntervalUs = 5 * 1000 * 1000
979
+ .enablePeriodicAlrProbing = true, .networkStateEstimateProbingIntervalUs = 5 * 1000 * 1000
973
980
  };
974
981
 
975
982
  RTC::BWE::ProbeController probeController(options);
976
983
 
977
984
  REQUIRE(probeController.OnNetworkAvailability(/*networkAvailable*/ true, nowUs).empty());
978
985
 
979
- probeController.EnablePeriodicAlrProbing(true);
980
-
981
986
  auto probes = probeController.SetBitrates(MinBitrate, StartBitrate, MaxBitrate, nowUs);
982
987
 
983
988
  probes = probeController.SetEstimatedBitrate(
@@ -1034,14 +1039,15 @@ SCENARIO("BWE ProbeController", "[bwe][probecontroller]")
1034
1039
 
1035
1040
  SECTION("loss growing back while not filling the link is worth a burst")
1036
1041
  {
1037
- RTC::BWE::ProbeController probeController;
1042
+ const RTC::BWE::ProbeController::ProbeControllerOptions options{ .enablePeriodicAlrProbing =
1043
+ true };
1044
+
1045
+ RTC::BWE::ProbeController probeController(options);
1038
1046
 
1039
1047
  REQUIRE(probeController.OnNetworkAvailability(/*networkAvailable*/ true, nowUs).empty());
1040
1048
 
1041
1049
  auto probes = probeController.SetBitrates(MinBitrate, StartBitrate, MaxBitrate, nowUs);
1042
1050
 
1043
- probeController.EnablePeriodicAlrProbing(true);
1044
-
1045
1051
  probes = probeController.SetEstimatedBitrate(
1046
1052
  StartBitrate,
1047
1053
  RTC::BWE::ProbeController::BandwidthLimitedCause::LOSS_LIMITED_BWE_INCREASING,
@@ -1065,14 +1071,15 @@ SCENARIO("BWE ProbeController", "[bwe][probecontroller]")
1065
1071
 
1066
1072
  SECTION("but loss that isn't growing back is not")
1067
1073
  {
1068
- RTC::BWE::ProbeController probeController;
1074
+ const RTC::BWE::ProbeController::ProbeControllerOptions options{ .enablePeriodicAlrProbing =
1075
+ true };
1076
+
1077
+ RTC::BWE::ProbeController probeController(options);
1069
1078
 
1070
1079
  REQUIRE(probeController.OnNetworkAvailability(/*networkAvailable*/ true, nowUs).empty());
1071
1080
 
1072
1081
  auto probes = probeController.SetBitrates(MinBitrate, StartBitrate, MaxBitrate, nowUs);
1073
1082
 
1074
- probeController.EnablePeriodicAlrProbing(true);
1075
-
1076
1083
  probes = probeController.SetEstimatedBitrate(
1077
1084
  StartBitrate, RTC::BWE::ProbeController::BandwidthLimitedCause::LOSS_LIMITED_BWE, nowUs);
1078
1085
 
@@ -1093,14 +1100,15 @@ SCENARIO("BWE ProbeController", "[bwe][probecontroller]")
1093
1100
 
1094
1101
  SECTION("nor is it worth one while the link is being filled")
1095
1102
  {
1096
- RTC::BWE::ProbeController probeController;
1103
+ const RTC::BWE::ProbeController::ProbeControllerOptions options{ .enablePeriodicAlrProbing =
1104
+ true };
1105
+
1106
+ RTC::BWE::ProbeController probeController(options);
1097
1107
 
1098
1108
  REQUIRE(probeController.OnNetworkAvailability(/*networkAvailable*/ true, nowUs).empty());
1099
1109
 
1100
1110
  auto probes = probeController.SetBitrates(MinBitrate, StartBitrate, MaxBitrate, nowUs);
1101
1111
 
1102
- probeController.EnablePeriodicAlrProbing(true);
1103
-
1104
1112
  probes = probeController.SetEstimatedBitrate(
1105
1113
  StartBitrate,
1106
1114
  RTC::BWE::ProbeController::BandwidthLimitedCause::LOSS_LIMITED_BWE_INCREASING,
@@ -1429,15 +1437,13 @@ SCENARIO("BWE ProbeController", "[bwe][probecontroller]")
1429
1437
  SECTION("an estimate already close to the maximum is not worth a burst")
1430
1438
  {
1431
1439
  const RTC::BWE::ProbeController::ProbeControllerOptions options{
1432
- .skipIfEstimateLargerThanFractionOfMax = 0.9
1440
+ .enablePeriodicAlrProbing = true, .skipIfEstimateLargerThanFractionOfMax = 0.9
1433
1441
  };
1434
1442
 
1435
1443
  RTC::BWE::ProbeController probeController(options);
1436
1444
 
1437
1445
  REQUIRE(probeController.OnNetworkAvailability(/*networkAvailable*/ true, nowUs).empty());
1438
1446
 
1439
- probeController.EnablePeriodicAlrProbing(true);
1440
-
1441
1447
  auto probes = probeController.SetBitrates(MinBitrate, StartBitrate, MaxBitrate, nowUs);
1442
1448
 
1443
1449
  REQUIRE(!probes.empty());
@@ -1464,15 +1470,13 @@ SCENARIO("BWE ProbeController", "[bwe][probecontroller]")
1464
1470
  SECTION("and neither is one already close to what the application wants to send")
1465
1471
  {
1466
1472
  const RTC::BWE::ProbeController::ProbeControllerOptions options{
1467
- .skipIfEstimateLargerThanFractionOfMax = 1.0
1473
+ .enablePeriodicAlrProbing = true, .skipIfEstimateLargerThanFractionOfMax = 1.0
1468
1474
  };
1469
1475
 
1470
1476
  RTC::BWE::ProbeController probeController(options);
1471
1477
 
1472
1478
  REQUIRE(probeController.OnNetworkAvailability(/*networkAvailable*/ true, nowUs).empty());
1473
1479
 
1474
- probeController.EnablePeriodicAlrProbing(true);
1475
-
1476
1480
  auto probes = probeController.SetBitrates(MinBitrate, StartBitrate, MaxBitrate, nowUs);
1477
1481
 
1478
1482
  REQUIRE(!probes.empty());
@@ -1574,6 +1578,7 @@ SCENARIO("BWE ProbeController", "[bwe][probecontroller]")
1574
1578
  SECTION("a measured link capacity below the estimate doesn't bring the burst down")
1575
1579
  {
1576
1580
  const RTC::BWE::ProbeController::ProbeControllerOptions options{
1581
+ .enablePeriodicAlrProbing = true,
1577
1582
  .networkStateEstimateProbingIntervalUs = 5 * 1000 * 1000,
1578
1583
  .networkStateProbeDurationUs = 100 * 1000,
1579
1584
  .networkStateMinProbeDeltaUs = 20 * 1000
@@ -1583,8 +1588,6 @@ SCENARIO("BWE ProbeController", "[bwe][probecontroller]")
1583
1588
 
1584
1589
  REQUIRE(probeController.OnNetworkAvailability(/*networkAvailable*/ true, nowUs).empty());
1585
1590
 
1586
- probeController.EnablePeriodicAlrProbing(true);
1587
-
1588
1591
  auto probes = probeController.SetBitrates(MinBitrate, StartBitrate, MaxBitrate, nowUs);
1589
1592
 
1590
1593
  probes = probeController.SetEstimatedBitrate(
@@ -28,7 +28,7 @@ SCENARIO("BWE ProbePacketGenerator", "[bwe][probepacketgenerator]")
28
28
  class TestProbePacketGeneratorListener : public RTC::BWE::ProbePacketGenerator::Listener
29
29
  {
30
30
  public:
31
- bool OnProbePacketGeneratorSendRtpPacket(
31
+ void OnProbePacketGeneratorSendRtpPacket(
32
32
  RTC::BWE::ProbePacketGenerator* /*probePacketGenerator*/, RTC::RTP::Packet* packet) override
33
33
  {
34
34
  HandedPacket handedPacket;
@@ -49,14 +49,10 @@ SCENARIO("BWE ProbePacketGenerator", "[bwe][probepacketgenerator]")
49
49
  handedPacket.isPaddedTo4Bytes = packet->IsPaddedTo4Bytes();
50
50
 
51
51
  this->handedPackets.push_back(handedPacket);
52
-
53
- return this->handedPackets.size() < this->stopAfter;
54
52
  }
55
53
 
56
54
  public:
57
55
  std::vector<HandedPacket> handedPackets;
58
- // Packets after which the burst is given up on.
59
- size_t stopAfter{ std::numeric_limits<size_t>::max() };
60
56
  };
61
57
 
62
58
  // How far the sequence number moved between two packets.
@@ -105,7 +101,7 @@ SCENARIO("BWE ProbePacketGenerator", "[bwe][probepacketgenerator]")
105
101
  class WritingListener : public RTC::BWE::ProbePacketGenerator::Listener
106
102
  {
107
103
  public:
108
- bool OnProbePacketGeneratorSendRtpPacket(
104
+ void OnProbePacketGeneratorSendRtpPacket(
109
105
  RTC::BWE::ProbePacketGenerator* /*probePacketGenerator*/, RTC::RTP::Packet* packet) override
110
106
  {
111
107
  this->sentAtUs += 1000;
@@ -122,8 +118,6 @@ SCENARIO("BWE ProbePacketGenerator", "[bwe][probepacketgenerator]")
122
118
 
123
119
  REQUIRE(packet->ReadTransportWideCc01(readWideSeqNumber));
124
120
  REQUIRE(readWideSeqNumber == this->wideSeqNumber);
125
-
126
- return true;
127
121
  }
128
122
 
129
123
  public:
@@ -253,13 +247,4 @@ SCENARIO("BWE ProbePacketGenerator", "[bwe][probepacketgenerator]")
253
247
  REQUIRE(
254
248
  sequenceNumberDelta(otherListener.handedPackets.at(0), otherListener.handedPackets.at(1)) == 1);
255
249
  }
256
-
257
- SECTION("a packet that cannot be sent stops the ones behind it")
258
- {
259
- listener.stopAfter = 2;
260
-
261
- probePacketGenerator.GeneratePackets(50000);
262
-
263
- REQUIRE(listener.handedPackets.size() == 2);
264
- }
265
250
  }
@@ -24,20 +24,13 @@ SCENARIO("BWE ProbingScheduler", "[bwe][probingscheduler]")
24
24
  class TestProbingSchedulerListener : public RTC::BWE::ProbingScheduler::Listener
25
25
  {
26
26
  public:
27
- bool OnProbingSchedulerSendRtpPacket(
27
+ void OnProbingSchedulerSendRtpPacket(
28
28
  RTC::BWE::ProbingScheduler* /*probingScheduler*/,
29
29
  RTC::RTP::Packet* packet,
30
30
  const RTC::BWE::Types::ProbeCluster& probeCluster) override
31
31
  {
32
- if (!this->sendPackets)
33
- {
34
- return false;
35
- }
36
-
37
32
  this->sentLengths.push_back(packet->GetLength());
38
33
  this->sentClusterIds.push_back(probeCluster.id);
39
-
40
- return true;
41
34
  }
42
35
 
43
36
  size_t GetSentBytes() const
@@ -56,7 +49,6 @@ SCENARIO("BWE ProbingScheduler", "[bwe][probingscheduler]")
56
49
  std::vector<size_t> sentLengths;
57
50
  // The burst each of those packets was handed over as part of.
58
51
  std::vector<int64_t> sentClusterIds;
59
- bool sendPackets{ true };
60
52
  };
61
53
 
62
54
  TestProbingSchedulerListener listener;
@@ -212,22 +204,6 @@ SCENARIO("BWE ProbingScheduler", "[bwe][probingscheduler]")
212
204
  REQUIRE(expectedNextUs - (timer->GetExpiresAtMs() * 1000) < 1000);
213
205
  }
214
206
 
215
- SECTION("a listener that cannot send stops the burst")
216
- {
217
- RTC::BWE::ProbingScheduler probingScheduler(std::addressof(listener), std::addressof(shared));
218
-
219
- listener.sendPackets = false;
220
-
221
- probingScheduler.CreateProbeClusters({ makeClusterConfig(0, nowUs, 900000, 2 * 1000) });
222
-
223
- REQUIRE(emitNextShot());
224
- REQUIRE(listener.sentLengths.empty());
225
-
226
- // Nothing went out, so there is no reason to believe that trying again
227
- // would do any better.
228
- REQUIRE(!shared.GetTimer(TimerLabel)->IsActive());
229
- }
230
-
231
207
  SECTION("a burst asked for while another one is being emitted waits for it")
232
208
  {
233
209
  constexpr int64_t TestBitrate{ 900000 };
@@ -0,0 +1,346 @@
1
+ #include "common.hpp"
2
+ #include "RTC/BWE/ReceiverTransportCongestionController.hpp"
3
+ #include "RTC/RTCP/FeedbackPsRemb.hpp"
4
+ #include "RTC/RTP/HeaderExtensionIds.hpp"
5
+ #include "RTC/RTP/Packet.hpp"
6
+ #include "RTC/RtpDictionaries.hpp"
7
+ #include "Utils.hpp"
8
+ #include "test/include/RTC/RTP/rtpCommon.hpp"
9
+ #include "mocks/include/MockShared.hpp"
10
+ #include <catch2/catch_test_macros.hpp>
11
+ #include <string_view>
12
+ #include <vector>
13
+
14
+ SCENARIO("BWE ReceiverTransportCongestionController", "[bwe][receivertransportcongestioncontroller]")
15
+ {
16
+ class TestReceiverTransportCongestionControllerListener
17
+ : public RTC::BWE::ReceiverTransportCongestionController::Listener
18
+ {
19
+ public:
20
+ void OnReceiverTransportCongestionControllerSendRtcpPacket(
21
+ RTC::BWE::ReceiverTransportCongestionController* /*receiverTransportCongestionControl*/,
22
+ RTC::RTCP::Packet* packet) override
23
+ {
24
+ this->rtcpTypes.push_back(packet->GetType());
25
+
26
+ if (packet->GetType() == RTC::RTCP::Type::PSFB)
27
+ {
28
+ const auto* rembPacket = static_cast<RTC::RTCP::FeedbackPsRembPacket*>(packet);
29
+
30
+ this->rembBitrates.push_back(rembPacket->GetBitrate());
31
+ this->rembSsrcs.push_back(rembPacket->GetSsrcs());
32
+ }
33
+ }
34
+
35
+ public:
36
+ std::vector<RTC::RTCP::Type> rtcpTypes;
37
+ std::vector<int64_t> rembBitrates;
38
+ std::vector<std::vector<uint32_t>> rembSsrcs;
39
+ };
40
+
41
+ constexpr uint32_t Ssrc{ 1111 };
42
+ constexpr uint32_t Ssrc2{ 2222 };
43
+ constexpr uint8_t TransportWideCc01Id{ 5 };
44
+ constexpr uint8_t AbsSendTimeId{ 4 };
45
+ // Instant the scenarios below start at, which is irrelevant other than for
46
+ // being far from zero.
47
+ constexpr int64_t BaseTimeUs{ 1000 * 1000 };
48
+ constexpr size_t PayloadSize{ 1000 };
49
+ // Packets a burst is made of, which is what the estimation of the incoming link
50
+ // is drawn from.
51
+ constexpr int Probes{ 5 };
52
+ constexpr std::string_view FeedbackTimerLabel{ "transport-wide-cc-feedback-generator-send" };
53
+
54
+ int64_t nowUs{ BaseTimeUs };
55
+
56
+ mocks::MockShared shared(
57
+ [&nowUs]() -> int64_t
58
+ {
59
+ return nowUs;
60
+ });
61
+
62
+ // Builds a packet carrying the transport wide sequence number, which is what a
63
+ // sender that negotiated transport-cc emits.
64
+ //
65
+ // NOTE: Every scenario reuses `rtpCommon::FactoryBuffer`, so the returned packet
66
+ // is only valid until the next call.
67
+ const auto buildTransportCcPacket = [](uint16_t wideSeqNumber) -> std::unique_ptr<RTC::RTP::Packet>
68
+ {
69
+ std::unique_ptr<RTC::RTP::Packet> packet(
70
+ RTC::RTP::Packet::Factory(rtpCommon::FactoryBuffer, sizeof(rtpCommon::FactoryBuffer)));
71
+
72
+ REQUIRE(packet);
73
+
74
+ packet->SetSsrc(Ssrc);
75
+
76
+ const std::vector<RTC::RTP::Packet::Extension> extensions{
77
+ { RTC::RtpHeaderExtensionUri::Type::TRANSPORT_WIDE_CC_01,
78
+ TransportWideCc01Id, /*len*/ 2,
79
+ rtpCommon::DataBuffer }
80
+ };
81
+
82
+ packet->SetExtensions(RTC::RTP::Packet::ExtensionsType::OneByte, extensions);
83
+
84
+ RTC::RTP::HeaderExtensionIds headerExtensionIds;
85
+
86
+ headerExtensionIds.transportWideCc01 = TransportWideCc01Id;
87
+
88
+ packet->AssignExtensionIds(headerExtensionIds);
89
+ packet->SetPayloadLength(PayloadSize);
90
+
91
+ REQUIRE(packet->UpdateTransportWideCc01(wideSeqNumber));
92
+
93
+ return packet;
94
+ };
95
+
96
+ // Builds a packet carrying 'abs-send-time', which is what a sender that
97
+ // negotiated REMB emits.
98
+ const auto buildRembPacket =
99
+ [](int64_t sendTimeUs, uint32_t ssrc) -> std::unique_ptr<RTC::RTP::Packet>
100
+ {
101
+ std::unique_ptr<RTC::RTP::Packet> packet(
102
+ RTC::RTP::Packet::Factory(rtpCommon::FactoryBuffer, sizeof(rtpCommon::FactoryBuffer)));
103
+
104
+ REQUIRE(packet);
105
+
106
+ packet->SetSsrc(ssrc);
107
+
108
+ const std::vector<RTC::RTP::Packet::Extension> extensions{
109
+ { RTC::RtpHeaderExtensionUri::Type::ABS_SEND_TIME, AbsSendTimeId, /*len*/ 3, rtpCommon::DataBuffer }
110
+ };
111
+
112
+ packet->SetExtensions(RTC::RTP::Packet::ExtensionsType::OneByte, extensions);
113
+
114
+ RTC::RTP::HeaderExtensionIds headerExtensionIds;
115
+
116
+ headerExtensionIds.absSendTime = AbsSendTimeId;
117
+
118
+ packet->AssignExtensionIds(headerExtensionIds);
119
+ packet->SetPayloadLength(PayloadSize);
120
+
121
+ REQUIRE(packet->UpdateAbsSendTime(Utils::Time::TimeUsToAbsSendTime(sendTimeUs)));
122
+
123
+ return packet;
124
+ };
125
+
126
+ SECTION("with transport-cc the arrival times reach the listener and nothing is estimated")
127
+ {
128
+ TestReceiverTransportCongestionControllerListener listener;
129
+
130
+ RTC::BWE::ReceiverTransportCongestionController receiverTransportCongestionControl(
131
+ std::addressof(listener),
132
+ std::addressof(shared),
133
+ { .congestionControlType = RTC::BWE::Types::CongestionControlType::TRANSPORT_CC });
134
+
135
+ for (uint16_t wideSeqNumber{ 0 }; wideSeqNumber < 10; ++wideSeqNumber)
136
+ {
137
+ nowUs += 10 * 1000;
138
+
139
+ const auto packet = buildTransportCcPacket(wideSeqNumber);
140
+
141
+ receiverTransportCongestionControl.ReceiveRtpPacket(
142
+ nowUs, packet.get(), RTC::Media::Kind::VIDEO);
143
+ }
144
+
145
+ // Nothing goes out until the periodic timer of the feedback generator fires.
146
+ REQUIRE(listener.rtcpTypes.empty());
147
+
148
+ auto* timer = shared.GetTimer(FeedbackTimerLabel);
149
+
150
+ REQUIRE(timer);
151
+
152
+ nowUs += timer->GetRepeatMs() * 1000;
153
+
154
+ REQUIRE(timer->EvaluateHasExpired());
155
+
156
+ REQUIRE(listener.rtcpTypes.size() == 1);
157
+ REQUIRE(listener.rtcpTypes.at(0) == RTC::RTCP::Type::RTPFB);
158
+
159
+ // The estimating is the remote sender's job in this mode.
160
+ REQUIRE(receiverTransportCongestionControl.GetAvailableBitrate().has_value() == false);
161
+ }
162
+
163
+ SECTION("with REMB the estimation of the incoming link reaches the listener")
164
+ {
165
+ TestReceiverTransportCongestionControllerListener listener;
166
+
167
+ RTC::BWE::ReceiverTransportCongestionController receiverTransportCongestionControl(
168
+ std::addressof(listener),
169
+ std::addressof(shared),
170
+ { .congestionControlType = RTC::BWE::Types::CongestionControlType::REMB });
171
+
172
+ REQUIRE(receiverTransportCongestionControl.GetAvailableBitrate().has_value() == false);
173
+
174
+ // A burst of packets spaced evenly, which is what the estimation is drawn
175
+ // from at the beginning of a call.
176
+ for (int idx{ 0 }; idx < Probes; ++idx)
177
+ {
178
+ nowUs += 10 * 1000;
179
+
180
+ const auto packet = buildRembPacket(nowUs, Ssrc);
181
+
182
+ receiverTransportCongestionControl.ReceiveRtpPacket(
183
+ nowUs, packet.get(), RTC::Media::Kind::VIDEO);
184
+ }
185
+
186
+ REQUIRE(listener.rtcpTypes.size() == 1);
187
+ REQUIRE(listener.rtcpTypes.at(0) == RTC::RTCP::Type::PSFB);
188
+ REQUIRE(listener.rembBitrates.at(0) > 0);
189
+
190
+ // What went out is what is reported as available.
191
+ REQUIRE(receiverTransportCongestionControl.GetAvailableBitrate() == listener.rembBitrates.at(0));
192
+ }
193
+
194
+ SECTION("a stream that is removed stops being announced")
195
+ {
196
+ TestReceiverTransportCongestionControllerListener listener;
197
+
198
+ RTC::BWE::ReceiverTransportCongestionController receiverTransportCongestionControl(
199
+ std::addressof(listener),
200
+ std::addressof(shared),
201
+ { .congestionControlType = RTC::BWE::Types::CongestionControlType::REMB });
202
+
203
+ // A burst where two streams alternate, so that the estimation applies to both.
204
+ for (int idx{ 0 }; idx < Probes; ++idx)
205
+ {
206
+ nowUs += 10 * 1000;
207
+
208
+ const auto packet = buildRembPacket(nowUs, idx % 2 == 0 ? Ssrc : Ssrc2);
209
+
210
+ receiverTransportCongestionControl.ReceiveRtpPacket(
211
+ nowUs, packet.get(), RTC::Media::Kind::VIDEO);
212
+ }
213
+
214
+ REQUIRE(listener.rembSsrcs.size() == 1);
215
+ REQUIRE(listener.rembSsrcs.at(0).size() == 2);
216
+
217
+ receiverTransportCongestionControl.RemoveStream(Ssrc2);
218
+
219
+ // Long enough for the next packet to bring another estimation out, and far
220
+ // shorter than what it takes for a silent stream to be forgotten on its own.
221
+ nowUs += 250 * 1000;
222
+
223
+ const auto packet = buildRembPacket(nowUs, Ssrc);
224
+
225
+ receiverTransportCongestionControl.ReceiveRtpPacket(nowUs, packet.get(), RTC::Media::Kind::VIDEO);
226
+
227
+ REQUIRE(listener.rembSsrcs.size() == 2);
228
+ REQUIRE(listener.rembSsrcs.at(1) == std::vector<uint32_t>{ Ssrc });
229
+ }
230
+
231
+ SECTION("with REMB audio takes no part in the estimation")
232
+ {
233
+ TestReceiverTransportCongestionControllerListener listener;
234
+
235
+ RTC::BWE::ReceiverTransportCongestionController receiverTransportCongestionControl(
236
+ std::addressof(listener),
237
+ std::addressof(shared),
238
+ { .congestionControlType = RTC::BWE::Types::CongestionControlType::REMB });
239
+
240
+ // The very same burst that gives an estimation when it carries video.
241
+ for (int idx{ 0 }; idx < Probes; ++idx)
242
+ {
243
+ nowUs += 10 * 1000;
244
+
245
+ const auto packet = buildRembPacket(nowUs, Ssrc);
246
+
247
+ receiverTransportCongestionControl.ReceiveRtpPacket(
248
+ nowUs, packet.get(), RTC::Media::Kind::AUDIO);
249
+ }
250
+
251
+ REQUIRE(listener.rtcpTypes.empty());
252
+ REQUIRE(receiverTransportCongestionControl.GetAvailableBitrate().has_value() == false);
253
+ }
254
+
255
+ SECTION("with transport-cc audio is reported like video")
256
+ {
257
+ TestReceiverTransportCongestionControllerListener listener;
258
+
259
+ RTC::BWE::ReceiverTransportCongestionController receiverTransportCongestionControl(
260
+ std::addressof(listener),
261
+ std::addressof(shared),
262
+ { .congestionControlType = RTC::BWE::Types::CongestionControlType::TRANSPORT_CC });
263
+
264
+ for (uint16_t wideSeqNumber{ 0 }; wideSeqNumber < 10; ++wideSeqNumber)
265
+ {
266
+ nowUs += 10 * 1000;
267
+
268
+ const auto packet = buildTransportCcPacket(wideSeqNumber);
269
+
270
+ receiverTransportCongestionControl.ReceiveRtpPacket(
271
+ nowUs, packet.get(), RTC::Media::Kind::AUDIO);
272
+ }
273
+
274
+ auto* timer = shared.GetTimer(FeedbackTimerLabel);
275
+
276
+ REQUIRE(timer);
277
+
278
+ nowUs += timer->GetRepeatMs() * 1000;
279
+
280
+ REQUIRE(timer->EvaluateHasExpired());
281
+
282
+ REQUIRE(listener.rtcpTypes.size() == 1);
283
+ REQUIRE(listener.rtcpTypes.at(0) == RTC::RTCP::Type::RTPFB);
284
+ }
285
+
286
+ SECTION("the cap is announced even when transport-cc was negotiated")
287
+ {
288
+ constexpr int64_t MaxIncomingBitrate{ 500000 };
289
+
290
+ TestReceiverTransportCongestionControllerListener listener;
291
+
292
+ RTC::BWE::ReceiverTransportCongestionController receiverTransportCongestionControl(
293
+ std::addressof(listener),
294
+ std::addressof(shared),
295
+ { .congestionControlType = RTC::BWE::Types::CongestionControlType::TRANSPORT_CC });
296
+
297
+ receiverTransportCongestionControl.SetMaxIncomingBitrate(MaxIncomingBitrate);
298
+
299
+ nowUs += 10 * 1000;
300
+
301
+ const auto packet = buildTransportCcPacket(/*wideSeqNumber*/ 0);
302
+
303
+ receiverTransportCongestionControl.ReceiveRtpPacket(nowUs, packet.get(), RTC::Media::Kind::VIDEO);
304
+
305
+ // Nothing else can tell the remote sender to hold back, since in this mode it
306
+ // is the one estimating.
307
+ REQUIRE(listener.rembBitrates.size() == 1);
308
+ REQUIRE(listener.rembBitrates.at(0) == MaxIncomingBitrate);
309
+ }
310
+
311
+ SECTION("a cap of zero is no cap at all")
312
+ {
313
+ constexpr int64_t MaxIncomingBitrate{ 500000 };
314
+
315
+ TestReceiverTransportCongestionControllerListener listener;
316
+
317
+ RTC::BWE::ReceiverTransportCongestionController receiverTransportCongestionControl(
318
+ std::addressof(listener),
319
+ std::addressof(shared),
320
+ { .congestionControlType = RTC::BWE::Types::CongestionControlType::TRANSPORT_CC });
321
+
322
+ receiverTransportCongestionControl.SetMaxIncomingBitrate(MaxIncomingBitrate);
323
+
324
+ // The cap went out as soon as it was set.
325
+ REQUIRE(listener.rembBitrates.size() == 1);
326
+ REQUIRE(listener.rembBitrates.at(0) == MaxIncomingBitrate);
327
+
328
+ receiverTransportCongestionControl.SetMaxIncomingBitrate(0);
329
+
330
+ // A REMB of zero is how the remote sender is told that it may send whatever it
331
+ // wants again, and the first of them goes out without waiting.
332
+ REQUIRE(listener.rembBitrates.size() == 2);
333
+ REQUIRE(listener.rembBitrates.at(1) == 0);
334
+
335
+ // Losing that single REMB would leave the remote sender limited forever, so the
336
+ // rest of them ride on the incoming packets once the announcing interval is past.
337
+ nowUs += (1500 + 1) * 1000;
338
+
339
+ const auto packet = buildTransportCcPacket(/*wideSeqNumber*/ 0);
340
+
341
+ receiverTransportCongestionControl.ReceiveRtpPacket(nowUs, packet.get(), RTC::Media::Kind::VIDEO);
342
+
343
+ REQUIRE(listener.rembBitrates.size() == 3);
344
+ REQUIRE(listener.rembBitrates.back() == 0);
345
+ }
346
+ }
@@ -15,7 +15,7 @@ SCENARIO("BWE RembGenerator", "[bwe][rembgenerator]")
15
15
  class TestRembGeneratorListener : public RTC::BWE::RembGenerator::Listener
16
16
  {
17
17
  public:
18
- void OnRembGeneratorSendRemb(
18
+ void OnRembGeneratorSendPacket(
19
19
  RTC::BWE::RembGenerator* /*rembGenerator*/, RTC::RTCP::FeedbackPsRembPacket* packet) override
20
20
  {
21
21
  this->rembs.push_back(TestRemb{ .bitrate = packet->GetBitrate(), .ssrcs = packet->GetSsrcs() });