OLD | NEW |
| (Empty) |
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 <limits> | |
12 #include <memory> | |
13 #include <vector> | |
14 | |
15 #include "webrtc/test/gmock.h" | |
16 #include "webrtc/test/gtest.h" | |
17 | |
18 #include "webrtc/base/checks.h" | |
19 #include "webrtc/modules/bitrate_controller/include/mock/mock_bitrate_controller
.h" | |
20 #include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitra
te_estimator.h" | |
21 #include "webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.h" | |
22 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" | |
23 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" | |
24 #include "webrtc/system_wrappers/include/clock.h" | |
25 | |
26 using ::testing::_; | |
27 using ::testing::Invoke; | |
28 | |
29 namespace webrtc { | |
30 namespace test { | |
31 | |
32 class TransportFeedbackAdapterTest : public ::testing::Test { | |
33 public: | |
34 TransportFeedbackAdapterTest() | |
35 : clock_(0), | |
36 bitrate_estimator_(nullptr), | |
37 bitrate_controller_(this), | |
38 receiver_estimated_bitrate_(0) {} | |
39 | |
40 virtual ~TransportFeedbackAdapterTest() {} | |
41 | |
42 virtual void SetUp() { | |
43 adapter_.reset(new TransportFeedbackAdapter(&clock_)); | |
44 | |
45 bitrate_estimator_ = new MockRemoteBitrateEstimator(); | |
46 adapter_->SetBitrateEstimator(bitrate_estimator_); | |
47 } | |
48 | |
49 virtual void TearDown() { | |
50 adapter_.reset(); | |
51 } | |
52 | |
53 protected: | |
54 // Proxy class used since TransportFeedbackAdapter will own the instance | |
55 // passed at construction. | |
56 class MockBitrateControllerAdapter : public MockBitrateController { | |
57 public: | |
58 explicit MockBitrateControllerAdapter(TransportFeedbackAdapterTest* owner) | |
59 : MockBitrateController(), owner_(owner) {} | |
60 | |
61 ~MockBitrateControllerAdapter() override {} | |
62 | |
63 void OnReceiveBitrateChanged(const std::vector<uint32_t>& ssrcs, | |
64 uint32_t bitrate_bps) override { | |
65 owner_->receiver_estimated_bitrate_ = bitrate_bps; | |
66 } | |
67 | |
68 TransportFeedbackAdapterTest* const owner_; | |
69 }; | |
70 | |
71 void OnReceivedEstimatedBitrate(uint32_t bitrate) {} | |
72 | |
73 void OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks, | |
74 int64_t rtt, | |
75 int64_t now_ms) {} | |
76 | |
77 void ComparePacketVectors(const std::vector<PacketInfo>& truth, | |
78 const std::vector<PacketInfo>& input) { | |
79 ASSERT_EQ(truth.size(), input.size()); | |
80 size_t len = truth.size(); | |
81 // truth contains the input data for the test, and input is what will be | |
82 // sent to the bandwidth estimator. truth.arrival_tims_ms is used to | |
83 // populate the transport feedback messages. As these times may be changed | |
84 // (because of resolution limits in the packets, and because of the time | |
85 // base adjustment performed by the TransportFeedbackAdapter at the first | |
86 // packet, the truth[x].arrival_time and input[x].arrival_time may not be | |
87 // equal. However, the difference must be the same for all x. | |
88 int64_t arrival_time_delta = | |
89 truth[0].arrival_time_ms - input[0].arrival_time_ms; | |
90 for (size_t i = 0; i < len; ++i) { | |
91 EXPECT_EQ(truth[i].arrival_time_ms, | |
92 input[i].arrival_time_ms + arrival_time_delta); | |
93 EXPECT_EQ(truth[i].send_time_ms, input[i].send_time_ms); | |
94 EXPECT_EQ(truth[i].sequence_number, input[i].sequence_number); | |
95 EXPECT_EQ(truth[i].payload_size, input[i].payload_size); | |
96 EXPECT_EQ(truth[i].probe_cluster_id, input[i].probe_cluster_id); | |
97 } | |
98 } | |
99 | |
100 // Utility method, to reset arrival_time_ms before adding send time. | |
101 void OnSentPacket(PacketInfo info) { | |
102 info.arrival_time_ms = 0; | |
103 adapter_->AddPacket(info.sequence_number, info.payload_size, | |
104 info.probe_cluster_id); | |
105 adapter_->OnSentPacket(info.sequence_number, info.send_time_ms); | |
106 } | |
107 | |
108 SimulatedClock clock_; | |
109 MockRemoteBitrateEstimator* bitrate_estimator_; | |
110 MockBitrateControllerAdapter bitrate_controller_; | |
111 std::unique_ptr<TransportFeedbackAdapter> adapter_; | |
112 | |
113 uint32_t receiver_estimated_bitrate_; | |
114 }; | |
115 | |
116 TEST_F(TransportFeedbackAdapterTest, AdaptsFeedbackAndPopulatesSendTimes) { | |
117 std::vector<PacketInfo> packets; | |
118 packets.push_back(PacketInfo(100, 200, 0, 1500, 0)); | |
119 packets.push_back(PacketInfo(110, 210, 1, 1500, 0)); | |
120 packets.push_back(PacketInfo(120, 220, 2, 1500, 0)); | |
121 packets.push_back(PacketInfo(130, 230, 3, 1500, 1)); | |
122 packets.push_back(PacketInfo(140, 240, 4, 1500, 1)); | |
123 | |
124 for (const PacketInfo& packet : packets) | |
125 OnSentPacket(packet); | |
126 | |
127 rtcp::TransportFeedback feedback; | |
128 feedback.SetBase(packets[0].sequence_number, | |
129 packets[0].arrival_time_ms * 1000); | |
130 | |
131 for (const PacketInfo& packet : packets) { | |
132 EXPECT_TRUE(feedback.AddReceivedPacket(packet.sequence_number, | |
133 packet.arrival_time_ms * 1000)); | |
134 } | |
135 | |
136 feedback.Build(); | |
137 | |
138 EXPECT_CALL(*bitrate_estimator_, IncomingPacketFeedbackVector(_)) | |
139 .Times(1) | |
140 .WillOnce(Invoke( | |
141 [packets, this](const std::vector<PacketInfo>& feedback_vector) { | |
142 ComparePacketVectors(packets, feedback_vector); | |
143 })); | |
144 adapter_->OnTransportFeedback(feedback); | |
145 } | |
146 | |
147 TEST_F(TransportFeedbackAdapterTest, HandlesDroppedPackets) { | |
148 std::vector<PacketInfo> packets; | |
149 packets.push_back(PacketInfo(100, 200, 0, 1500, 1)); | |
150 packets.push_back(PacketInfo(110, 210, 1, 1500, 2)); | |
151 packets.push_back(PacketInfo(120, 220, 2, 1500, 3)); | |
152 packets.push_back(PacketInfo(130, 230, 3, 1500, 4)); | |
153 packets.push_back(PacketInfo(140, 240, 4, 1500, 5)); | |
154 | |
155 const uint16_t kSendSideDropBefore = 1; | |
156 const uint16_t kReceiveSideDropAfter = 3; | |
157 | |
158 for (const PacketInfo& packet : packets) { | |
159 if (packet.sequence_number >= kSendSideDropBefore) | |
160 OnSentPacket(packet); | |
161 } | |
162 | |
163 rtcp::TransportFeedback feedback; | |
164 feedback.SetBase(packets[0].sequence_number, | |
165 packets[0].arrival_time_ms * 1000); | |
166 | |
167 for (const PacketInfo& packet : packets) { | |
168 if (packet.sequence_number <= kReceiveSideDropAfter) { | |
169 EXPECT_TRUE(feedback.AddReceivedPacket(packet.sequence_number, | |
170 packet.arrival_time_ms * 1000)); | |
171 } | |
172 } | |
173 | |
174 feedback.Build(); | |
175 | |
176 std::vector<PacketInfo> expected_packets( | |
177 packets.begin() + kSendSideDropBefore, | |
178 packets.begin() + kReceiveSideDropAfter + 1); | |
179 | |
180 EXPECT_CALL(*bitrate_estimator_, IncomingPacketFeedbackVector(_)) | |
181 .Times(1) | |
182 .WillOnce(Invoke([expected_packets, | |
183 this](const std::vector<PacketInfo>& feedback_vector) { | |
184 ComparePacketVectors(expected_packets, feedback_vector); | |
185 })); | |
186 adapter_->OnTransportFeedback(feedback); | |
187 } | |
188 | |
189 TEST_F(TransportFeedbackAdapterTest, SendTimeWrapsBothWays) { | |
190 int64_t kHighArrivalTimeMs = rtcp::TransportFeedback::kDeltaScaleFactor * | |
191 static_cast<int64_t>(1 << 8) * | |
192 static_cast<int64_t>((1 << 23) - 1) / 1000; | |
193 std::vector<PacketInfo> packets; | |
194 packets.push_back(PacketInfo(kHighArrivalTimeMs - 64, 200, 0, 1500, | |
195 PacketInfo::kNotAProbe)); | |
196 packets.push_back(PacketInfo(kHighArrivalTimeMs + 64, 210, 1, 1500, | |
197 PacketInfo::kNotAProbe)); | |
198 packets.push_back( | |
199 PacketInfo(kHighArrivalTimeMs, 220, 2, 1500, PacketInfo::kNotAProbe)); | |
200 | |
201 for (const PacketInfo& packet : packets) | |
202 OnSentPacket(packet); | |
203 | |
204 for (size_t i = 0; i < packets.size(); ++i) { | |
205 std::unique_ptr<rtcp::TransportFeedback> feedback( | |
206 new rtcp::TransportFeedback()); | |
207 feedback->SetBase(packets[i].sequence_number, | |
208 packets[i].arrival_time_ms * 1000); | |
209 | |
210 EXPECT_TRUE(feedback->AddReceivedPacket(packets[i].sequence_number, | |
211 packets[i].arrival_time_ms * 1000)); | |
212 | |
213 rtc::Buffer raw_packet = feedback->Build(); | |
214 feedback = rtcp::TransportFeedback::ParseFrom(raw_packet.data(), | |
215 raw_packet.size()); | |
216 | |
217 std::vector<PacketInfo> expected_packets; | |
218 expected_packets.push_back(packets[i]); | |
219 | |
220 EXPECT_CALL(*bitrate_estimator_, IncomingPacketFeedbackVector(_)) | |
221 .Times(1) | |
222 .WillOnce(Invoke([expected_packets, this]( | |
223 const std::vector<PacketInfo>& feedback_vector) { | |
224 ComparePacketVectors(expected_packets, feedback_vector); | |
225 })); | |
226 adapter_->OnTransportFeedback(*feedback.get()); | |
227 } | |
228 } | |
229 | |
230 TEST_F(TransportFeedbackAdapterTest, HandlesReordering) { | |
231 std::vector<PacketInfo> packets; | |
232 packets.push_back(PacketInfo(120, 200, 0, 1500, 0)); | |
233 packets.push_back(PacketInfo(110, 210, 1, 1500, 0)); | |
234 packets.push_back(PacketInfo(100, 220, 2, 1500, 0)); | |
235 std::vector<PacketInfo> expected_packets; | |
236 expected_packets.push_back(packets[2]); | |
237 expected_packets.push_back(packets[1]); | |
238 expected_packets.push_back(packets[0]); | |
239 | |
240 for (const PacketInfo& packet : packets) | |
241 OnSentPacket(packet); | |
242 | |
243 rtcp::TransportFeedback feedback; | |
244 feedback.SetBase(packets[0].sequence_number, | |
245 packets[0].arrival_time_ms * 1000); | |
246 | |
247 for (const PacketInfo& packet : packets) { | |
248 EXPECT_TRUE(feedback.AddReceivedPacket(packet.sequence_number, | |
249 packet.arrival_time_ms * 1000)); | |
250 } | |
251 | |
252 feedback.Build(); | |
253 | |
254 EXPECT_CALL(*bitrate_estimator_, IncomingPacketFeedbackVector(_)) | |
255 .Times(1) | |
256 .WillOnce(Invoke([expected_packets, | |
257 this](const std::vector<PacketInfo>& feedback_vector) { | |
258 ComparePacketVectors(expected_packets, feedback_vector); | |
259 })); | |
260 adapter_->OnTransportFeedback(feedback); | |
261 } | |
262 | |
263 TEST_F(TransportFeedbackAdapterTest, TimestampDeltas) { | |
264 std::vector<PacketInfo> sent_packets; | |
265 const int64_t kSmallDeltaUs = | |
266 rtcp::TransportFeedback::kDeltaScaleFactor * ((1 << 8) - 1); | |
267 const int64_t kLargePositiveDeltaUs = | |
268 rtcp::TransportFeedback::kDeltaScaleFactor * | |
269 std::numeric_limits<int16_t>::max(); | |
270 const int64_t kLargeNegativeDeltaUs = | |
271 rtcp::TransportFeedback::kDeltaScaleFactor * | |
272 std::numeric_limits<int16_t>::min(); | |
273 | |
274 PacketInfo info(100, 200, 0, 1500, true, PacketInfo::kNotAProbe); | |
275 sent_packets.push_back(info); | |
276 | |
277 info.send_time_ms += kSmallDeltaUs / 1000; | |
278 info.arrival_time_ms += kSmallDeltaUs / 1000; | |
279 ++info.sequence_number; | |
280 sent_packets.push_back(info); | |
281 | |
282 info.send_time_ms += kLargePositiveDeltaUs / 1000; | |
283 info.arrival_time_ms += kLargePositiveDeltaUs / 1000; | |
284 ++info.sequence_number; | |
285 sent_packets.push_back(info); | |
286 | |
287 info.send_time_ms += kLargeNegativeDeltaUs / 1000; | |
288 info.arrival_time_ms += kLargeNegativeDeltaUs / 1000; | |
289 ++info.sequence_number; | |
290 sent_packets.push_back(info); | |
291 | |
292 // Too large, delta - will need two feedback messages. | |
293 info.send_time_ms += (kLargePositiveDeltaUs + 1000) / 1000; | |
294 info.arrival_time_ms += (kLargePositiveDeltaUs + 1000) / 1000; | |
295 ++info.sequence_number; | |
296 | |
297 // Expected to be ordered on arrival time when the feedback message has been | |
298 // parsed. | |
299 std::vector<PacketInfo> expected_packets; | |
300 expected_packets.push_back(sent_packets[0]); | |
301 expected_packets.push_back(sent_packets[3]); | |
302 expected_packets.push_back(sent_packets[1]); | |
303 expected_packets.push_back(sent_packets[2]); | |
304 | |
305 // Packets will be added to send history. | |
306 for (const PacketInfo& packet : sent_packets) | |
307 OnSentPacket(packet); | |
308 OnSentPacket(info); | |
309 | |
310 // Create expected feedback and send into adapter. | |
311 std::unique_ptr<rtcp::TransportFeedback> feedback( | |
312 new rtcp::TransportFeedback()); | |
313 feedback->SetBase(sent_packets[0].sequence_number, | |
314 sent_packets[0].arrival_time_ms * 1000); | |
315 | |
316 for (const PacketInfo& packet : sent_packets) { | |
317 EXPECT_TRUE(feedback->AddReceivedPacket(packet.sequence_number, | |
318 packet.arrival_time_ms * 1000)); | |
319 } | |
320 EXPECT_FALSE(feedback->AddReceivedPacket(info.sequence_number, | |
321 info.arrival_time_ms * 1000)); | |
322 | |
323 rtc::Buffer raw_packet = feedback->Build(); | |
324 feedback = | |
325 rtcp::TransportFeedback::ParseFrom(raw_packet.data(), raw_packet.size()); | |
326 | |
327 std::vector<PacketInfo> received_feedback; | |
328 | |
329 EXPECT_TRUE(feedback.get() != nullptr); | |
330 EXPECT_CALL(*bitrate_estimator_, IncomingPacketFeedbackVector(_)) | |
331 .Times(1) | |
332 .WillOnce(Invoke([expected_packets, &received_feedback]( | |
333 const std::vector<PacketInfo>& feedback_vector) { | |
334 EXPECT_EQ(expected_packets.size(), feedback_vector.size()); | |
335 received_feedback = feedback_vector; | |
336 })); | |
337 adapter_->OnTransportFeedback(*feedback.get()); | |
338 | |
339 // Create a new feedback message and add the trailing item. | |
340 feedback.reset(new rtcp::TransportFeedback()); | |
341 feedback->SetBase(info.sequence_number, info.arrival_time_ms * 1000); | |
342 EXPECT_TRUE(feedback->AddReceivedPacket(info.sequence_number, | |
343 info.arrival_time_ms * 1000)); | |
344 raw_packet = feedback->Build(); | |
345 feedback = | |
346 rtcp::TransportFeedback::ParseFrom(raw_packet.data(), raw_packet.size()); | |
347 | |
348 EXPECT_TRUE(feedback.get() != nullptr); | |
349 EXPECT_CALL(*bitrate_estimator_, IncomingPacketFeedbackVector(_)) | |
350 .Times(1) | |
351 .WillOnce(Invoke( | |
352 [&received_feedback](const std::vector<PacketInfo>& feedback_vector) { | |
353 EXPECT_EQ(1u, feedback_vector.size()); | |
354 received_feedback.push_back(feedback_vector[0]); | |
355 })); | |
356 adapter_->OnTransportFeedback(*feedback.get()); | |
357 | |
358 expected_packets.push_back(info); | |
359 | |
360 ComparePacketVectors(expected_packets, received_feedback); | |
361 } | |
362 | |
363 } // namespace test | |
364 } // namespace webrtc | |
OLD | NEW |