1/* 2 * Copyright (c) 2013 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/gtest/include/gtest/gtest.h" 12 13#include "webrtc/base/scoped_ptr.h" 14#include "webrtc/common_types.h" 15#include "webrtc/modules/remote_bitrate_estimator/inter_arrival.h" 16 17namespace webrtc { 18namespace testing { 19 20enum { 21 kTimestampGroupLengthUs = 5000, 22 kMinStep = 20, 23 kTriggerNewGroupUs = kTimestampGroupLengthUs + kMinStep, 24 kBurstThresholdMs = 5, 25 kAbsSendTimeFraction = 18, 26 kAbsSendTimeInterArrivalUpshift = 8, 27 kInterArrivalShift = kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift, 28}; 29 30const double kRtpTimestampToMs = 1.0 / 90.0; 31const double kAstToMs = 1000.0 / static_cast<double>(1 << kInterArrivalShift); 32 33class InterArrivalTest : public ::testing::Test { 34 protected: 35 virtual void SetUp() { 36 inter_arrival_rtp_.reset(new InterArrival( 37 MakeRtpTimestamp(kTimestampGroupLengthUs), 38 kRtpTimestampToMs, 39 true)); 40 inter_arrival_ast_.reset(new InterArrival( 41 MakeAbsSendTime(kTimestampGroupLengthUs), 42 kAstToMs, 43 true)); 44 } 45 46 // Test that neither inter_arrival instance complete the timestamp group from 47 // the given data. 48 void ExpectFalse(int64_t timestamp_us, int64_t arrival_time_ms, 49 size_t packet_size) { 50 InternalExpectFalse(inter_arrival_rtp_.get(), 51 MakeRtpTimestamp(timestamp_us), arrival_time_ms, 52 packet_size); 53 InternalExpectFalse(inter_arrival_ast_.get(), MakeAbsSendTime(timestamp_us), 54 arrival_time_ms, packet_size); 55 } 56 57 // Test that both inter_arrival instances complete the timestamp group from 58 // the given data and that all returned deltas are as expected (except 59 // timestamp delta, which is rounded from us to different ranges and must 60 // match within an interval, given in |timestamp_near]. 61 void ExpectTrue(int64_t timestamp_us, int64_t arrival_time_ms, 62 size_t packet_size, int64_t expected_timestamp_delta_us, 63 int64_t expected_arrival_time_delta_ms, 64 int expected_packet_size_delta, 65 uint32_t timestamp_near) { 66 InternalExpectTrue(inter_arrival_rtp_.get(), MakeRtpTimestamp(timestamp_us), 67 arrival_time_ms, packet_size, 68 MakeRtpTimestamp(expected_timestamp_delta_us), 69 expected_arrival_time_delta_ms, 70 expected_packet_size_delta, timestamp_near); 71 InternalExpectTrue(inter_arrival_ast_.get(), MakeAbsSendTime(timestamp_us), 72 arrival_time_ms, packet_size, 73 MakeAbsSendTime(expected_timestamp_delta_us), 74 expected_arrival_time_delta_ms, 75 expected_packet_size_delta, timestamp_near << 8); 76 } 77 78 void WrapTestHelper(int64_t wrap_start_us, uint32_t timestamp_near, 79 bool unorderly_within_group) { 80 // Step through the range of a 32 bit int, 1/4 at a time to not cause 81 // packets close to wraparound to be judged as out of order. 82 83 // G1 84 int64_t arrival_time = 17; 85 ExpectFalse(0, arrival_time, 1); 86 87 // G2 88 arrival_time += kBurstThresholdMs + 1; 89 ExpectFalse(wrap_start_us / 4, arrival_time, 1); 90 91 // G3 92 arrival_time += kBurstThresholdMs + 1; 93 ExpectTrue(wrap_start_us / 2, arrival_time, 1, 94 wrap_start_us / 4, 6, 0, // Delta G2-G1 95 0); 96 97 // G4 98 arrival_time += kBurstThresholdMs + 1; 99 int64_t g4_arrival_time = arrival_time; 100 ExpectTrue(wrap_start_us / 2 + wrap_start_us / 4, arrival_time, 1, 101 wrap_start_us / 4, 6, 0, // Delta G3-G2 102 timestamp_near); 103 104 // G5 105 arrival_time += kBurstThresholdMs + 1; 106 ExpectTrue(wrap_start_us, arrival_time, 2, 107 wrap_start_us / 4, 6, 0, // Delta G4-G3 108 timestamp_near); 109 for (int i = 0; i < 10; ++i) { 110 // Slowly step across the wrap point. 111 arrival_time += kBurstThresholdMs + 1; 112 if (unorderly_within_group) { 113 // These packets arrive with timestamps in decreasing order but are 114 // nevertheless accumulated to group because their timestamps are higher 115 // than the initial timestamp of the group. 116 ExpectFalse(wrap_start_us + kMinStep * (9 - i), arrival_time, 1); 117 } else { 118 ExpectFalse(wrap_start_us + kMinStep * i, arrival_time, 1); 119 } 120 } 121 int64_t g5_arrival_time = arrival_time; 122 123 // This packet is out of order and should be dropped. 124 arrival_time += kBurstThresholdMs + 1; 125 ExpectFalse(wrap_start_us - 100, arrival_time, 100); 126 127 // G6 128 arrival_time += kBurstThresholdMs + 1; 129 int64_t g6_arrival_time = arrival_time; 130 ExpectTrue(wrap_start_us + kTriggerNewGroupUs, arrival_time, 10, 131 wrap_start_us / 4 + 9 * kMinStep, 132 g5_arrival_time - g4_arrival_time, 133 (2 + 10) - 1, // Delta G5-G4 134 timestamp_near); 135 136 // This packet is out of order and should be dropped. 137 arrival_time += kBurstThresholdMs + 1; 138 ExpectFalse(wrap_start_us + kTimestampGroupLengthUs, arrival_time, 100); 139 140 // G7 141 arrival_time += kBurstThresholdMs + 1; 142 ExpectTrue(wrap_start_us + 2 * kTriggerNewGroupUs, 143 arrival_time, 100, 144 // Delta G6-G5 145 kTriggerNewGroupUs - 9 * kMinStep, 146 g6_arrival_time - g5_arrival_time, 147 10 - (2 + 10), 148 timestamp_near); 149 } 150 151 private: 152 static uint32_t MakeRtpTimestamp(int64_t us) { 153 return static_cast<uint32_t>(static_cast<uint64_t>(us * 90 + 500) / 1000); 154 } 155 156 static uint32_t MakeAbsSendTime(int64_t us) { 157 uint32_t absolute_send_time = static_cast<uint32_t>( 158 ((static_cast<uint64_t>(us) << 18) + 500000) / 1000000) & 0x00FFFFFFul; 159 return absolute_send_time << 8; 160 } 161 162 static void InternalExpectFalse(InterArrival* inter_arrival, 163 uint32_t timestamp, int64_t arrival_time_ms, 164 size_t packet_size) { 165 uint32_t dummy_timestamp = 101; 166 int64_t dummy_arrival_time_ms = 303; 167 int dummy_packet_size = 909; 168 bool computed = inter_arrival->ComputeDeltas(timestamp, 169 arrival_time_ms, 170 packet_size, 171 &dummy_timestamp, 172 &dummy_arrival_time_ms, 173 &dummy_packet_size); 174 EXPECT_EQ(computed, false); 175 EXPECT_EQ(101ul, dummy_timestamp); 176 EXPECT_EQ(303, dummy_arrival_time_ms); 177 EXPECT_EQ(909, dummy_packet_size); 178 } 179 180 static void InternalExpectTrue(InterArrival* inter_arrival, 181 uint32_t timestamp, int64_t arrival_time_ms, 182 size_t packet_size, 183 uint32_t expected_timestamp_delta, 184 int64_t expected_arrival_time_delta_ms, 185 int expected_packet_size_delta, 186 uint32_t timestamp_near) { 187 uint32_t delta_timestamp = 101; 188 int64_t delta_arrival_time_ms = 303; 189 int delta_packet_size = 909; 190 bool computed = inter_arrival->ComputeDeltas(timestamp, 191 arrival_time_ms, 192 packet_size, 193 &delta_timestamp, 194 &delta_arrival_time_ms, 195 &delta_packet_size); 196 EXPECT_EQ(true, computed); 197 EXPECT_NEAR(expected_timestamp_delta, delta_timestamp, timestamp_near); 198 EXPECT_EQ(expected_arrival_time_delta_ms, delta_arrival_time_ms); 199 EXPECT_EQ(expected_packet_size_delta, delta_packet_size); 200 } 201 202 rtc::scoped_ptr<InterArrival> inter_arrival_rtp_; 203 rtc::scoped_ptr<InterArrival> inter_arrival_ast_; 204}; 205 206TEST_F(InterArrivalTest, FirstPacket) { 207 ExpectFalse(0, 17, 1); 208} 209 210TEST_F(InterArrivalTest, FirstGroup) { 211 // G1 212 int64_t arrival_time = 17; 213 int64_t g1_arrival_time = arrival_time; 214 ExpectFalse(0, arrival_time, 1); 215 216 // G2 217 arrival_time += kBurstThresholdMs + 1; 218 int64_t g2_arrival_time = arrival_time; 219 ExpectFalse(kTriggerNewGroupUs, arrival_time, 2); 220 221 // G3 222 // Only once the first packet of the third group arrives, do we see the deltas 223 // between the first two. 224 arrival_time += kBurstThresholdMs + 1; 225 ExpectTrue(2 * kTriggerNewGroupUs, arrival_time, 1, 226 // Delta G2-G1 227 kTriggerNewGroupUs, g2_arrival_time - g1_arrival_time, 1, 228 0); 229} 230 231TEST_F(InterArrivalTest, SecondGroup) { 232 // G1 233 int64_t arrival_time = 17; 234 int64_t g1_arrival_time = arrival_time; 235 ExpectFalse(0, arrival_time, 1); 236 237 // G2 238 arrival_time += kBurstThresholdMs + 1; 239 int64_t g2_arrival_time = arrival_time; 240 ExpectFalse(kTriggerNewGroupUs, arrival_time, 2); 241 242 // G3 243 arrival_time += kBurstThresholdMs + 1; 244 int64_t g3_arrival_time = arrival_time; 245 ExpectTrue(2 * kTriggerNewGroupUs, arrival_time, 1, 246 // Delta G2-G1 247 kTriggerNewGroupUs, g2_arrival_time - g1_arrival_time, 1, 248 0); 249 250 // G4 251 // First packet of 4th group yields deltas between group 2 and 3. 252 arrival_time += kBurstThresholdMs + 1; 253 ExpectTrue(3 * kTriggerNewGroupUs, arrival_time, 2, 254 // Delta G3-G2 255 kTriggerNewGroupUs, g3_arrival_time - g2_arrival_time, -1, 256 0); 257} 258 259TEST_F(InterArrivalTest, AccumulatedGroup) { 260 // G1 261 int64_t arrival_time = 17; 262 int64_t g1_arrival_time = arrival_time; 263 ExpectFalse(0, arrival_time, 1); 264 265 // G2 266 arrival_time += kBurstThresholdMs + 1; 267 ExpectFalse(kTriggerNewGroupUs, 28, 2); 268 int64_t timestamp = kTriggerNewGroupUs; 269 for (int i = 0; i < 10; ++i) { 270 // A bunch of packets arriving within the same group. 271 arrival_time += kBurstThresholdMs + 1; 272 timestamp += kMinStep; 273 ExpectFalse(timestamp, arrival_time, 1); 274 } 275 int64_t g2_arrival_time = arrival_time; 276 int64_t g2_timestamp = timestamp; 277 278 // G3 279 arrival_time = 500; 280 ExpectTrue(2 * kTriggerNewGroupUs, arrival_time, 100, 281 g2_timestamp, g2_arrival_time - g1_arrival_time, 282 (2 + 10) - 1, // Delta G2-G1 283 0); 284} 285 286TEST_F(InterArrivalTest, OutOfOrderPacket) { 287 // G1 288 int64_t arrival_time = 17; 289 int64_t timestamp = 0; 290 ExpectFalse(timestamp, arrival_time, 1); 291 int64_t g1_timestamp = timestamp; 292 int64_t g1_arrival_time = arrival_time; 293 294 // G2 295 arrival_time += 11; 296 timestamp += kTriggerNewGroupUs; 297 ExpectFalse(timestamp, 28, 2); 298 for (int i = 0; i < 10; ++i) { 299 arrival_time += kBurstThresholdMs + 1; 300 timestamp += kMinStep; 301 ExpectFalse(timestamp, arrival_time, 1); 302 } 303 int64_t g2_timestamp = timestamp; 304 int64_t g2_arrival_time = arrival_time; 305 306 // This packet is out of order and should be dropped. 307 arrival_time = 281; 308 ExpectFalse(g1_timestamp, arrival_time, 100); 309 310 // G3 311 arrival_time = 500; 312 timestamp = 2 * kTriggerNewGroupUs; 313 ExpectTrue(timestamp, arrival_time, 100, 314 // Delta G2-G1 315 g2_timestamp - g1_timestamp, g2_arrival_time - g1_arrival_time, 316 (2 + 10) - 1, 317 0); 318} 319 320TEST_F(InterArrivalTest, OutOfOrderWithinGroup) { 321 // G1 322 int64_t arrival_time = 17; 323 int64_t timestamp = 0; 324 ExpectFalse(timestamp, arrival_time, 1); 325 int64_t g1_timestamp = timestamp; 326 int64_t g1_arrival_time = arrival_time; 327 328 // G2 329 timestamp += kTriggerNewGroupUs; 330 arrival_time += 11; 331 ExpectFalse(kTriggerNewGroupUs, 28, 2); 332 timestamp += 10 * kMinStep; 333 int64_t g2_timestamp = timestamp; 334 for (int i = 0; i < 10; ++i) { 335 // These packets arrive with timestamps in decreasing order but are 336 // nevertheless accumulated to group because their timestamps are higher 337 // than the initial timestamp of the group. 338 arrival_time += kBurstThresholdMs + 1; 339 ExpectFalse(timestamp, arrival_time, 1); 340 timestamp -= kMinStep; 341 } 342 int64_t g2_arrival_time = arrival_time; 343 344 // However, this packet is deemed out of order and should be dropped. 345 arrival_time = 281; 346 timestamp = g1_timestamp; 347 ExpectFalse(timestamp, arrival_time, 100); 348 349 // G3 350 timestamp = 2 * kTriggerNewGroupUs; 351 arrival_time = 500; 352 ExpectTrue(timestamp, arrival_time, 100, 353 g2_timestamp - g1_timestamp, g2_arrival_time - g1_arrival_time, 354 (2 + 10) - 1, 355 0); 356} 357 358TEST_F(InterArrivalTest, TwoBursts) { 359 // G1 360 int64_t g1_arrival_time = 17; 361 ExpectFalse(0, g1_arrival_time, 1); 362 363 // G2 364 int64_t timestamp = kTriggerNewGroupUs; 365 int64_t arrival_time = 100; // Simulate no packets arriving for 100 ms. 366 for (int i = 0; i < 10; ++i) { 367 // A bunch of packets arriving in one burst (within 5 ms apart). 368 timestamp += 30000; 369 arrival_time += kBurstThresholdMs; 370 ExpectFalse(timestamp, arrival_time, 1); 371 } 372 int64_t g2_arrival_time = arrival_time; 373 int64_t g2_timestamp = timestamp; 374 375 // G3 376 timestamp += 30000; 377 arrival_time += kBurstThresholdMs + 1; 378 ExpectTrue(timestamp, arrival_time, 100, 379 g2_timestamp, g2_arrival_time - g1_arrival_time, 380 10 - 1, // Delta G2-G1 381 0); 382} 383 384 385TEST_F(InterArrivalTest, NoBursts) { 386 // G1 387 ExpectFalse(0, 17, 1); 388 389 // G2 390 int64_t timestamp = kTriggerNewGroupUs; 391 int64_t arrival_time = 28; 392 ExpectFalse(timestamp, arrival_time, 2); 393 394 // G3 395 ExpectTrue(kTriggerNewGroupUs + 30000, arrival_time + kBurstThresholdMs + 1, 396 100, timestamp - 0, arrival_time - 17, 397 2 - 1, // Delta G2-G1 398 0); 399} 400 401// Yields 0xfffffffe when converted to internal representation in 402// inter_arrival_rtp_ and inter_arrival_ast_ respectively. 403static const int64_t kStartRtpTimestampWrapUs = 47721858827; 404static const int64_t kStartAbsSendTimeWrapUs = 63999995; 405 406TEST_F(InterArrivalTest, RtpTimestampWrap) { 407 WrapTestHelper(kStartRtpTimestampWrapUs, 1, false); 408} 409 410TEST_F(InterArrivalTest, AbsSendTimeWrap) { 411 WrapTestHelper(kStartAbsSendTimeWrapUs, 1, false); 412} 413 414TEST_F(InterArrivalTest, RtpTimestampWrapOutOfOrderWithinGroup) { 415 WrapTestHelper(kStartRtpTimestampWrapUs, 1, true); 416} 417 418TEST_F(InterArrivalTest, AbsSendTimeWrapOutOfOrderWithinGroup) { 419 WrapTestHelper(kStartAbsSendTimeWrapUs, 1, true); 420} 421} // namespace testing 422} // namespace webrtc 423