Home | History | Annotate | Download | only in estimators
      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