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