Add support for multiple report blocks. Use a weighted average of fraction loss for bandwidth estimation. TEST=trybots and vie_auto_test --automated BUG=1811 R=mflodman@webrtc.org Review URL: https://webrtc-codereview.appspot.com/2198004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@4762 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/bitrate_controller/bitrate_controller_unittest.cc b/webrtc/modules/bitrate_controller/bitrate_controller_unittest.cc index fcf419e..7abe71b 100644 --- a/webrtc/modules/bitrate_controller/bitrate_controller_unittest.cc +++ b/webrtc/modules/bitrate_controller/bitrate_controller_unittest.cc
@@ -20,6 +20,21 @@ using webrtc::BitrateObserver; using webrtc::BitrateController; +uint8_t WeightedLoss(int num_packets1, uint8_t fraction_loss1, + int num_packets2, uint8_t fraction_loss2) { + int weighted_sum = num_packets1 * fraction_loss1 + + num_packets2 * fraction_loss2; + int total_num_packets = num_packets1 + num_packets2; + return (weighted_sum + total_num_packets / 2) / total_num_packets; +} + +webrtc::RTCPReportBlock CreateReportBlock( + uint32_t remote_ssrc, uint32_t source_ssrc, + uint8_t fraction_lost, uint32_t extended_high_sequence_number) { + return webrtc::RTCPReportBlock(remote_ssrc, source_ssrc, fraction_lost, 0, + extended_high_sequence_number, 0, 0, 0); +} + class TestBitrateObserver: public BitrateObserver { public: TestBitrateObserver() @@ -73,33 +88,49 @@ bandwidth_observer_->OnReceivedEstimatedBitrate(400000); // Test start bitrate. - bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 1, 1); + webrtc::ReportBlockList report_blocks; + report_blocks.push_back(CreateReportBlock(1, 2, 0, 1)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1); EXPECT_EQ(0u, bitrate_observer.last_bitrate_); EXPECT_EQ(0, bitrate_observer.last_fraction_loss_); EXPECT_EQ(0u, bitrate_observer.last_rtt_); // Test bitrate increase 8% per second. - bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 21, 1001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 21)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1001); EXPECT_EQ(217000u, bitrate_observer.last_bitrate_); EXPECT_EQ(0, bitrate_observer.last_fraction_loss_); EXPECT_EQ(50u, bitrate_observer.last_rtt_); - bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 41, 2001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 41)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 2001); EXPECT_EQ(235360u, bitrate_observer.last_bitrate_); - bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 61, 3001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 61)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 3001); EXPECT_EQ(255189u, bitrate_observer.last_bitrate_); - bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 801, 4001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 801)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 4001); EXPECT_EQ(276604u, bitrate_observer.last_bitrate_); - bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 101, 5001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 101)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 5001); EXPECT_EQ(299732u, bitrate_observer.last_bitrate_); - bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 121, 6001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 121)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 6001); EXPECT_EQ(300000u, bitrate_observer.last_bitrate_); // Max cap. - bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 141, 7001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 141)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 7001); EXPECT_EQ(300000u, bitrate_observer.last_bitrate_); // Max cap. // Test that a low REMB trigger immediately. @@ -124,44 +155,73 @@ bandwidth_observer_->OnReceivedEstimatedBitrate(400000); // Test start bitrate. - bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 1, 1); - second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 100, 1, 1); + webrtc::ReportBlockList report_blocks; + report_blocks.push_back(CreateReportBlock(1, 2, 0, 1)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1); + second_bandwidth_observer->OnReceivedRtcpReceiverReport( + report_blocks, 100, 1); EXPECT_EQ(0u, bitrate_observer.last_bitrate_); EXPECT_EQ(0, bitrate_observer.last_fraction_loss_); EXPECT_EQ(0u, bitrate_observer.last_rtt_); // Test bitrate increase 8% per second. - bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 21, 501); - second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 100, 21, 1001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 21)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 501); + second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 100, + 1001); EXPECT_EQ(217000u, bitrate_observer.last_bitrate_); EXPECT_EQ(0, bitrate_observer.last_fraction_loss_); EXPECT_EQ(100u, bitrate_observer.last_rtt_); // Extra report should not change estimate. - second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 100, 31, 1501); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 31)); + second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 100, + 1501); EXPECT_EQ(217000u, bitrate_observer.last_bitrate_); - bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 41, 2001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 41)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 2001); EXPECT_EQ(235360u, bitrate_observer.last_bitrate_); // Second report should not change estimate. - second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 100, 41, 2001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 41)); + second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 100, + 2001); EXPECT_EQ(235360u, bitrate_observer.last_bitrate_); // Reports from only one bandwidth observer is ok. - second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 50, 61, 3001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 61)); + second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 50, + 3001); EXPECT_EQ(255189u, bitrate_observer.last_bitrate_); - second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 50, 81, 4001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 81)); + second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 50, + 4001); EXPECT_EQ(276604u, bitrate_observer.last_bitrate_); - second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 50, 101, 5001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 101)); + second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 50, + 5001); EXPECT_EQ(299732u, bitrate_observer.last_bitrate_); - second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 50, 121, 6001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 121)); + second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 50, + 6001); EXPECT_EQ(300000u, bitrate_observer.last_bitrate_); // Max cap. - second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 50, 141, 7001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 141)); + second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 50, + 7001); EXPECT_EQ(300000u, bitrate_observer.last_bitrate_); // Max cap. // Test that a low REMB trigger immediately. @@ -177,6 +237,78 @@ delete second_bandwidth_observer; } +TEST_F(BitrateControllerTest, OneBitrateObserverMultipleReportBlocks) { + TestBitrateObserver bitrate_observer; + uint32_t sequence_number[2] = {0, 0xFF00}; + const uint32_t kStartBitrate = 200000; + const uint32_t kMinBitrate = 100000; + const uint32_t kMaxBitrate = 300000; + controller_->SetBitrateObserver(&bitrate_observer, kStartBitrate, kMinBitrate, + kMaxBitrate); + + // Receive a high REMB, test bitrate increase. + bandwidth_observer_->OnReceivedEstimatedBitrate(400000); + + webrtc::ReportBlockList report_blocks; + int64_t time_ms = 1001; + uint32_t last_bitrate = 0; + // Ramp up to max bitrate. + for (int i = 0; i < 6; ++i) { + report_blocks.push_back(CreateReportBlock(1, 2, 0, sequence_number[0])); + report_blocks.push_back(CreateReportBlock(1, 3, 0, sequence_number[1])); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, + time_ms); + EXPECT_GT(bitrate_observer.last_bitrate_, last_bitrate); + EXPECT_EQ(0, bitrate_observer.last_fraction_loss_); + EXPECT_EQ(50u, bitrate_observer.last_rtt_); + last_bitrate = bitrate_observer.last_bitrate_; + time_ms += 1000; + sequence_number[0] += 20; + sequence_number[1] += 1; + report_blocks.clear(); + } + + EXPECT_EQ(kMaxBitrate, bitrate_observer.last_bitrate_); + + // Packet loss on the first stream. Verify that bitrate decreases. + report_blocks.push_back(CreateReportBlock(1, 2, 50, sequence_number[0])); + report_blocks.push_back(CreateReportBlock(1, 3, 0, sequence_number[1])); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms); + EXPECT_LT(bitrate_observer.last_bitrate_, last_bitrate); + EXPECT_EQ(WeightedLoss(20, 50, 1, 0), bitrate_observer.last_fraction_loss_); + EXPECT_EQ(50u, bitrate_observer.last_rtt_); + last_bitrate = bitrate_observer.last_bitrate_; + sequence_number[0] += 20; + sequence_number[1] += 20; + time_ms += 1000; + report_blocks.clear(); + + // Packet loss on the second stream. Verify that bitrate decreases. + report_blocks.push_back(CreateReportBlock(1, 2, 0, sequence_number[0])); + report_blocks.push_back(CreateReportBlock(1, 3, 75, sequence_number[1])); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms); + EXPECT_LT(bitrate_observer.last_bitrate_, last_bitrate); + EXPECT_EQ(WeightedLoss(20, 0, 20, 75), bitrate_observer.last_fraction_loss_); + EXPECT_EQ(50u, bitrate_observer.last_rtt_); + last_bitrate = bitrate_observer.last_bitrate_; + sequence_number[0] += 20; + sequence_number[1] += 1; + time_ms += 1000; + report_blocks.clear(); + + // All packets lost on stream with few packets, no back-off. + report_blocks.push_back(CreateReportBlock(1, 2, 1, sequence_number[0])); + report_blocks.push_back(CreateReportBlock(1, 3, 255, sequence_number[1])); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms); + EXPECT_EQ(bitrate_observer.last_bitrate_, last_bitrate); + EXPECT_EQ(WeightedLoss(20, 1, 1, 255), bitrate_observer.last_fraction_loss_); + EXPECT_EQ(50u, bitrate_observer.last_rtt_); + last_bitrate = bitrate_observer.last_bitrate_; + sequence_number[0] += 20; + sequence_number[1] += 1; + report_blocks.clear(); +} + TEST_F(BitrateControllerTest, TwoBitrateObserversOneRtcpObserver) { TestBitrateObserver bitrate_observer_1; TestBitrateObserver bitrate_observer_2; @@ -187,10 +319,14 @@ bandwidth_observer_->OnReceivedEstimatedBitrate(400000); // Test too low start bitrate, hence lower than sum of min. - bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 1, 1); + webrtc::ReportBlockList report_blocks; + report_blocks.push_back(CreateReportBlock(1, 2, 0, 1)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1); // Test bitrate increase 8% per second, distributed equally. - bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 21, 1001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 21)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1001); EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_); EXPECT_EQ(0, bitrate_observer_1.last_fraction_loss_); EXPECT_EQ(50u, bitrate_observer_1.last_rtt_); @@ -199,47 +335,67 @@ EXPECT_EQ(0, bitrate_observer_2.last_fraction_loss_); EXPECT_EQ(50u, bitrate_observer_2.last_rtt_); - bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 41, 2001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 41)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 2001); EXPECT_EQ(112500u, bitrate_observer_1.last_bitrate_); EXPECT_EQ(212500u, bitrate_observer_2.last_bitrate_); - bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 61, 3001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 61)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 3001); EXPECT_EQ(126000u, bitrate_observer_1.last_bitrate_); EXPECT_EQ(226000u, bitrate_observer_2.last_bitrate_); - bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 81, 4001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 81)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 4001); EXPECT_EQ(140580u, bitrate_observer_1.last_bitrate_); EXPECT_EQ(240580u, bitrate_observer_2.last_bitrate_); // Check that the bitrate sum honor our REMB. - bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 101, 5001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 101)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 5001); EXPECT_EQ(150000u, bitrate_observer_1.last_bitrate_); EXPECT_EQ(250000u, bitrate_observer_2.last_bitrate_); // Remove REMB cap, higher than sum of max. bandwidth_observer_->OnReceivedEstimatedBitrate(700000); - bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 121, 6001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 121)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 6001); EXPECT_EQ(166500u, bitrate_observer_1.last_bitrate_); EXPECT_EQ(266500u, bitrate_observer_2.last_bitrate_); - bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 141, 7001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 141)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 7001); EXPECT_EQ(184320u, bitrate_observer_1.last_bitrate_); EXPECT_EQ(284320u, bitrate_observer_2.last_bitrate_); - bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 161, 8001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 161)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 8001); EXPECT_EQ(207130u, bitrate_observer_1.last_bitrate_); EXPECT_EQ(300000u, bitrate_observer_2.last_bitrate_); // Max cap. - bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 181, 9001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 181)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 9001); EXPECT_EQ(248700u, bitrate_observer_1.last_bitrate_); EXPECT_EQ(300000u, bitrate_observer_2.last_bitrate_); - bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 201, 10001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 201)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 10001); EXPECT_EQ(293596u, bitrate_observer_1.last_bitrate_); EXPECT_EQ(300000u, bitrate_observer_2.last_bitrate_); - bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 221, 11001); + report_blocks.clear(); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 221)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 11001); EXPECT_EQ(300000u, bitrate_observer_1.last_bitrate_); // Max cap. EXPECT_EQ(300000u, bitrate_observer_2.last_bitrate_);