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 "webrtc/modules/remote_bitrate_estimator/test/estimators/send_side.h"
12db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
134346d92578e5acbf3c40c89967c548e8f72e7543stefan@webrtc.org#include "webrtc/base/logging.h"
14468e62a97426a8d001e9187f3ca1d1e43f80b970Erik Språng#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
15bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h"
164346d92578e5acbf3c40c89967c548e8f72e7543stefan@webrtc.org
17db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgnamespace webrtc {
18db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgnamespace testing {
19db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgnamespace bwe {
20db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
210908d0dcf227b78c55ba4d59d7f5eadcc95af75bStefan Holmerconst int kFeedbackIntervalMs = 50;
220908d0dcf227b78c55ba4d59d7f5eadcc95af75bStefan Holmer
23db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgFullBweSender::FullBweSender(int kbps, BitrateObserver* observer, Clock* clock)
24db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    : bitrate_controller_(
25792f1a14e2b62382c5c6080d0b8fdc5c89d27bc6stefan@webrtc.org          BitrateController::CreateBitrateController(clock, observer)),
264fbd145dcefd23169a9b1612d5ca92dace8196d6stefan      rbe_(new RemoteBitrateEstimatorAbsSendTime(this, clock)),
27db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org      feedback_observer_(bitrate_controller_->CreateRtcpBandwidthObserver()),
284346d92578e5acbf3c40c89967c548e8f72e7543stefan@webrtc.org      clock_(clock),
29bbe876f0d30ec806c7c4a12629eb1f19ab45fb86stefan      send_time_history_(clock_, 10000),
30bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer      has_received_ack_(false),
31bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer      last_acked_seq_num_(0) {
32db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  assert(kbps >= kMinBitrateKbps);
33db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  assert(kbps <= kMaxBitrateKbps);
34792f1a14e2b62382c5c6080d0b8fdc5c89d27bc6stefan@webrtc.org  bitrate_controller_->SetStartBitrate(1000 * kbps);
35792f1a14e2b62382c5c6080d0b8fdc5c89d27bc6stefan@webrtc.org  bitrate_controller_->SetMinMaxBitrate(1000 * kMinBitrateKbps,
36792f1a14e2b62382c5c6080d0b8fdc5c89d27bc6stefan@webrtc.org                                        1000 * kMaxBitrateKbps);
374fbd145dcefd23169a9b1612d5ca92dace8196d6stefan  rbe_->SetMinBitrate(1000 * kMinBitrateKbps);
38db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
39db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
40db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgFullBweSender::~FullBweSender() {
41db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
42db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
43db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgint FullBweSender::GetFeedbackIntervalMs() const {
440908d0dcf227b78c55ba4d59d7f5eadcc95af75bStefan Holmer  return kFeedbackIntervalMs;
45db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
46db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
47db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgvoid FullBweSender::GiveFeedback(const FeedbackPacket& feedback) {
48db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  const SendSideBweFeedback& fb =
49db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org      static_cast<const SendSideBweFeedback&>(feedback);
50db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  if (fb.packet_feedback_vector().empty())
51db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    return;
524346d92578e5acbf3c40c89967c548e8f72e7543stefan@webrtc.org  std::vector<PacketInfo> packet_feedback_vector(fb.packet_feedback_vector());
53318673cf5a1b230d445a50fdc4869f4b8f99c85dsprang  for (PacketInfo& packet_info : packet_feedback_vector) {
54318673cf5a1b230d445a50fdc4869f4b8f99c85dsprang    if (!send_time_history_.GetInfo(&packet_info, true)) {
554346d92578e5acbf3c40c89967c548e8f72e7543stefan@webrtc.org      LOG(LS_WARNING) << "Ack arrived too late.";
564346d92578e5acbf3c40c89967c548e8f72e7543stefan@webrtc.org    }
574346d92578e5acbf3c40c89967c548e8f72e7543stefan@webrtc.org  }
58bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer
5953d0dc3f067d6440c37157db6060d2f2c9fa8446Stefan Holmer  int64_t rtt_ms =
6053d0dc3f067d6440c37157db6060d2f2c9fa8446Stefan Holmer      clock_->TimeInMilliseconds() - feedback.latest_send_time_ms();
612328a94ec7ee545a26e8220c5ae157e1b3b5144fstefan  rbe_->OnRttUpdate(rtt_ms, rtt_ms);
6253d0dc3f067d6440c37157db6060d2f2c9fa8446Stefan Holmer  BWE_TEST_LOGGING_PLOT(1, "RTT", clock_->TimeInMilliseconds(), rtt_ms);
6353d0dc3f067d6440c37157db6060d2f2c9fa8446Stefan Holmer
644346d92578e5acbf3c40c89967c548e8f72e7543stefan@webrtc.org  rbe_->IncomingPacketFeedbackVector(packet_feedback_vector);
65bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer  if (has_received_ack_) {
66bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer    int expected_packets = fb.packet_feedback_vector().back().sequence_number -
67bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer                           last_acked_seq_num_;
68bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer    // Assuming no reordering for now.
69bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer    if (expected_packets > 0) {
70bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer      int lost_packets = expected_packets -
71bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer                         static_cast<int>(fb.packet_feedback_vector().size());
72bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer      report_block_.fractionLost = (lost_packets << 8) / expected_packets;
73bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer      report_block_.cumulativeLost += lost_packets;
74bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer      report_block_.extendedHighSeqNum =
75bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer          packet_feedback_vector.back().sequence_number;
76bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer      ReportBlockList report_blocks;
77bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer      report_blocks.push_back(report_block_);
78bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer      feedback_observer_->OnReceivedRtcpReceiverReport(
7953d0dc3f067d6440c37157db6060d2f2c9fa8446Stefan Holmer          report_blocks, rtt_ms, clock_->TimeInMilliseconds());
80bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer    }
81bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer    bitrate_controller_->Process();
82bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer
83bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer    last_acked_seq_num_ = LatestSequenceNumber(
84bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer        packet_feedback_vector.back().sequence_number, last_acked_seq_num_);
85bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer  } else {
86bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer    last_acked_seq_num_ = packet_feedback_vector.back().sequence_number;
87bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer    has_received_ack_ = true;
88bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer  }
89db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
90db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
914346d92578e5acbf3c40c89967c548e8f72e7543stefan@webrtc.orgvoid FullBweSender::OnPacketsSent(const Packets& packets) {
924346d92578e5acbf3c40c89967c548e8f72e7543stefan@webrtc.org  for (Packet* packet : packets) {
934346d92578e5acbf3c40c89967c548e8f72e7543stefan@webrtc.org    if (packet->GetPacketType() == Packet::kMedia) {
944346d92578e5acbf3c40c89967c548e8f72e7543stefan@webrtc.org      MediaPacket* media_packet = static_cast<MediaPacket*>(packet);
95bbe876f0d30ec806c7c4a12629eb1f19ab45fb86stefan      send_time_history_.AddAndRemoveOld(media_packet->header().sequenceNumber,
96bbe876f0d30ec806c7c4a12629eb1f19ab45fb86stefan                                         media_packet->payload_size(),
97bbe876f0d30ec806c7c4a12629eb1f19ab45fb86stefan                                         packet->paced());
98bbe876f0d30ec806c7c4a12629eb1f19ab45fb86stefan      send_time_history_.OnSentPacket(media_packet->header().sequenceNumber,
99bbe876f0d30ec806c7c4a12629eb1f19ab45fb86stefan                                      media_packet->sender_timestamp_ms());
1004346d92578e5acbf3c40c89967c548e8f72e7543stefan@webrtc.org    }
1014346d92578e5acbf3c40c89967c548e8f72e7543stefan@webrtc.org  }
1024346d92578e5acbf3c40c89967c548e8f72e7543stefan@webrtc.org}
1034346d92578e5acbf3c40c89967c548e8f72e7543stefan@webrtc.org
104db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgvoid FullBweSender::OnReceiveBitrateChanged(
105db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    const std::vector<unsigned int>& ssrcs,
106db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    unsigned int bitrate) {
107db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  feedback_observer_->OnReceivedEstimatedBitrate(bitrate);
108db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
109db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
110db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgint64_t FullBweSender::TimeUntilNextProcess() {
111db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  return bitrate_controller_->TimeUntilNextProcess();
112db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
113db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
114db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgint FullBweSender::Process() {
115db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  rbe_->Process();
116db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  return bitrate_controller_->Process();
117db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
118db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
119db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgSendSideBweReceiver::SendSideBweReceiver(int flow_id)
120db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    : BweReceiver(flow_id), last_feedback_ms_(0) {
121db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
122db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
123db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgSendSideBweReceiver::~SendSideBweReceiver() {
124db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
125db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
126db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgvoid SendSideBweReceiver::ReceivePacket(int64_t arrival_time_ms,
127db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org                                        const MediaPacket& media_packet) {
128db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  packet_feedback_vector_.push_back(PacketInfo(
129bbe876f0d30ec806c7c4a12629eb1f19ab45fb86stefan      -1, arrival_time_ms, media_packet.sender_timestamp_ms(),
130ff4ea9310e981da6292fb044cff9eeefd986cf2bStefan Holmer      media_packet.header().sequenceNumber, media_packet.payload_size(), true));
13177cabab51a2a362b589ba96ce81e605fbeca83e2Cesar Magalhaes
1329c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  // Log received packet information.
1339c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  BweReceiver::ReceivePacket(arrival_time_ms, media_packet);
134db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
135db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
136db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.orgFeedbackPacket* SendSideBweReceiver::GetFeedback(int64_t now_ms) {
1370908d0dcf227b78c55ba4d59d7f5eadcc95af75bStefan Holmer  if (now_ms - last_feedback_ms_ < kFeedbackIntervalMs)
138db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org    return NULL;
139db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  last_feedback_ms_ = now_ms;
14053d0dc3f067d6440c37157db6060d2f2c9fa8446Stefan Holmer  int64_t corrected_send_time_ms =
14153d0dc3f067d6440c37157db6060d2f2c9fa8446Stefan Holmer      packet_feedback_vector_.back().send_time_ms + now_ms -
14253d0dc3f067d6440c37157db6060d2f2c9fa8446Stefan Holmer      packet_feedback_vector_.back().arrival_time_ms;
143c81591d63f5e441bd26025a5e986bb2ebfd9fdfdCesar Magalhaes  FeedbackPacket* fb = new SendSideBweFeedback(
14453d0dc3f067d6440c37157db6060d2f2c9fa8446Stefan Holmer      flow_id_, now_ms * 1000, corrected_send_time_ms, packet_feedback_vector_);
145db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  packet_feedback_vector_.clear();
146db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org  return fb;
147db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}
148db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org
149db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}  // namespace bwe
150db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}  // namespace testing
151db8e605c16539df84b01ad8f66730e3d61902edasprang@webrtc.org}  // namespace webrtc
152