1/* 2 * Copyright (c) 2011 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 <math.h> 12#include <stdio.h> 13#include <stdlib.h> 14 15#include "testing/gtest/include/gtest/gtest.h" 16 17#include "webrtc/modules/video_coding/main/interface/video_coding.h" 18#include "webrtc/modules/video_coding/main/source/internal_defines.h" 19#include "webrtc/modules/video_coding/main/source/timing.h" 20#include "webrtc/modules/video_coding/main/test/receiver_tests.h" 21#include "webrtc/modules/video_coding/main/test/test_util.h" 22#include "webrtc/system_wrappers/interface/trace.h" 23#include "webrtc/test/testsupport/fileutils.h" 24 25namespace webrtc { 26 27TEST(ReceiverTiming, Tests) { 28 SimulatedClock clock(0); 29 VCMTiming timing(&clock); 30 uint32_t waitTime = 0; 31 uint32_t jitterDelayMs = 0; 32 uint32_t maxDecodeTimeMs = 0; 33 uint32_t timeStamp = 0; 34 35 timing.Reset(); 36 37 timing.UpdateCurrentDelay(timeStamp); 38 39 timing.Reset(); 40 41 timing.IncomingTimestamp(timeStamp, clock.TimeInMilliseconds()); 42 jitterDelayMs = 20; 43 timing.SetJitterDelay(jitterDelayMs); 44 timing.UpdateCurrentDelay(timeStamp); 45 timing.set_render_delay(0); 46 waitTime = timing.MaxWaitingTime( 47 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()), 48 clock.TimeInMilliseconds()); 49 // First update initializes the render time. Since we have no decode delay 50 // we get waitTime = renderTime - now - renderDelay = jitter. 51 EXPECT_EQ(jitterDelayMs, waitTime); 52 53 jitterDelayMs += VCMTiming::kDelayMaxChangeMsPerS + 10; 54 timeStamp += 90000; 55 clock.AdvanceTimeMilliseconds(1000); 56 timing.SetJitterDelay(jitterDelayMs); 57 timing.UpdateCurrentDelay(timeStamp); 58 waitTime = timing.MaxWaitingTime(timing.RenderTimeMs( 59 timeStamp, clock.TimeInMilliseconds()), clock.TimeInMilliseconds()); 60 // Since we gradually increase the delay we only get 100 ms every second. 61 EXPECT_EQ(jitterDelayMs - 10, waitTime); 62 63 timeStamp += 90000; 64 clock.AdvanceTimeMilliseconds(1000); 65 timing.UpdateCurrentDelay(timeStamp); 66 waitTime = timing.MaxWaitingTime( 67 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()), 68 clock.TimeInMilliseconds()); 69 EXPECT_EQ(waitTime, jitterDelayMs); 70 71 // 300 incoming frames without jitter, verify that this gives the exact wait 72 // time. 73 for (int i = 0; i < 300; i++) { 74 clock.AdvanceTimeMilliseconds(1000 / 25); 75 timeStamp += 90000 / 25; 76 timing.IncomingTimestamp(timeStamp, clock.TimeInMilliseconds()); 77 } 78 timing.UpdateCurrentDelay(timeStamp); 79 waitTime = timing.MaxWaitingTime( 80 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()), 81 clock.TimeInMilliseconds()); 82 EXPECT_EQ(waitTime, jitterDelayMs); 83 84 // Add decode time estimates. 85 for (int i = 0; i < 10; i++) { 86 int64_t startTimeMs = clock.TimeInMilliseconds(); 87 clock.AdvanceTimeMilliseconds(10); 88 timing.StopDecodeTimer(timeStamp, startTimeMs, 89 clock.TimeInMilliseconds()); 90 timeStamp += 90000 / 25; 91 clock.AdvanceTimeMilliseconds(1000 / 25 - 10); 92 timing.IncomingTimestamp(timeStamp, clock.TimeInMilliseconds()); 93 } 94 maxDecodeTimeMs = 10; 95 timing.SetJitterDelay(jitterDelayMs); 96 clock.AdvanceTimeMilliseconds(1000); 97 timeStamp += 90000; 98 timing.UpdateCurrentDelay(timeStamp); 99 waitTime = timing.MaxWaitingTime( 100 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()), 101 clock.TimeInMilliseconds()); 102 EXPECT_EQ(waitTime, jitterDelayMs); 103 104 uint32_t minTotalDelayMs = 200; 105 timing.set_min_playout_delay(minTotalDelayMs); 106 clock.AdvanceTimeMilliseconds(5000); 107 timeStamp += 5*90000; 108 timing.UpdateCurrentDelay(timeStamp); 109 const int kRenderDelayMs = 10; 110 timing.set_render_delay(kRenderDelayMs); 111 waitTime = timing.MaxWaitingTime( 112 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()), 113 clock.TimeInMilliseconds()); 114 // We should at least have minTotalDelayMs - decodeTime (10) - renderTime 115 // (10) to wait. 116 EXPECT_EQ(waitTime, minTotalDelayMs - maxDecodeTimeMs - kRenderDelayMs); 117 // The total video delay should be equal to the min total delay. 118 EXPECT_EQ(minTotalDelayMs, timing.TargetVideoDelay()); 119 120 // Reset playout delay. 121 timing.set_min_playout_delay(0); 122 clock.AdvanceTimeMilliseconds(5000); 123 timeStamp += 5*90000; 124 timing.UpdateCurrentDelay(timeStamp); 125} 126 127TEST(ReceiverTiming, WrapAround) { 128 const int kFramerate = 25; 129 SimulatedClock clock(0); 130 VCMTiming timing(&clock); 131 // Provoke a wrap-around. The forth frame will have wrapped at 25 fps. 132 uint32_t timestamp = 0xFFFFFFFFu - 3 * 90000 / kFramerate; 133 for (int i = 0; i < 4; ++i) { 134 timing.IncomingTimestamp(timestamp, clock.TimeInMilliseconds()); 135 clock.AdvanceTimeMilliseconds(1000 / kFramerate); 136 timestamp += 90000 / kFramerate; 137 int64_t render_time = timing.RenderTimeMs(0xFFFFFFFFu, 138 clock.TimeInMilliseconds()); 139 EXPECT_EQ(3 * 1000 / kFramerate, render_time); 140 render_time = timing.RenderTimeMs(89u, // One second later in 90 kHz. 141 clock.TimeInMilliseconds()); 142 EXPECT_EQ(3 * 1000 / kFramerate + 1, render_time); 143 } 144} 145 146} // namespace webrtc 147