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/include/video_coding.h" 18#include "webrtc/modules/video_coding/internal_defines.h" 19#include "webrtc/modules/video_coding/timing.h" 20#include "webrtc/modules/video_coding/test/test_util.h" 21#include "webrtc/system_wrappers/include/clock.h" 22#include "webrtc/system_wrappers/include/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( 59 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()), 60 clock.TimeInMilliseconds()); 61 // Since we gradually increase the delay we only get 100 ms every second. 62 EXPECT_EQ(jitterDelayMs - 10, waitTime); 63 64 timeStamp += 90000; 65 clock.AdvanceTimeMilliseconds(1000); 66 timing.UpdateCurrentDelay(timeStamp); 67 waitTime = timing.MaxWaitingTime( 68 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()), 69 clock.TimeInMilliseconds()); 70 EXPECT_EQ(waitTime, jitterDelayMs); 71 72 // 300 incoming frames without jitter, verify that this gives the exact wait 73 // time. 74 for (int i = 0; i < 300; i++) { 75 clock.AdvanceTimeMilliseconds(1000 / 25); 76 timeStamp += 90000 / 25; 77 timing.IncomingTimestamp(timeStamp, clock.TimeInMilliseconds()); 78 } 79 timing.UpdateCurrentDelay(timeStamp); 80 waitTime = timing.MaxWaitingTime( 81 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()), 82 clock.TimeInMilliseconds()); 83 EXPECT_EQ(waitTime, jitterDelayMs); 84 85 // Add decode time estimates. 86 for (int i = 0; i < 10; i++) { 87 int64_t startTimeMs = clock.TimeInMilliseconds(); 88 clock.AdvanceTimeMilliseconds(10); 89 timing.StopDecodeTimer( 90 timeStamp, clock.TimeInMilliseconds() - startTimeMs, 91 clock.TimeInMilliseconds(), 92 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds())); 93 timeStamp += 90000 / 25; 94 clock.AdvanceTimeMilliseconds(1000 / 25 - 10); 95 timing.IncomingTimestamp(timeStamp, clock.TimeInMilliseconds()); 96 } 97 maxDecodeTimeMs = 10; 98 timing.SetJitterDelay(jitterDelayMs); 99 clock.AdvanceTimeMilliseconds(1000); 100 timeStamp += 90000; 101 timing.UpdateCurrentDelay(timeStamp); 102 waitTime = timing.MaxWaitingTime( 103 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()), 104 clock.TimeInMilliseconds()); 105 EXPECT_EQ(waitTime, jitterDelayMs); 106 107 uint32_t minTotalDelayMs = 200; 108 timing.set_min_playout_delay(minTotalDelayMs); 109 clock.AdvanceTimeMilliseconds(5000); 110 timeStamp += 5 * 90000; 111 timing.UpdateCurrentDelay(timeStamp); 112 const int kRenderDelayMs = 10; 113 timing.set_render_delay(kRenderDelayMs); 114 waitTime = timing.MaxWaitingTime( 115 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()), 116 clock.TimeInMilliseconds()); 117 // We should at least have minTotalDelayMs - decodeTime (10) - renderTime 118 // (10) to wait. 119 EXPECT_EQ(waitTime, minTotalDelayMs - maxDecodeTimeMs - kRenderDelayMs); 120 // The total video delay should be equal to the min total delay. 121 EXPECT_EQ(minTotalDelayMs, timing.TargetVideoDelay()); 122 123 // Reset playout delay. 124 timing.set_min_playout_delay(0); 125 clock.AdvanceTimeMilliseconds(5000); 126 timeStamp += 5 * 90000; 127 timing.UpdateCurrentDelay(timeStamp); 128} 129 130TEST(ReceiverTiming, WrapAround) { 131 const int kFramerate = 25; 132 SimulatedClock clock(0); 133 VCMTiming timing(&clock); 134 // Provoke a wrap-around. The forth frame will have wrapped at 25 fps. 135 uint32_t timestamp = 0xFFFFFFFFu - 3 * 90000 / kFramerate; 136 for (int i = 0; i < 4; ++i) { 137 timing.IncomingTimestamp(timestamp, clock.TimeInMilliseconds()); 138 clock.AdvanceTimeMilliseconds(1000 / kFramerate); 139 timestamp += 90000 / kFramerate; 140 int64_t render_time = 141 timing.RenderTimeMs(0xFFFFFFFFu, clock.TimeInMilliseconds()); 142 EXPECT_EQ(3 * 1000 / kFramerate, render_time); 143 render_time = timing.RenderTimeMs(89u, // One second later in 90 kHz. 144 clock.TimeInMilliseconds()); 145 EXPECT_EQ(3 * 1000 / kFramerate + 1, render_time); 146 } 147} 148 149} // namespace webrtc 150