1 /* 2 * Copyright (c) 2015 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 #include <algorithm> 12 13 #include "webrtc/modules/remote_bitrate_estimator/test/estimators/remb.h" 14 15 #include "testing/gtest/include/gtest/gtest.h" 16 #include "webrtc/base/common.h" 17 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" 18 #include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h" 19 #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h" 20 #include "webrtc/modules/rtp_rtcp/include/receive_statistics.h" 21 22 namespace webrtc { 23 namespace testing { 24 namespace bwe { 25 26 RembBweSender::RembBweSender(int kbps, BitrateObserver* observer, Clock* clock) 27 : bitrate_controller_( 28 BitrateController::CreateBitrateController(clock, observer)), 29 feedback_observer_(bitrate_controller_->CreateRtcpBandwidthObserver()), 30 clock_(clock) { 31 assert(kbps >= kMinBitrateKbps); 32 assert(kbps <= kMaxBitrateKbps); 33 bitrate_controller_->SetStartBitrate(1000 * kbps); 34 bitrate_controller_->SetMinMaxBitrate(1000 * kMinBitrateKbps, 35 1000 * kMaxBitrateKbps); 36 } 37 38 RembBweSender::~RembBweSender() { 39 } 40 41 void RembBweSender::GiveFeedback(const FeedbackPacket& feedback) { 42 const RembFeedback& remb_feedback = 43 static_cast<const RembFeedback&>(feedback); 44 feedback_observer_->OnReceivedEstimatedBitrate(remb_feedback.estimated_bps()); 45 ReportBlockList report_blocks; 46 report_blocks.push_back(remb_feedback.report_block()); 47 feedback_observer_->OnReceivedRtcpReceiverReport( 48 report_blocks, 0, clock_->TimeInMilliseconds()); 49 bitrate_controller_->Process(); 50 } 51 52 int64_t RembBweSender::TimeUntilNextProcess() { 53 return bitrate_controller_->TimeUntilNextProcess(); 54 } 55 56 int RembBweSender::Process() { 57 return bitrate_controller_->Process(); 58 } 59 60 int RembBweSender::GetFeedbackIntervalMs() const { 61 return 100; 62 } 63 64 RembReceiver::RembReceiver(int flow_id, bool plot) 65 : BweReceiver(flow_id), 66 estimate_log_prefix_(), 67 plot_estimate_(plot), 68 clock_(0), 69 recv_stats_(ReceiveStatistics::Create(&clock_)), 70 latest_estimate_bps_(-1), 71 last_feedback_ms_(-1), 72 estimator_(new RemoteBitrateEstimatorAbsSendTime(this, &clock_)) { 73 std::stringstream ss; 74 ss << "Estimate_" << flow_id_ << "#1"; 75 estimate_log_prefix_ = ss.str(); 76 // Default RTT in RemoteRateControl is 200 ms ; 50 ms is more realistic. 77 estimator_->OnRttUpdate(50, 50); 78 estimator_->SetMinBitrate(kRemoteBitrateEstimatorMinBitrateBps); 79 } 80 81 RembReceiver::~RembReceiver() { 82 } 83 84 void RembReceiver::ReceivePacket(int64_t arrival_time_ms, 85 const MediaPacket& media_packet) { 86 recv_stats_->IncomingPacket(media_packet.header(), 87 media_packet.payload_size(), false); 88 89 latest_estimate_bps_ = -1; 90 91 int64_t step_ms = std::max<int64_t>(estimator_->TimeUntilNextProcess(), 0); 92 while ((clock_.TimeInMilliseconds() + step_ms) < arrival_time_ms) { 93 clock_.AdvanceTimeMilliseconds(step_ms); 94 estimator_->Process(); 95 step_ms = std::max<int64_t>(estimator_->TimeUntilNextProcess(), 0); 96 } 97 estimator_->IncomingPacket(arrival_time_ms, media_packet.payload_size(), 98 media_packet.header(), true); 99 clock_.AdvanceTimeMilliseconds(arrival_time_ms - clock_.TimeInMilliseconds()); 100 ASSERT_TRUE(arrival_time_ms == clock_.TimeInMilliseconds()); 101 102 // Log received packet information. 103 BweReceiver::ReceivePacket(arrival_time_ms, media_packet); 104 } 105 106 FeedbackPacket* RembReceiver::GetFeedback(int64_t now_ms) { 107 BWE_TEST_LOGGING_CONTEXT("Remb"); 108 uint32_t estimated_bps = 0; 109 RembFeedback* feedback = NULL; 110 if (LatestEstimate(&estimated_bps)) { 111 StatisticianMap statisticians = recv_stats_->GetActiveStatisticians(); 112 RTCPReportBlock report_block; 113 if (!statisticians.empty()) { 114 report_block = BuildReportBlock(statisticians.begin()->second); 115 } 116 117 feedback = new RembFeedback(flow_id_, now_ms * 1000, last_feedback_ms_, 118 estimated_bps, report_block); 119 last_feedback_ms_ = now_ms; 120 121 double estimated_kbps = static_cast<double>(estimated_bps) / 1000.0; 122 RTC_UNUSED(estimated_kbps); 123 if (plot_estimate_) { 124 BWE_TEST_LOGGING_PLOT(0, estimate_log_prefix_, 125 clock_.TimeInMilliseconds(), estimated_kbps); 126 } 127 } 128 return feedback; 129 } 130 131 void RembReceiver::OnReceiveBitrateChanged( 132 const std::vector<unsigned int>& ssrcs, 133 unsigned int bitrate) { 134 } 135 136 RTCPReportBlock RembReceiver::BuildReportBlock( 137 StreamStatistician* statistician) { 138 RTCPReportBlock report_block; 139 RtcpStatistics stats; 140 if (!statistician->GetStatistics(&stats, true)) 141 return report_block; 142 report_block.fractionLost = stats.fraction_lost; 143 report_block.cumulativeLost = stats.cumulative_lost; 144 report_block.extendedHighSeqNum = stats.extended_max_sequence_number; 145 report_block.jitter = stats.jitter; 146 return report_block; 147 } 148 149 bool RembReceiver::LatestEstimate(uint32_t* estimate_bps) { 150 if (latest_estimate_bps_ < 0) { 151 std::vector<unsigned int> ssrcs; 152 unsigned int bps = 0; 153 if (!estimator_->LatestEstimate(&ssrcs, &bps)) { 154 return false; 155 } 156 latest_estimate_bps_ = bps; 157 } 158 *estimate_bps = latest_estimate_bps_; 159 return true; 160 } 161 162 } // namespace bwe 163 } // namespace testing 164 } // namespace webrtc 165