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 "webrtc/modules/remote_bitrate_estimator/test/packet_receiver.h"
12 
13 #include <vector>
14 
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "webrtc/base/common.h"
17 #include "webrtc/modules/include/module_common_types.h"
18 #include "webrtc/modules/remote_bitrate_estimator/test/bwe.h"
19 #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h"
20 #include "webrtc/modules/rtp_rtcp/include/receive_statistics.h"
21 #include "webrtc/system_wrappers/include/clock.h"
22 
23 namespace webrtc {
24 namespace testing {
25 namespace bwe {
26 
PacketReceiver(PacketProcessorListener * listener,int flow_id,BandwidthEstimatorType bwe_type,bool plot_delay,bool plot_bwe,MetricRecorder * metric_recorder)27 PacketReceiver::PacketReceiver(PacketProcessorListener* listener,
28                                int flow_id,
29                                BandwidthEstimatorType bwe_type,
30                                bool plot_delay,
31                                bool plot_bwe,
32                                MetricRecorder* metric_recorder)
33     : PacketProcessor(listener, flow_id, kReceiver),
34       bwe_receiver_(CreateBweReceiver(bwe_type, flow_id, plot_bwe)),
35       metric_recorder_(metric_recorder),
36       plot_delay_(plot_delay),
37       last_delay_plot_ms_(0),
38       // #2 aligns the plot with the right axis.
39       delay_prefix_("Delay_ms#2"),
40       bwe_type_(bwe_type) {
41   if (metric_recorder_ != nullptr) {
42     // Setup the prefix std::strings used when logging.
43     std::vector<std::string> prefixes;
44 
45     // Metric recorder plots them in separated figures,
46     // alignment will take place with the #1 left axis.
47     prefixes.push_back("Throughput_kbps#1");
48     prefixes.push_back("Sending_Estimate_kbps#1");
49     prefixes.push_back("Delay_ms_#1");
50     prefixes.push_back("Packet_Loss_#1");
51     prefixes.push_back("Objective_function_#1");
52 
53     // Plot Total/PerFlow Available capacity together with throughputs.
54     prefixes.push_back("Throughput_kbps#1");  // Total Available.
55     prefixes.push_back("Throughput_kbps#1");  // Available per flow.
56 
57     bool plot_loss = plot_delay;  // Plot loss if delay is plotted.
58     metric_recorder_->SetPlotInformation(prefixes, plot_delay, plot_loss);
59   }
60 }
61 
PacketReceiver(PacketProcessorListener * listener,int flow_id,BandwidthEstimatorType bwe_type,bool plot_delay,bool plot_bwe)62 PacketReceiver::PacketReceiver(PacketProcessorListener* listener,
63                                int flow_id,
64                                BandwidthEstimatorType bwe_type,
65                                bool plot_delay,
66                                bool plot_bwe)
67     : PacketReceiver(listener,
68                      flow_id,
69                      bwe_type,
70                      plot_delay,
71                      plot_bwe,
72                      nullptr) {
73 }
74 
~PacketReceiver()75 PacketReceiver::~PacketReceiver() {
76 }
77 
RunFor(int64_t time_ms,Packets * in_out)78 void PacketReceiver::RunFor(int64_t time_ms, Packets* in_out) {
79   Packets feedback;
80   for (auto it = in_out->begin(); it != in_out->end();) {
81     // PacketReceivers are only associated with a single stream, and therefore
82     // should only process a single flow id.
83     // TODO(holmer): Break this out into a Demuxer which implements both
84     // PacketProcessorListener and PacketProcessor.
85     BWE_TEST_LOGGING_CONTEXT("Receiver");
86     if ((*it)->GetPacketType() == Packet::kMedia &&
87         (*it)->flow_id() == *flow_ids().begin()) {
88       BWE_TEST_LOGGING_CONTEXT(*flow_ids().begin());
89       const MediaPacket* media_packet = static_cast<const MediaPacket*>(*it);
90       // We're treating the send time (from previous filter) as the arrival
91       // time once packet reaches the estimator.
92       int64_t arrival_time_ms = media_packet->send_time_ms();
93       int64_t send_time_ms = media_packet->creation_time_ms();
94       delay_stats_.Push(arrival_time_ms - send_time_ms);
95 
96       if (metric_recorder_ != nullptr) {
97         metric_recorder_->UpdateTimeMs(arrival_time_ms);
98         UpdateMetrics(arrival_time_ms, send_time_ms,
99                       media_packet->payload_size());
100         metric_recorder_->PlotAllDynamics();
101       } else if (plot_delay_) {
102         PlotDelay(arrival_time_ms, send_time_ms);
103       }
104 
105       bwe_receiver_->ReceivePacket(arrival_time_ms, *media_packet);
106       FeedbackPacket* fb = bwe_receiver_->GetFeedback(arrival_time_ms);
107       if (fb)
108         feedback.push_back(fb);
109       delete media_packet;
110       it = in_out->erase(it);
111     } else {
112       ++it;
113     }
114   }
115   // Insert feedback packets to be sent back to the sender.
116   in_out->merge(feedback, DereferencingComparator<Packet>);
117 }
118 
UpdateMetrics(int64_t arrival_time_ms,int64_t send_time_ms,size_t payload_size)119 void PacketReceiver::UpdateMetrics(int64_t arrival_time_ms,
120                                    int64_t send_time_ms,
121                                    size_t payload_size) {
122   metric_recorder_->UpdateThroughput(bwe_receiver_->RecentKbps(), payload_size);
123   metric_recorder_->UpdateDelayMs(arrival_time_ms - send_time_ms);
124   metric_recorder_->UpdateLoss(bwe_receiver_->RecentPacketLossRatio());
125   metric_recorder_->UpdateObjective();
126 }
127 
PlotDelay(int64_t arrival_time_ms,int64_t send_time_ms)128 void PacketReceiver::PlotDelay(int64_t arrival_time_ms, int64_t send_time_ms) {
129   const int64_t kDelayPlotIntervalMs = 100;
130   if (arrival_time_ms >= last_delay_plot_ms_ + kDelayPlotIntervalMs) {
131     BWE_TEST_LOGGING_PLOT_WITH_NAME(0, delay_prefix_, arrival_time_ms,
132                                     arrival_time_ms - send_time_ms,
133                                     bwe_names[bwe_type_]);
134     last_delay_plot_ms_ = arrival_time_ms;
135   }
136 }
137 
GlobalPacketLoss()138 float PacketReceiver::GlobalPacketLoss() {
139   return bwe_receiver_->GlobalReceiverPacketLossRatio();
140 }
141 
GetDelayStats() const142 Stats<double> PacketReceiver::GetDelayStats() const {
143   return delay_stats_;
144 }
145 }  // namespace bwe
146 }  // namespace testing
147 }  // namespace webrtc
148