blob: 02bd88ddb2de572f184c7c50ea10f4327ca3e878 [file] [log] [blame]
stefan@webrtc.org9f557c12013-05-17 12:55:07 +00001/*
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
pbos@webrtc.org12dc1a32013-08-05 16:22:53 +000011#include <math.h>
12#include <stdio.h>
13#include <stdlib.h>
14
pbos@webrtc.orga4407322013-07-16 12:32:05 +000015#include "testing/gtest/include/gtest/gtest.h"
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000016
Henrik Kjellander2557b862015-11-18 22:00:21 +010017#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"
Henrik Kjellander98f53512015-10-28 18:17:40 +010021#include "webrtc/system_wrappers/include/clock.h"
22#include "webrtc/system_wrappers/include/trace.h"
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000023#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;
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +000043 timing.SetJitterDelay(jitterDelayMs);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000044 timing.UpdateCurrentDelay(timeStamp);
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +000045 timing.set_render_delay(0);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000046 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);
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +000056 timing.SetJitterDelay(jitterDelayMs);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000057 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);
Per327d8ba2015-11-10 14:00:27 +010088 timing.StopDecodeTimer(timeStamp,
89 clock.TimeInMilliseconds() - startTimeMs,
90 clock.TimeInMilliseconds(),
91 timing.RenderTimeMs(
asapersson@webrtc.orgf2447602014-12-09 14:13:26 +000092 timeStamp, clock.TimeInMilliseconds()));
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000093 timeStamp += 90000 / 25;
94 clock.AdvanceTimeMilliseconds(1000 / 25 - 10);
95 timing.IncomingTimestamp(timeStamp, clock.TimeInMilliseconds());
96 }
97 maxDecodeTimeMs = 10;
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +000098 timing.SetJitterDelay(jitterDelayMs);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000099 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;
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +0000108 timing.set_min_playout_delay(minTotalDelayMs);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000109 clock.AdvanceTimeMilliseconds(5000);
110 timeStamp += 5*90000;
111 timing.UpdateCurrentDelay(timeStamp);
112 const int kRenderDelayMs = 10;
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +0000113 timing.set_render_delay(kRenderDelayMs);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000114 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
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +0000123 // Reset playout delay.
124 timing.set_min_playout_delay(0);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000125 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 = timing.RenderTimeMs(0xFFFFFFFFu,
141 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