{"id":458,"date":"2022-03-02T21:42:10","date_gmt":"2022-03-02T13:42:10","guid":{"rendered":"https:\/\/www.fanyamin.com\/wordpress\/?p=458"},"modified":"2022-03-27T21:29:14","modified_gmt":"2022-03-27T13:29:14","slug":"google-congestion-control-%e7%9a%84%e5%ae%9e%e7%8e%b0%e5%88%86%e6%9e%90%e4%b9%8b%e4%b8%80","status":"publish","type":"post","link":"https:\/\/www.fanyamin.com\/wordpress\/?p=458","title":{"rendered":"Google Congestion control \u7684\u5b9e\u73b0\u5206\u6790\u4e4b\u4e00"},"content":{"rendered":"<h1>Overview<\/h1>\n<p>\u5f71\u54cd\u56e0\u7d20\u6709 Packet loss, RTT \u548c OWDV(One Way Delay Varion)<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.fanyamin.com\/wordpress\/wp-content\/uploads\/2022\/03\/image-1648384747695.png\" alt=\"\" \/><\/p>\n<ul>\n<li>\n<p>\u57fa\u4e8e\u4e22\u5305\u7684\u63a7\u5236\u5668\uff1a\u4ee5\u4e22\u5305\u7387\uff0c RTT \u548c REMB \u6d88\u606f\u6765\u4f30\u7b97\u4e00\u4e2a\u76ee\u6807\u53d1\u9001\u7801\u7387<\/p>\n<\/li>\n<li>\n<p>\u57fa\u4e8e\u5ef6\u8fdf\u7684\u63a7\u5236\u5668\uff1a\u4ee5\u5305\u7684\u5230\u8fbe\u4fe1\u606f\uff0c\u6216\u8005\u5728\u63a5\u6536\u65b9\uff0c\u6216\u8005\u5728\u53d1\u9001\u65b9\u63a5\u6536\u53cd\u9988\uff0c\u4f30\u7b97\u4e00\u4e2a\u6700\u5927\u7684\u7801\u7387\uff0c\u7136\u540e\u4f20\u9001\u7ed9\u57fa\u4e8e\u4e22\u5305\u7684\u63a7\u5236\u5668<\/p>\n<\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"https:\/\/www.fanyamin.com\/wordpress\/wp-content\/uploads\/2022\/03\/image-1648384561901.png\" alt=\"\" \/><\/p>\n<p>\u57fa\u4e8e\u4e22\u5305\u7684\u4f30\u7b97\u662f\u4fdd\u5e95\u7684\uff0c\u4e22\u5305\u7387\u5927\u4e8e 10% \u5c31\u5f80\u4e0b\u964d\u7801\u7387\uff0c\u5c0f\u4e8e 2% \u5c31\u5f80\u4e0a\u5347\u7801\u7387<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.fanyamin.com\/wordpress\/wp-content\/uploads\/2022\/03\/image-1648384679041.png\" alt=\"\" \/><\/p>\n<p>\u57fa\u4e8e\u5ef6\u8fdf\u7684\u63a7\u5236\u5668\u4e00\u5f00\u59cb\u7528\u7684\u662f Kalman filter, \u540e\u6765\u6539\u4e3a Trendline filter , \u4fbf\u4e8e\u9884\u6d4b\u7f51\u7edc\u53d8\u5316\u7684\u8d8b\u52bf<\/p>\n<p>Trendline filter \u7684\u8f93\u5165\u53c2\u6570\u6709<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.fanyamin.com\/wordpress\/wp-content\/uploads\/2022\/03\/image-1648385422918.png\" alt=\"\" \/><\/p>\n<h1>Main interface<\/h1>\n<table>\n<thead>\n<tr>\n<th>method<\/th>\n<th>parameter<\/th>\n<th>description<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>OnNetworkAvailability<\/td>\n<td>NetworkAvailability<\/td>\n<td>\u5f53\u7f51\u7edc\u8fde\u63a5\u6709\u6548\u6216\u65e0\u6548\u65f6<\/td>\n<\/tr>\n<tr>\n<td>OnNetworkRouteChange<\/td>\n<td>NetworkRouteChange<\/td>\n<td>\u5f53\u7f51\u7edc\u5730\u5740\u66f4\u6539\u65f6<\/td>\n<\/tr>\n<tr>\n<td>OnProcessInterval<\/td>\n<td>ProcessInterval<\/td>\n<td>\u5b9a\u65f6\u56de\u8c03\uff0c\u4ee5\u68c0\u67e5\u7f51\u7edc<\/td>\n<\/tr>\n<tr>\n<td>OnRemoteBitrateReport<\/td>\n<td>RemoteBitrateReport<\/td>\n<td>\u5f53\u6536\u5230 REMB RTCP \u6d88\u606f\u65f6\u56de\u8c03<\/td>\n<\/tr>\n<tr>\n<td>OnRoundTripTimeUpdate<\/td>\n<td>RoundTripTimeUpdate<\/td>\n<td>\u5f53 RTT \u66f4\u6539\u65f6\u56de\u8c03\uff08\u53ef\u901a\u8fc7 RTCP RR\uff09<\/td>\n<\/tr>\n<tr>\n<td>OnSentPacket<\/td>\n<td>SentPacket<\/td>\n<td>\u5f53\u53d1\u51fa\u4e00\u4e2a RTP \u5305\u65f6<\/td>\n<\/tr>\n<tr>\n<td>OnReceivedPacket<\/td>\n<td>ReceivedPacket<\/td>\n<td>\u5f53\u6536\u5230\u4e00\u4e2a RTP \u5305\u65f6<\/td>\n<\/tr>\n<tr>\n<td>OnStreamsConfig<\/td>\n<td>StreamsConfig<\/td>\n<td>\u5f53\u6709\u5a92\u4f53\u6d41\u76f8\u5173\u7684\u914d\u7f6e\u66f4\u65b0\u65f6<\/td>\n<\/tr>\n<tr>\n<td>OnTargetRateConstraints<\/td>\n<td>TargetRateConstraints<\/td>\n<td>\u5f53\u76ee\u6807\u901f\u7387\u7ea6\u675f\u66f4\u6539\u65f6<\/td>\n<\/tr>\n<tr>\n<td>OnTransportLossReport<\/td>\n<td><\/td>\n<td>\u5f53\u6536\u5230 TransportLossReport \u65f6<\/td>\n<\/tr>\n<tr>\n<td>OnTransportPacketsFeedback<\/td>\n<td>TransportPacketsFeedback<\/td>\n<td>\u5f53\u6536\u5230 TransportPacketsFeedback \u65f6<\/td>\n<\/tr>\n<tr>\n<td>OnNetworkStateEstimate<\/td>\n<td>NetworkStateEstimate<\/td>\n<td>\u5f53\u7f51\u7edc\u72b6\u6001\u4f30\u8ba1\u66f4\u65b0\u65f6\uff0c\u8fd8\u5728\u5f00\u53d1\u4e2d<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<pre><code class=\"language-cpp\">\n\/\/ NetworkControllerInterface is implemented by network controllers. A network\n\/\/ controller is a class that uses information about network state and traffic\n\/\/ to estimate network parameters such as round trip time and bandwidth. Network\n\/\/ controllers does not guarantee thread safety, the interface must be used in a\n\/\/ non-concurrent fashion.\n    class NetworkControllerInterface {\n    public:\n      virtual ~NetworkControllerInterface() = default;\n\n      \/\/ Called when network availabilty changes.  -- \u5f53\u7f51\u7edc\u6709\u6548\u6216\u65e0\u6548\u65f6\n      ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnNetworkAvailability(NetworkAvailability) = 0;\n      \/\/ Called when the receiving or sending endpoint changes address.  -- \u5f53\u7f51\u7edc\u5730\u5740\u66f4\u6539\u65f6\n      ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnNetworkRouteChange(NetworkRouteChange) = 0;\n      \/\/ Called periodically with a periodicy as specified by\n      \/\/ NetworkControllerFactoryInterface::GetProcessInterval.  -- \u5b9a\u65f6\u56de\u8c03\uff0c\u4ee5\u68c0\u67e5\u7f51\u7edc\n      ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnProcessInterval( ProcessInterval) = 0;\n      \/\/ Called when remotely calculated bitrate is received.    -- \u5f53\u6536\u5230 REMB RTCP \u6d88\u606f\u65f6\u56de\u8c03\n      ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnRemoteBitrateReport(RemoteBitrateReport) = 0;\n      \/\/ Called round trip time has been calculated by protocol specific mechanisms.  -- \u5f53 RTT \u66f4\u6539\u65f6\u56de\u8c03\uff08\u53ef\u901a\u8fc7 RTCP RR\uff09\n      ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnRoundTripTimeUpdate(RoundTripTimeUpdate) = 0;\n      \/\/ Called when a packet is sent on the network.  -- \u5f53\u53d1\u51fa\u4e00\u4e2a RTP \u5305\u65f6\n      ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnSentPacket(SentPacket) = 0;\n      \/\/ Called when a packet is received from the remote client. -- \u5f53\u6536\u5230\u4e00\u4e2a RTP \u5305\u65f6\n      ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnReceivedPacket(ReceivedPacket) = 0;\n      \/\/ Called when the stream specific configuration has been updated.  -- \u5f53\u6709\u6d41\u76f8\u5173\u7684\u914d\u7f6e\u66f4\u65b0\u65f6\n      ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnStreamsConfig(StreamsConfig) = 0;\n      \/\/ Called when target transfer rate constraints has been changed.  -- \u5f53\u76ee\u6807\u901f\u7387\u7ea6\u675f\u66f4\u6539\u65f6\n      ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnTargetRateConstraints(TargetRateConstraints) = 0;\n      \/\/ Called when a protocol specific calculation of packet loss has been made.  -- \u5f53\u6536\u5230 TransportLossReport \u65f6\n      ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnTransportLossReport(TransportLossReport) = 0;\n      \/\/ Called with per packet feedback regarding receive time.  -- \u5f53\u6536\u5230 TransportPacketsFeedback \u65f6\n      ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnTransportPacketsFeedback(TransportPacketsFeedback) = 0;\n      \/\/ Called with network state estimate updates. -- \u5f53\u7f51\u7edc\u72b6\u6001\u4f30\u8ba1\u66f4\u65b0\u65f6\uff0c\u8fd8\u5728\u5f00\u53d1\u4e2d\n      ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnNetworkStateEstimate(NetworkStateEstimate) = 0;\n    };<\/code><\/pre>\n<h2>Main Flow<\/h2>\n<h3>Bandwidth Probe<\/h3>\n<ul>\n<li>class ProbeController<\/li>\n<li>class ProbeBitrateEstimator <\/li>\n<\/ul>\n<pre><code class=\"language-flow\">s=&gt;start: start\ne=&gt;end: end\nOnNetworkAvailability1=&gt;operation: GoogCcNetworkController::OnNetworkAvailability\nOnNetworkAvailability2=&gt;operation: ProbeController::OnNetworkAvailability\nis_available=&gt;condition: is network available\nInitiateExponentialProbing=&gt;operation: ProbeController::InitiateExponentialProbing\nInitiateProbing=&gt;operation: ProbeController::InitiateProbing: 900k, 1.8m\n\ns-&gt;OnNetworkAvailability1-&gt;OnNetworkAvailability2-&gt;is_available\nis_available(yes)-&gt;InitiateExponentialProbing-&gt;InitiateProbing-&gt;e\nis_available(no)-&gt;e\n<\/code><\/pre>\n<h2>GoogCcNetworkController \u662f\u6838\u5fc3\u7c7b<\/h2>\n<pre><code>class NetworkControllerTestFixture {\n public:\n  NetworkControllerTestFixture() : factory_() {}\n\n  std::unique_ptr&lt;NetworkControllerInterface&gt; CreateController() {\n    NetworkControllerConfig config = InitialConfig();\n    std::unique_ptr&lt;NetworkControllerInterface&gt; controller =\n        factory_.Create(config);\n    return controller;\n  }\n\n private:\n  NetworkControllerConfig InitialConfig(\n      int starting_bandwidth_kbps = kInitialBitrateKbps,\n      int min_data_rate_kbps = 0,\n      int max_data_rate_kbps = 5 * kInitialBitrateKbps) {\n    NetworkControllerConfig config;\n    config.constraints.at_time = Timestamp::Millis(0);\n    config.constraints.min_data_rate =\n        DataRate::KilobitsPerSec(min_data_rate_kbps);\n    config.constraints.max_data_rate =\n        DataRate::KilobitsPerSec(max_data_rate_kbps);\n    config.constraints.starting_rate =\n        DataRate::KilobitsPerSec(starting_bandwidth_kbps);\n    config.event_log = &amp;event_log_;\n    return config;\n  }\n\n  NiceMock&lt;MockRtcEventLog&gt; event_log_;\n  GoogCcNetworkControllerFactory factory_;\n};\n\nTEST(GoogCcNetworkControllerTest, InitializeTargetRateOnFirstProcessInterval) {\n  NetworkControllerTestFixture fixture;\n  std::unique_ptr&lt;NetworkControllerInterface&gt; controller =\n      fixture.CreateController();\n\n  NetworkControlUpdate update =\n      controller-&gt;OnProcessInterval({.at_time = Timestamp::Millis(123456)});\n\n  EXPECT_EQ(update.target_rate-&gt;target_rate, kInitialBitrate);\n  EXPECT_EQ(update.pacer_config-&gt;data_rate(),\n            kInitialBitrate * kDefaultPacingRate);\n  EXPECT_EQ(update.probe_cluster_configs[0].target_data_rate,\n            kInitialBitrate * 3);\n  EXPECT_EQ(update.probe_cluster_configs[1].target_data_rate,\n            kInitialBitrate * 5);\n}<\/code><\/pre>\n<p>run the uni test case<\/p>\n<pre><code>\n.\/out\/Default\/modules_unittests --gtest_filter=GoogCcNetworkControllerTest.InitializeTargetRateOnFirstProcessInterval\n(field_trial.cc:140): Setting field trial string:\nNote: Google Test filter = GoogCcNetworkControllerTest.InitializeTargetRateOnFirstProcessInterval\n[==========] Running 1 test from 1 test suite.\n[----------] Global test environment set-up.\n[----------] 1 test from GoogCcNetworkControllerTest\n[ RUN      ] GoogCcNetworkControllerTest.InitializeTargetRateOnFirstProcessInterval\n(alr_experiment.cc:79): Using ALR experiment settings: pacing factor: 1, max pacer queue length: 2875, ALR bandwidth usage percent: 80, ALR start budget level percent: 40, ALR end budget level percent: -60, ALR experiment group ID: 3\n(trendline_estimator.cc:185): Using Trendline filter for delay change estimation with settings sort:false,cap:false,beginning_packets:7,end_packets:7,cap_uncertainty:0,window_size:20 and no network state predictor\n(trendline_estimator.cc:185): Using Trendline filter for delay change estimation with settings sort:false,cap:false,beginning_packets:7,end_packets:7,cap_uncertainty:0,window_size:20 and no network state predictor\n(aimd_rate_control.cc:112): Using aimd rate control with back off factor 0.85\n(delay_based_bwe.cc:88): Initialized DelayBasedBwe with separate audio overuse detectionenabled:false,packet_threshold:10,time_threshold:1 s and alr limited backoff disabled\n(delay_based_bwe.cc:301): BWE Setting start bitrate to: 60 kbps\nPLOT    1   fraction_loss_%:0@- 123.456000  0.000000\nPLOT    1   rtt_ms:0@-  123.456000  0.000000\nPLOT    1   Target_bitrate_kbps:0@- 123.456000  60.000000\n[       OK ] GoogCcNetworkControllerTest.InitializeTargetRateOnFirstProcessInterval (1 ms)\n[----------] 1 test from GoogCcNetworkControllerTest (1 ms total)\n\n[----------] Global test environment tear-down\n[==========] 1 test from 1 test suite ran. (2 ms total)\n[  PASSED  ] 1 test.<\/code><\/pre>\n<h2>RTCP message \u7531 TransportFeedbackAdapter \u89e3\u6790<\/h2>\n<pre><code class=\"language-cpp\">absl::optional&lt;TransportPacketsFeedback&gt; TransportFeedbackAdapter::ProcessTransportFeedback(\n    const rtcp::TransportFeedback&amp; feedback,\n    Timestamp feedback_receive_time) {\n  if (feedback.GetPacketStatusCount() == 0) {\n    RTC_LOG(LS_INFO) &lt;&lt; &quot;Empty transport feedback packet received.&quot;;\n    return absl::nullopt;\n  }\n\n  TransportPacketsFeedback msg;\n  msg.feedback_time = feedback_receive_time;\n\n  msg.prior_in_flight = in_flight_.GetOutstandingData(network_route_);\n  msg.packet_feedbacks =\n      ProcessTransportFeedbackInner(feedback, feedback_receive_time);\n  if (msg.packet_feedbacks.empty())\n    return absl::nullopt;\n\n  auto it = history_.find(last_ack_seq_num_);\n  if (it != history_.end()) {\n    msg.first_unacked_send_time = it-&gt;second.sent.send_time;\n  }\n  msg.data_in_flight = in_flight_.GetOutstandingData(network_route_);\n\n  return msg;\n}\n<\/code><\/pre>\n<h2>\u5c06 RTCP \u6d88\u606f\u8f6c\u5316\u4e3a TransportPacketsFeedback<\/h2>\n<pre><code class=\"language-cpp\">struct TransportPacketsFeedback {\n  TransportPacketsFeedback();\n  TransportPacketsFeedback(const TransportPacketsFeedback&amp; other);\n  ~TransportPacketsFeedback();\n\n  Timestamp feedback_time = Timestamp::PlusInfinity();\n  Timestamp first_unacked_send_time = Timestamp::PlusInfinity();\n  DataSize data_in_flight = DataSize::Zero();\n  DataSize prior_in_flight = DataSize::Zero();\n  std::vector&lt;PacketResult&gt; packet_feedbacks;\n\n  \/\/ Arrival times for messages without send time information.\n  std::vector&lt;Timestamp&gt; sendless_arrival_times;\n\n  std::vector&lt;PacketResult&gt; ReceivedWithSendInfo() const;\n  std::vector&lt;PacketResult&gt; LostWithSendInfo() const;\n  std::vector&lt;PacketResult&gt; PacketsWithFeedback() const;\n  std::vector&lt;PacketResult&gt; SortedByReceiveTime() const;\n};\n<\/code><\/pre>\n<p>\u53ef\u4ee5\u901a\u8fc7\u8fd9\u4e2a\u5355\u5143\u6d4b\u8bd5\u6765\u7406\u89e3\u8fd9\u4e2a\u7ed3\u6784\u548c\u6d41\u7a0b<\/p>\n<p>.\/out\/Default\/modules_unittests --gtest_filter=&quot;GoogCcNetworkControllerTest.*&quot;<\/p>\n<p>.\/out\/Default\/modules_unittests --gtest_filter=GoogCcNetworkControllerTest.UpdatesDelayBasedEstimate<\/p>\n<p>.\/out\/Default\/modules_unittests --gtest_filter=TransportFeedbackAdapterTest.AdaptsFeedbackAndPopulatesSendTimes<\/p>\n<pre><code class=\"language-cpp\">\nclass TransportFeedbackAdapterTest : public ::testing::Test {\n public:\n  TransportFeedbackAdapterTest() : clock_(0) {}\n\n  virtual ~TransportFeedbackAdapterTest() {}\n\n  virtual void SetUp() {\n    adapter_.reset(new TransportFeedbackAdapter(&amp;clock_));\n  }\n\n  virtual void TearDown() { adapter_.reset(); }\n\n protected:\n  void OnReceivedEstimatedBitrate(uint32_t bitrate) {}\n\n  void OnReceivedRtcpReceiverReport(const ReportBlockList&amp; report_blocks,\n                                    int64_t rtt,\n                                    int64_t now_ms) {}\n\n  void OnSentPacket(const PacketFeedback&amp; packet_feedback) {\n    adapter_-&gt;AddPacket(kSsrc, packet_feedback.sequence_number,\n                        packet_feedback.payload_size,\n                        packet_feedback.pacing_info);\n    adapter_-&gt;OnSentPacket(packet_feedback.sequence_number,\n                           packet_feedback.send_time_ms);\n  }\n\n  static constexpr uint32_t kSsrc = 8492;\n\n  SimulatedClock clock_;\n  std::unique_ptr&lt;TransportFeedbackAdapter&gt; adapter_;\n};<\/code><\/pre>\n<h1>Unit test<\/h1>\n<pre><code> .\/modules_unittests --gtest_filter=&quot;GoogCc*&quot; --gtest_output=&quot;xml:goog-cc-ut-report.xml&quot;\ngtest2html.py --input=.\/goog-cc-ut-report.xml --output=goog-cc-ut-report.md<\/code><\/pre>\n<h2>Test suite:  GoogCcNetworkControllerTest<\/h2>\n<ul>\n<li>tests=6, failures=0, errors=0, disabled=0, time=0.076<\/li>\n<\/ul>\n<table>\n<thead>\n<tr>\n<th>#<\/th>\n<th>suite<\/th>\n<th>case<\/th>\n<th>time<\/th>\n<th>result<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>1<\/td>\n<td>GoogCcNetworkControllerTest<\/td>\n<td>InitializeTargetRateOnFirstProcessInterval<\/td>\n<td>0.016<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td>GoogCcNetworkControllerTest<\/td>\n<td>ReactsToChangedNetworkConditions<\/td>\n<td>0<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>3<\/td>\n<td>GoogCcNetworkControllerTest<\/td>\n<td>OnNetworkRouteChanged<\/td>\n<td>0<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>4<\/td>\n<td>GoogCcNetworkControllerTest<\/td>\n<td>ProbeOnRouteChange<\/td>\n<td>0<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>5<\/td>\n<td>GoogCcNetworkControllerTest<\/td>\n<td>UpdatesDelayBasedEstimate<\/td>\n<td>0.054<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>6<\/td>\n<td>GoogCcNetworkControllerTest<\/td>\n<td>PaceAtMaxOfLowerLinkCapacityAndBwe<\/td>\n<td>0<\/td>\n<td>pass<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Test suite:  GoogCcScenario<\/h2>\n<ul>\n<li>tests=20, failures=0, errors=0, disabled=0, time=22.666<\/li>\n<\/ul>\n<table>\n<thead>\n<tr>\n<th>#<\/th>\n<th>suite<\/th>\n<th>case<\/th>\n<th>time<\/th>\n<th>result<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>7<\/td>\n<td>GoogCcScenario<\/td>\n<td>CongestionWindowPushbackOnNetworkDelay<\/td>\n<td>0.509<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>8<\/td>\n<td>GoogCcScenario<\/td>\n<td>CongestionWindowPushbackDropFrameOnNetworkDelay<\/td>\n<td>0.432<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>9<\/td>\n<td>GoogCcScenario<\/td>\n<td>PaddingRateLimitedByCongestionWindowInTrial<\/td>\n<td>0.366<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>10<\/td>\n<td>GoogCcScenario<\/td>\n<td>LimitsToFloorIfRttIsHighInTrial<\/td>\n<td>0.255<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>11<\/td>\n<td>GoogCcScenario<\/td>\n<td>UpdatesTargetRateBasedOnLinkCapacity<\/td>\n<td>2.233<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>12<\/td>\n<td>GoogCcScenario<\/td>\n<td>StableEstimateDoesNotVaryInSteadyState<\/td>\n<td>1.559<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>13<\/td>\n<td>GoogCcScenario<\/td>\n<td>LossBasedControlUpdatesTargetRateBasedOnLinkCapacity<\/td>\n<td>2.23<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>14<\/td>\n<td>GoogCcScenario<\/td>\n<td>LossBasedControlDoesModestBackoffToHighLoss<\/td>\n<td>3.106<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>15<\/td>\n<td>GoogCcScenario<\/td>\n<td>LossBasedRecoversFasterAfterCrossInducedLoss<\/td>\n<td>5.93<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>16<\/td>\n<td>GoogCcScenario<\/td>\n<td>LossBasedEstimatorCapsRateAtModerateLoss<\/td>\n<td>1.211<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>17<\/td>\n<td>GoogCcScenario<\/td>\n<td>MaintainsLowRateInSafeResetTrial<\/td>\n<td>0.016<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>18<\/td>\n<td>GoogCcScenario<\/td>\n<td>CutsHighRateInSafeResetTrial<\/td>\n<td>0.015<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>19<\/td>\n<td>GoogCcScenario<\/td>\n<td>DetectsHighRateInSafeResetTrial<\/td>\n<td>0.079<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>20<\/td>\n<td>GoogCcScenario<\/td>\n<td>TargetRateReducedOnPacingBufferBuildupInTrial<\/td>\n<td>0.169<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>21<\/td>\n<td>GoogCcScenario<\/td>\n<td>NoBandwidthTogglingInLossControlTrial<\/td>\n<td>0.082<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>22<\/td>\n<td>GoogCcScenario<\/td>\n<td>NoRttBackoffCollapseWhenVideoStops<\/td>\n<td>0.071<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>23<\/td>\n<td>GoogCcScenario<\/td>\n<td>NoCrashOnVeryLateFeedback<\/td>\n<td>2.252<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>24<\/td>\n<td>GoogCcScenario<\/td>\n<td>IsFairToTCP<\/td>\n<td>0.289<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>25<\/td>\n<td>GoogCcScenario<\/td>\n<td>FastRampupOnRembCapLifted<\/td>\n<td>1.077<\/td>\n<td>pass<\/td>\n<\/tr>\n<tr>\n<td>26<\/td>\n<td>GoogCcScenario<\/td>\n<td>SlowRampupOnRembCapLiftedWithFieldTrial<\/td>\n<td>0.775<\/td>\n<td>pass<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n","protected":false},"excerpt":{"rendered":"<p>Overview \u5f71\u54cd\u56e0\u7d20\u6709 Packet loss, RTT \u548c OWDV(One Way Delay Varion) \u57fa\u4e8e\u4e22\u5305\u7684\u63a7\u5236\u5668\uff1a\u4ee5\u4e22\u5305\u7387\uff0c RTT \u548c REMB \u6d88\u606f\u6765\u4f30\u7b97\u4e00\u4e2a\u76ee\u6807\u53d1\u9001\u7801\u7387 \u57fa\u4e8e\u5ef6\u8fdf\u7684\u63a7\u5236\u5668\uff1a\u4ee5\u5305\u7684\u5230\u8fbe\u4fe1\u606f\uff0c\u6216\u8005\u5728\u63a5\u6536\u65b9\uff0c\u6216\u8005\u5728\u53d1\u9001\u65b9\u63a5\u6536\u53cd\u9988\uff0c\u4f30\u7b97\u4e00\u4e2a\u6700\u5927\u7684\u7801\u7387\uff0c\u7136\u540e\u4f20\u9001\u7ed9\u57fa\u4e8e\u4e22\u5305\u7684\u63a7\u5236\u5668 \u57fa\u4e8e\u4e22\u5305\u7684\u4f30\u7b97\u662f\u4fdd\u5e95\u7684\uff0c\u4e22\u5305\u7387\u5927\u4e8e 10% \u5c31\u5f80\u4e0b\u964d\u7801\u7387\uff0c\u5c0f\u4e8e 2% \u5c31\u5f80\u4e0a\u5347\u7801\u7387 \u57fa\u4e8e\u5ef6\u8fdf\u7684\u63a7\u5236\u5668\u4e00\u5f00\u59cb\u7528\u7684\u662f Kalman filter, \u540e\u6765\u6539\u4e3a Trendline filter , \u4fbf\u4e8e\u9884\u6d4b\u7f51\u7edc\u53d8\u5316\u7684\u8d8b\u52bf Trendline filter \u7684\u8f93\u5165\u53c2\u6570\u6709 Main interface method parameter description OnNetworkAvailability NetworkAvailability \u5f53\u7f51\u7edc\u8fde\u63a5\u6709\u6548\u6216\u65e0\u6548\u65f6 OnNetworkRouteChange NetworkRouteChange \u5f53\u7f51\u7edc\u5730\u5740\u66f4\u6539\u65f6 OnProcessInterval ProcessInterval \u5b9a\u65f6\u56de\u8c03\uff0c\u4ee5\u68c0\u67e5\u7f51\u7edc OnRemoteBitrateReport RemoteBitrateReport \u5f53\u6536\u5230 REMB RTCP \u6d88\u606f\u65f6\u56de\u8c03 OnRoundTripTimeUpdate RoundTripTimeUpdate \u5f53 [&hellip;] <a class=\"read-more\" href=\"https:\/\/www.fanyamin.com\/wordpress\/?p=458\" title=\"Permanent Link to: Google Congestion control \u7684\u5b9e\u73b0\u5206\u6790\u4e4b\u4e00\">&rarr;Read&nbsp;more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15,4],"tags":[],"class_list":["post-458","post","type-post","status-publish","format-standard","hentry","category-webrtc","category-4"],"_links":{"self":[{"href":"https:\/\/www.fanyamin.com\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/458"}],"collection":[{"href":"https:\/\/www.fanyamin.com\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.fanyamin.com\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.fanyamin.com\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.fanyamin.com\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=458"}],"version-history":[{"count":21,"href":"https:\/\/www.fanyamin.com\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/458\/revisions"}],"predecessor-version":[{"id":671,"href":"https:\/\/www.fanyamin.com\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/458\/revisions\/671"}],"wp:attachment":[{"href":"https:\/\/www.fanyamin.com\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=458"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.fanyamin.com\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=458"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.fanyamin.com\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=458"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}