1db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org/*
2db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org *
4db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org *  Use of this source code is governed by a BSD-style license
5db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org *  that can be found in the LICENSE file in the root of the source
6db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org *  tree. An additional intellectual property rights grant can be found
7db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org *  in the file PATENTS.  All contributing project authors may
8db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org */
10db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
11db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org#include <algorithm>
12db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
13db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org#include "webrtc/modules/remote_bitrate_estimator/test/estimators/remb.h"
14db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
15db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org#include "testing/gtest/include/gtest/gtest.h"
16db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org#include "webrtc/base/common.h"
17db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
18468e62a97426a8d001e9187f3ca1d1e43f80b970Erik Språng#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
19db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h"
20ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/rtp_rtcp/include/receive_statistics.h"
21db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
22db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgnamespace webrtc {
23db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgnamespace testing {
24db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgnamespace bwe {
25db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
26db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgRembBweSender::RembBweSender(int kbps, BitrateObserver* observer, Clock* clock)
27db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    : bitrate_controller_(
28792f1a14e2b62382c5c6080d0b8fdc5c89d27bc6stefan@webrtc.org          BitrateController::CreateBitrateController(clock, observer)),
29db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org      feedback_observer_(bitrate_controller_->CreateRtcpBandwidthObserver()),
30db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org      clock_(clock) {
31db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  assert(kbps >= kMinBitrateKbps);
32db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  assert(kbps <= kMaxBitrateKbps);
33792f1a14e2b62382c5c6080d0b8fdc5c89d27bc6stefan@webrtc.org  bitrate_controller_->SetStartBitrate(1000 * kbps);
34792f1a14e2b62382c5c6080d0b8fdc5c89d27bc6stefan@webrtc.org  bitrate_controller_->SetMinMaxBitrate(1000 * kMinBitrateKbps,
35792f1a14e2b62382c5c6080d0b8fdc5c89d27bc6stefan@webrtc.org                                        1000 * kMaxBitrateKbps);
36db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
37db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
38db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgRembBweSender::~RembBweSender() {
39db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
40db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
41db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgvoid RembBweSender::GiveFeedback(const FeedbackPacket& feedback) {
42db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  const RembFeedback& remb_feedback =
43db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org      static_cast<const RembFeedback&>(feedback);
44db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  feedback_observer_->OnReceivedEstimatedBitrate(remb_feedback.estimated_bps());
45db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  ReportBlockList report_blocks;
46db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  report_blocks.push_back(remb_feedback.report_block());
47db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  feedback_observer_->OnReceivedRtcpReceiverReport(
48db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org      report_blocks, 0, clock_->TimeInMilliseconds());
49db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  bitrate_controller_->Process();
50db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
51db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
52db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgint64_t RembBweSender::TimeUntilNextProcess() {
53db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  return bitrate_controller_->TimeUntilNextProcess();
54db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
55db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
56db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgint RembBweSender::Process() {
57db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  return bitrate_controller_->Process();
58db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
59db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
60db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgint RembBweSender::GetFeedbackIntervalMs() const {
61db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  return 100;
62db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
63db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
64db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgRembReceiver::RembReceiver(int flow_id, bool plot)
65db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    : BweReceiver(flow_id),
66db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org      estimate_log_prefix_(),
67db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org      plot_estimate_(plot),
68db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org      clock_(0),
69db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org      recv_stats_(ReceiveStatistics::Create(&clock_)),
70db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org      latest_estimate_bps_(-1),
71468e62a97426a8d001e9187f3ca1d1e43f80b970Erik Språng      last_feedback_ms_(-1),
724fbd145dcefd23169a9b1612d5ca92dace8196d6stefan      estimator_(new RemoteBitrateEstimatorAbsSendTime(this, &clock_)) {
73db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  std::stringstream ss;
74db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  ss << "Estimate_" << flow_id_ << "#1";
75db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  estimate_log_prefix_ = ss.str();
76db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  // Default RTT in RemoteRateControl is 200 ms ; 50 ms is more realistic.
772328a94ec7ee545a26e8220c5ae157e1b3b5144fstefan  estimator_->OnRttUpdate(50, 50);
784fbd145dcefd23169a9b1612d5ca92dace8196d6stefan  estimator_->SetMinBitrate(kRemoteBitrateEstimatorMinBitrateBps);
79db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
80db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
81db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgRembReceiver::~RembReceiver() {
82db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
83db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
84db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgvoid RembReceiver::ReceivePacket(int64_t arrival_time_ms,
85db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org                                 const MediaPacket& media_packet) {
86db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  recv_stats_->IncomingPacket(media_packet.header(),
87db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org                              media_packet.payload_size(), false);
88db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
89db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  latest_estimate_bps_ = -1;
90db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
91db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  int64_t step_ms = std::max<int64_t>(estimator_->TimeUntilNextProcess(), 0);
92db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  while ((clock_.TimeInMilliseconds() + step_ms) < arrival_time_ms) {
93db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    clock_.AdvanceTimeMilliseconds(step_ms);
94db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    estimator_->Process();
95db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    step_ms = std::max<int64_t>(estimator_->TimeUntilNextProcess(), 0);
96db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  }
97db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  estimator_->IncomingPacket(arrival_time_ms, media_packet.payload_size(),
98ff4ea9310e981da6292fb044cff9eeefd986cf2bStefan Holmer                             media_packet.header(), true);
99db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  clock_.AdvanceTimeMilliseconds(arrival_time_ms - clock_.TimeInMilliseconds());
100db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  ASSERT_TRUE(arrival_time_ms == clock_.TimeInMilliseconds());
10177cabab51a2a362b589ba96ce81e605fbeca83e2Cesar Magalhaes
1029c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  // Log received packet information.
1039c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  BweReceiver::ReceivePacket(arrival_time_ms, media_packet);
104db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
105db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
106db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgFeedbackPacket* RembReceiver::GetFeedback(int64_t now_ms) {
107db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  BWE_TEST_LOGGING_CONTEXT("Remb");
108db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  uint32_t estimated_bps = 0;
109db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  RembFeedback* feedback = NULL;
110db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  if (LatestEstimate(&estimated_bps)) {
111db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    StatisticianMap statisticians = recv_stats_->GetActiveStatisticians();
112db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    RTCPReportBlock report_block;
113db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    if (!statisticians.empty()) {
114db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org      report_block = BuildReportBlock(statisticians.begin()->second);
115db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    }
116c81591d63f5e441bd26025a5e986bb2ebfd9fdfdCesar Magalhaes
117c81591d63f5e441bd26025a5e986bb2ebfd9fdfdCesar Magalhaes    feedback = new RembFeedback(flow_id_, now_ms * 1000, last_feedback_ms_,
118c81591d63f5e441bd26025a5e986bb2ebfd9fdfdCesar Magalhaes                                estimated_bps, report_block);
119c81591d63f5e441bd26025a5e986bb2ebfd9fdfdCesar Magalhaes    last_feedback_ms_ = now_ms;
120db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
121db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    double estimated_kbps = static_cast<double>(estimated_bps) / 1000.0;
122db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    RTC_UNUSED(estimated_kbps);
123db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    if (plot_estimate_) {
124dcbd3acbef881b0e6a5d459c6f6b7c7080eb1a20Stefan Holmer      BWE_TEST_LOGGING_PLOT(0, estimate_log_prefix_,
125dcbd3acbef881b0e6a5d459c6f6b7c7080eb1a20Stefan Holmer                            clock_.TimeInMilliseconds(), estimated_kbps);
126db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    }
127db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  }
128db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  return feedback;
129db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
130db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
131db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgvoid RembReceiver::OnReceiveBitrateChanged(
132db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    const std::vector<unsigned int>& ssrcs,
133db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    unsigned int bitrate) {
134db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
135db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
136db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgRTCPReportBlock RembReceiver::BuildReportBlock(
137db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    StreamStatistician* statistician) {
138db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  RTCPReportBlock report_block;
139db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  RtcpStatistics stats;
140db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  if (!statistician->GetStatistics(&stats, true))
141db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    return report_block;
142db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  report_block.fractionLost = stats.fraction_lost;
143db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  report_block.cumulativeLost = stats.cumulative_lost;
144db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  report_block.extendedHighSeqNum = stats.extended_max_sequence_number;
145db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  report_block.jitter = stats.jitter;
146db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  return report_block;
147db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
148db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
149db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgbool RembReceiver::LatestEstimate(uint32_t* estimate_bps) {
150db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  if (latest_estimate_bps_ < 0) {
151db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    std::vector<unsigned int> ssrcs;
152db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    unsigned int bps = 0;
153db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    if (!estimator_->LatestEstimate(&ssrcs, &bps)) {
154db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org      return false;
155db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    }
156db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    latest_estimate_bps_ = bps;
157db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  }
158db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  *estimate_bps = latest_estimate_bps_;
159db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  return true;
160db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
161db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
162db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}  // namespace bwe
163db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}  // namespace testing
164db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}  // namespace webrtc
165