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