1e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes/* 2e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 3e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes * 4e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes * Use of this source code is governed by a BSD-style license 5e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes * that can be found in the LICENSE file in the root of the source 6e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes * tree. An additional intellectual property rights grant can be found 7e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes * in the file PATENTS. All contributing project authors may 8e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes * be found in the AUTHORS file in the root of the source tree. 9e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes */ 10e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes 11e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes#include "webrtc/modules/remote_bitrate_estimator/test/metric_recorder.h" 12e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes 132386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes#include <math.h> 14e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes#include <algorithm> 15e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes#include <vector> 16e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes 17e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes#include "testing/gtest/include/gtest/gtest.h" 18e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes 19e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaesnamespace webrtc { 20e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaesnamespace testing { 21e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaesnamespace bwe { 22e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes 23e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaesclass MetricRecorderTest : public ::testing::Test { 24e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes public: 25e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes MetricRecorderTest() : metric_recorder_("Test", 0, nullptr, nullptr) {} 26e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes 27e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes ~MetricRecorderTest() {} 28e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes 29e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes protected: 30e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes MetricRecorder metric_recorder_; 31e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes}; 32e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes 33e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar MagalhaesTEST_F(MetricRecorderTest, NoPackets) { 34e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes EXPECT_EQ(metric_recorder_.AverageBitrateKbps(0), 0); 35e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes EXPECT_EQ(metric_recorder_.DelayStdDev(), 0.0); 36e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes EXPECT_EQ(metric_recorder_.NthDelayPercentile(0), 0); 37e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes EXPECT_EQ(metric_recorder_.NthDelayPercentile(5), 0); 38e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes EXPECT_EQ(metric_recorder_.NthDelayPercentile(95), 0); 39e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes EXPECT_EQ(metric_recorder_.NthDelayPercentile(100), 0); 40e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes} 41e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes 42e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar MagalhaesTEST_F(MetricRecorderTest, RegularPackets) { 43e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes const size_t kPayloadSizeBytes = 1200; 44e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes const int64_t kDelayMs = 20; 45e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes const int64_t kInterpacketGapMs = 5; 46e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes const int kNumPackets = 1000; 47e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes 48e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes for (int i = 0; i < kNumPackets; ++i) { 49e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes int64_t arrival_time_ms = kInterpacketGapMs * i + kDelayMs; 502386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes metric_recorder_.UpdateTimeMs(arrival_time_ms); 51e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes metric_recorder_.PushDelayMs(kDelayMs, arrival_time_ms); 52e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes metric_recorder_.PushThroughputBytes(kPayloadSizeBytes, arrival_time_ms); 53e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes } 54e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes 55e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes EXPECT_NEAR( 56e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes metric_recorder_.AverageBitrateKbps(0), 57e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes static_cast<uint32_t>(kPayloadSizeBytes * 8) / (kInterpacketGapMs), 10); 58e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes 59e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes EXPECT_EQ(metric_recorder_.DelayStdDev(), 0.0); 60e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes 61e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes EXPECT_EQ(metric_recorder_.NthDelayPercentile(0), kDelayMs); 62e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes EXPECT_EQ(metric_recorder_.NthDelayPercentile(5), kDelayMs); 63e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes EXPECT_EQ(metric_recorder_.NthDelayPercentile(95), kDelayMs); 64e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes EXPECT_EQ(metric_recorder_.NthDelayPercentile(100), kDelayMs); 65e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes} 66e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes 67e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar MagalhaesTEST_F(MetricRecorderTest, VariableDelayPackets) { 68e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes const size_t kPayloadSizeBytes = 1200; 69e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes const int64_t kInterpacketGapMs = 2000; 70e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes const int kNumPackets = 1000; 71e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes 72e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes std::vector<int64_t> delays_ms; 73e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes for (int i = 0; i < kNumPackets; ++i) { 74e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes delays_ms.push_back(static_cast<int64_t>(i + 1)); 75e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes } 76e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes // Order of packets should not matter here. 77e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes std::random_shuffle(delays_ms.begin(), delays_ms.end()); 78e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes 79e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes int first_received_ms = delays_ms[0]; 80e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes int64_t last_received_ms = 0; 81e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes for (int i = 0; i < kNumPackets; ++i) { 82e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes int64_t arrival_time_ms = kInterpacketGapMs * i + delays_ms[i]; 83e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes last_received_ms = std::max(last_received_ms, arrival_time_ms); 842386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes metric_recorder_.UpdateTimeMs(arrival_time_ms); 85e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes metric_recorder_.PushDelayMs(delays_ms[i], arrival_time_ms); 86e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes metric_recorder_.PushThroughputBytes(kPayloadSizeBytes, arrival_time_ms); 87e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes } 88e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes 89e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes size_t received_bits = kPayloadSizeBytes * 8 * kNumPackets; 90e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes EXPECT_NEAR(metric_recorder_.AverageBitrateKbps(0), 91e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes static_cast<uint32_t>(received_bits) / 92e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes ((last_received_ms - first_received_ms)), 93e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes 10); 94e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes 95e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes double expected_x = (kNumPackets + 1) / 2.0; 96e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes double expected_x2 = ((kNumPackets + 1) * (2 * kNumPackets + 1)) / 6.0; 97e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes double var = expected_x2 - pow(expected_x, 2.0); 98e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes EXPECT_NEAR(metric_recorder_.DelayStdDev(), sqrt(var), kNumPackets / 1000.0); 99e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes 100e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes EXPECT_EQ(metric_recorder_.NthDelayPercentile(0), 1); 101e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes EXPECT_EQ(metric_recorder_.NthDelayPercentile(5), (5 * kNumPackets) / 100); 102e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes EXPECT_EQ(metric_recorder_.NthDelayPercentile(95), (95 * kNumPackets) / 100); 103e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes EXPECT_EQ(metric_recorder_.NthDelayPercentile(100), kNumPackets); 104e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes} 105e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes 106e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes} // namespace bwe 107e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes} // namespace testing 108e2cb1f12c3d1c5500de1b733dfc8bbfea504d89fCesar Magalhaes} // namespace webrtc 109