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
RembBweSender(int kbps,BitrateObserver * observer,Clock * clock)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
~RembBweSender()38 RembBweSender::~RembBweSender() {
39 }
40
GiveFeedback(const FeedbackPacket & feedback)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
TimeUntilNextProcess()52 int64_t RembBweSender::TimeUntilNextProcess() {
53 return bitrate_controller_->TimeUntilNextProcess();
54 }
55
Process()56 int RembBweSender::Process() {
57 return bitrate_controller_->Process();
58 }
59
GetFeedbackIntervalMs() const60 int RembBweSender::GetFeedbackIntervalMs() const {
61 return 100;
62 }
63
RembReceiver(int flow_id,bool plot)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
~RembReceiver()81 RembReceiver::~RembReceiver() {
82 }
83
ReceivePacket(int64_t arrival_time_ms,const MediaPacket & media_packet)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
GetFeedback(int64_t now_ms)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
OnReceiveBitrateChanged(const std::vector<unsigned int> & ssrcs,unsigned int bitrate)131 void RembReceiver::OnReceiveBitrateChanged(
132 const std::vector<unsigned int>& ssrcs,
133 unsigned int bitrate) {
134 }
135
BuildReportBlock(StreamStatistician * statistician)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
LatestEstimate(uint32_t * estimate_bps)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