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 "testing/gmock/include/gmock/gmock.h" | |
12 #include "testing/gtest/include/gtest/gtest.h" | |
13 | |
14 #include "webrtc/modules/pacing/include/packet_router.h" | |
15 #include "webrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.h" | |
16 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" | |
17 #include "webrtc/system_wrappers/interface/clock.h" | |
18 | |
19 using ::testing::_; | |
20 using ::testing::InSequence; | |
21 using ::testing::Invoke; | |
22 | |
23 namespace webrtc { | |
24 | |
25 class MockPacketRouter : public PacketRouter { | |
26 public: | |
27 MOCK_METHOD1(SendFeedback, bool(rtcp::TransportFeedback* packet)); | |
28 }; | |
29 | |
30 class RemoteEstimatorProxyTest : public ::testing::Test { | |
31 public: | |
32 RemoteEstimatorProxyTest() : clock_(0), proxy_(&clock_, &router_) {} | |
33 | |
34 protected: | |
35 void IncomingPacket(uint16_t seq, int64_t time_ms) { | |
36 RTPHeader header; | |
37 header.extension.hasTransportSequenceNumber = true; | |
38 header.extension.transportSequenceNumber = seq; | |
39 header.ssrc = kMediaSsrc; | |
40 proxy_.IncomingPacket(time_ms, kDefaultPacketSize, header, true); | |
41 } | |
42 | |
43 void Process() { | |
44 clock_.AdvanceTimeMilliseconds( | |
45 RemoteEstimatorProxy::kDefaultProcessIntervalMs); | |
46 proxy_.Process(); | |
47 } | |
48 | |
49 SimulatedClock clock_; | |
50 MockPacketRouter router_; | |
51 RemoteEstimatorProxy proxy_; | |
52 | |
53 const size_t kDefaultPacketSize = 100; | |
54 const uint32_t kMediaSsrc = 456; | |
55 const uint16_t kBaseSeq = 10; | |
56 const int64_t kBaseTimeMs = 123; | |
57 const int64_t kMaxSmallDeltaMs = | |
58 (rtcp::TransportFeedback::kDeltaScaleFactor * 0xFF) / 1000; | |
59 }; | |
60 | |
61 TEST_F(RemoteEstimatorProxyTest, SendsSinglePacketFeedback) { | |
62 IncomingPacket(kBaseSeq, kBaseTimeMs); | |
63 | |
64 EXPECT_CALL(router_, SendFeedback(_)) | |
65 .Times(1) | |
66 .WillOnce(Invoke([this](rtcp::TransportFeedback* packet) { | |
67 packet->Build(); | |
68 EXPECT_EQ(kBaseSeq, packet->GetBaseSequence()); | |
69 EXPECT_EQ(kMediaSsrc, packet->GetMediaSourceSsrc()); | |
70 | |
71 std::vector<rtcp::TransportFeedback::StatusSymbol> status_vec = | |
72 packet->GetStatusVector(); | |
73 EXPECT_EQ(1u, status_vec.size()); | |
74 EXPECT_EQ(rtcp::TransportFeedback::StatusSymbol::kReceivedSmallDelta, | |
75 status_vec[0]); | |
76 std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs(); | |
77 EXPECT_EQ(1u, delta_vec.size()); | |
78 EXPECT_EQ(kBaseTimeMs, (packet->GetBaseTimeUs() + delta_vec[0]) / 1000); | |
79 return true; | |
80 })); | |
81 | |
82 Process(); | |
83 } | |
84 | |
85 TEST_F(RemoteEstimatorProxyTest, SendsFeedbackWithVaryingDeltas) { | |
86 IncomingPacket(kBaseSeq, kBaseTimeMs); | |
87 IncomingPacket(kBaseSeq + 1, kBaseTimeMs + kMaxSmallDeltaMs); | |
88 IncomingPacket(kBaseSeq + 2, kBaseTimeMs + (2 * kMaxSmallDeltaMs) + 1); | |
89 | |
90 EXPECT_CALL(router_, SendFeedback(_)) | |
91 .Times(1) | |
92 .WillOnce(Invoke([this](rtcp::TransportFeedback* packet) { | |
93 packet->Build(); | |
94 EXPECT_EQ(kBaseSeq, packet->GetBaseSequence()); | |
95 EXPECT_EQ(kMediaSsrc, packet->GetMediaSourceSsrc()); | |
96 | |
97 std::vector<rtcp::TransportFeedback::StatusSymbol> status_vec = | |
98 packet->GetStatusVector(); | |
99 EXPECT_EQ(3u, status_vec.size()); | |
100 EXPECT_EQ(rtcp::TransportFeedback::StatusSymbol::kReceivedSmallDelta, | |
101 status_vec[0]); | |
102 EXPECT_EQ(rtcp::TransportFeedback::StatusSymbol::kReceivedSmallDelta, | |
103 status_vec[1]); | |
104 EXPECT_EQ(rtcp::TransportFeedback::StatusSymbol::kReceivedLargeDelta, | |
105 status_vec[2]); | |
106 | |
107 std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs(); | |
108 EXPECT_EQ(3u, delta_vec.size()); | |
109 EXPECT_EQ(kBaseTimeMs, (packet->GetBaseTimeUs() + delta_vec[0]) / 1000); | |
110 EXPECT_EQ(kMaxSmallDeltaMs, delta_vec[1] / 1000); | |
111 EXPECT_EQ(kMaxSmallDeltaMs + 1, delta_vec[2] / 1000); | |
112 return true; | |
113 })); | |
114 | |
115 Process(); | |
116 } | |
117 | |
118 TEST_F(RemoteEstimatorProxyTest, SendsFragmentedFeedback) { | |
119 const int64_t kTooLargeDelta = | |
120 rtcp::TransportFeedback::kDeltaScaleFactor * (1 << 16); | |
121 | |
122 IncomingPacket(kBaseSeq, kBaseTimeMs); | |
123 IncomingPacket(kBaseSeq + 1, kBaseTimeMs + kTooLargeDelta); | |
124 | |
125 InSequence s; | |
126 EXPECT_CALL(router_, SendFeedback(_)) | |
127 .Times(1) | |
128 .WillOnce(Invoke([kTooLargeDelta, this](rtcp::TransportFeedback* packet) { | |
129 packet->Build(); | |
130 EXPECT_EQ(kBaseSeq, packet->GetBaseSequence()); | |
131 EXPECT_EQ(kMediaSsrc, packet->GetMediaSourceSsrc()); | |
132 | |
133 std::vector<rtcp::TransportFeedback::StatusSymbol> status_vec = | |
134 packet->GetStatusVector(); | |
135 EXPECT_EQ(1u, status_vec.size()); | |
136 EXPECT_EQ(rtcp::TransportFeedback::StatusSymbol::kReceivedSmallDelta, | |
137 status_vec[0]); | |
138 std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs(); | |
139 EXPECT_EQ(1u, delta_vec.size()); | |
140 EXPECT_EQ(kBaseTimeMs, (packet->GetBaseTimeUs() + delta_vec[0]) / 1000); | |
141 return true; | |
142 })) | |
143 .RetiresOnSaturation(); | |
stefan-webrtc
2015/09/04 07:31:36
Seems a bit odd to me that this is needed in combi
sprang_webrtc
2015/09/04 13:29:44
I'm a rookie! Brought this over after following so
| |
144 | |
145 EXPECT_CALL(router_, SendFeedback(_)) | |
146 .Times(1) | |
147 .WillOnce(Invoke([kTooLargeDelta, this](rtcp::TransportFeedback* packet) { | |
148 packet->Build(); | |
149 EXPECT_EQ(kBaseSeq + 1, packet->GetBaseSequence()); | |
150 EXPECT_EQ(kMediaSsrc, packet->GetMediaSourceSsrc()); | |
151 | |
152 std::vector<rtcp::TransportFeedback::StatusSymbol> status_vec = | |
153 packet->GetStatusVector(); | |
154 EXPECT_EQ(1u, status_vec.size()); | |
155 EXPECT_EQ(rtcp::TransportFeedback::StatusSymbol::kReceivedSmallDelta, | |
156 status_vec[0]); | |
157 std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs(); | |
158 EXPECT_EQ(1u, delta_vec.size()); | |
159 EXPECT_EQ(kBaseTimeMs + kTooLargeDelta, | |
160 (packet->GetBaseTimeUs() + delta_vec[0]) / 1000); | |
161 return true; | |
162 })) | |
163 .RetiresOnSaturation(); | |
164 | |
165 Process(); | |
166 } | |
167 | |
168 TEST_F(RemoteEstimatorProxyTest, ResendsTimestampsOnReordering) { | |
169 IncomingPacket(kBaseSeq, kBaseTimeMs); | |
170 IncomingPacket(kBaseSeq + 2, kBaseTimeMs + 2); | |
171 | |
172 EXPECT_CALL(router_, SendFeedback(_)) | |
173 .Times(1) | |
174 .WillOnce(Invoke([this](rtcp::TransportFeedback* packet) { | |
175 packet->Build(); | |
176 EXPECT_EQ(kBaseSeq, packet->GetBaseSequence()); | |
177 EXPECT_EQ(kMediaSsrc, packet->GetMediaSourceSsrc()); | |
178 | |
179 std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs(); | |
180 EXPECT_EQ(2u, delta_vec.size()); | |
181 EXPECT_EQ(kBaseTimeMs, (packet->GetBaseTimeUs() + delta_vec[0]) / 1000); | |
182 EXPECT_EQ(2, delta_vec[1] / 1000); | |
183 return true; | |
184 })); | |
185 | |
186 Process(); | |
187 | |
188 IncomingPacket(kBaseSeq + 1, kBaseTimeMs + 1); | |
189 | |
190 EXPECT_CALL(router_, SendFeedback(_)) | |
191 .Times(1) | |
192 .WillOnce(Invoke([this](rtcp::TransportFeedback* packet) { | |
193 packet->Build(); | |
194 EXPECT_EQ(kBaseSeq + 1, packet->GetBaseSequence()); | |
195 EXPECT_EQ(kMediaSsrc, packet->GetMediaSourceSsrc()); | |
196 | |
197 std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs(); | |
198 EXPECT_EQ(2u, delta_vec.size()); | |
199 EXPECT_EQ(kBaseTimeMs + 1, | |
200 (packet->GetBaseTimeUs() + delta_vec[0]) / 1000); | |
201 EXPECT_EQ(1, delta_vec[1] / 1000); | |
202 return true; | |
203 })); | |
204 | |
205 Process(); | |
206 } | |
207 | |
208 TEST_F(RemoteEstimatorProxyTest, RemovesTimestampsOutOfScope) { | |
209 const int64_t kTimeoutTimeMs = | |
210 kBaseTimeMs + RemoteEstimatorProxy::kBackWindowMs; | |
211 | |
212 IncomingPacket(kBaseSeq + 2, kBaseTimeMs); | |
213 | |
214 EXPECT_CALL(router_, SendFeedback(_)) | |
215 .Times(1) | |
216 .WillOnce(Invoke([kTimeoutTimeMs, this](rtcp::TransportFeedback* packet) { | |
217 packet->Build(); | |
218 EXPECT_EQ(kBaseSeq + 2, packet->GetBaseSequence()); | |
219 | |
220 std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs(); | |
221 EXPECT_EQ(1u, delta_vec.size()); | |
222 EXPECT_EQ(kBaseTimeMs, (packet->GetBaseTimeUs() + delta_vec[0]) / 1000); | |
223 return true; | |
224 })); | |
225 | |
226 Process(); | |
227 | |
228 IncomingPacket(kBaseSeq + 3, kTimeoutTimeMs); // kBaseSeq + 2 times out here. | |
229 | |
230 EXPECT_CALL(router_, SendFeedback(_)) | |
231 .Times(1) | |
232 .WillOnce(Invoke([kTimeoutTimeMs, this](rtcp::TransportFeedback* packet) { | |
233 packet->Build(); | |
234 EXPECT_EQ(kBaseSeq + 3, packet->GetBaseSequence()); | |
235 | |
236 std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs(); | |
237 EXPECT_EQ(1u, delta_vec.size()); | |
238 EXPECT_EQ(kTimeoutTimeMs, | |
239 (packet->GetBaseTimeUs() + delta_vec[0]) / 1000); | |
240 return true; | |
241 })); | |
242 | |
243 Process(); | |
244 | |
245 // New group, with sequence starting below the first so that they may be | |
246 // retransmitted. | |
247 IncomingPacket(kBaseSeq, kBaseTimeMs - 1); | |
248 IncomingPacket(kBaseSeq + 1, kTimeoutTimeMs - 1); | |
249 | |
250 EXPECT_CALL(router_, SendFeedback(_)) | |
251 .Times(1) | |
252 .WillOnce(Invoke([kTimeoutTimeMs, this](rtcp::TransportFeedback* packet) { | |
253 packet->Build(); | |
254 EXPECT_EQ(kBaseSeq, packet->GetBaseSequence()); | |
255 | |
256 // Four status entries (kBaseSeq + 3 missing). | |
257 EXPECT_EQ(4u, packet->GetStatusVector().size()); | |
258 | |
259 // Only three actual timestamps. | |
260 std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs(); | |
261 EXPECT_EQ(3u, delta_vec.size()); | |
262 EXPECT_EQ(kBaseTimeMs - 1, | |
263 (packet->GetBaseTimeUs() + delta_vec[0]) / 1000); | |
264 EXPECT_EQ(kTimeoutTimeMs - kBaseTimeMs, delta_vec[1] / 1000); | |
265 EXPECT_EQ(1, delta_vec[2] / 1000); | |
266 return true; | |
267 })); | |
268 | |
269 Process(); | |
270 } | |
271 | |
272 } // namespace webrtc | |
OLD | NEW |