blob: 3aaa46d65db7cb738952018beb37163a9a42d18e [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
Henrik Kjellander2557b862015-11-18 22:00:21 +010015#include "webrtc/modules/video_coding/include/video_coding.h"
16#include "webrtc/modules/video_coding/internal_defines.h"
Henrik Kjellander2557b862015-11-18 22:00:21 +010017#include "webrtc/modules/video_coding/test/test_util.h"
kwibergac9f8762016-09-30 22:29:43 -070018#include "webrtc/modules/video_coding/timing.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010019#include "webrtc/system_wrappers/include/clock.h"
20#include "webrtc/system_wrappers/include/trace.h"
kwibergac9f8762016-09-30 22:29:43 -070021#include "webrtc/test/gtest.h"
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000022#include "webrtc/test/testsupport/fileutils.h"
23
24namespace webrtc {
25
26TEST(ReceiverTiming, Tests) {
27 SimulatedClock clock(0);
28 VCMTiming timing(&clock);
29 uint32_t waitTime = 0;
30 uint32_t jitterDelayMs = 0;
magjed2943f012016-03-22 05:12:09 -070031 uint32_t requiredDecodeTimeMs = 0;
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000032 uint32_t timeStamp = 0;
33
34 timing.Reset();
35
36 timing.UpdateCurrentDelay(timeStamp);
37
38 timing.Reset();
39
40 timing.IncomingTimestamp(timeStamp, clock.TimeInMilliseconds());
41 jitterDelayMs = 20;
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +000042 timing.SetJitterDelay(jitterDelayMs);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000043 timing.UpdateCurrentDelay(timeStamp);
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +000044 timing.set_render_delay(0);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000045 waitTime = timing.MaxWaitingTime(
46 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()),
47 clock.TimeInMilliseconds());
48 // First update initializes the render time. Since we have no decode delay
49 // we get waitTime = renderTime - now - renderDelay = jitter.
50 EXPECT_EQ(jitterDelayMs, waitTime);
51
52 jitterDelayMs += VCMTiming::kDelayMaxChangeMsPerS + 10;
53 timeStamp += 90000;
54 clock.AdvanceTimeMilliseconds(1000);
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +000055 timing.SetJitterDelay(jitterDelayMs);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000056 timing.UpdateCurrentDelay(timeStamp);
philipel5908c712015-12-21 08:23:20 -080057 waitTime = timing.MaxWaitingTime(
58 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()),
59 clock.TimeInMilliseconds());
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000060 // 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);
philipel5908c712015-12-21 08:23:20 -080088 timing.StopDecodeTimer(
89 timeStamp, clock.TimeInMilliseconds() - startTimeMs,
90 clock.TimeInMilliseconds(),
91 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()));
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000092 timeStamp += 90000 / 25;
93 clock.AdvanceTimeMilliseconds(1000 / 25 - 10);
94 timing.IncomingTimestamp(timeStamp, clock.TimeInMilliseconds());
95 }
magjed2943f012016-03-22 05:12:09 -070096 requiredDecodeTimeMs = 10;
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +000097 timing.SetJitterDelay(jitterDelayMs);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000098 clock.AdvanceTimeMilliseconds(1000);
99 timeStamp += 90000;
100 timing.UpdateCurrentDelay(timeStamp);
101 waitTime = timing.MaxWaitingTime(
102 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()),
103 clock.TimeInMilliseconds());
104 EXPECT_EQ(waitTime, jitterDelayMs);
105
isheriff6b4b5f32016-06-08 00:24:21 -0700106 int minTotalDelayMs = 200;
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +0000107 timing.set_min_playout_delay(minTotalDelayMs);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000108 clock.AdvanceTimeMilliseconds(5000);
philipel5908c712015-12-21 08:23:20 -0800109 timeStamp += 5 * 90000;
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000110 timing.UpdateCurrentDelay(timeStamp);
111 const int kRenderDelayMs = 10;
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +0000112 timing.set_render_delay(kRenderDelayMs);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000113 waitTime = timing.MaxWaitingTime(
114 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()),
115 clock.TimeInMilliseconds());
116 // We should at least have minTotalDelayMs - decodeTime (10) - renderTime
117 // (10) to wait.
magjed2943f012016-03-22 05:12:09 -0700118 EXPECT_EQ(waitTime, minTotalDelayMs - requiredDecodeTimeMs - kRenderDelayMs);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000119 // The total video delay should be equal to the min total delay.
120 EXPECT_EQ(minTotalDelayMs, timing.TargetVideoDelay());
121
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +0000122 // Reset playout delay.
123 timing.set_min_playout_delay(0);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000124 clock.AdvanceTimeMilliseconds(5000);
philipel5908c712015-12-21 08:23:20 -0800125 timeStamp += 5 * 90000;
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000126 timing.UpdateCurrentDelay(timeStamp);
127}
128
129TEST(ReceiverTiming, WrapAround) {
130 const int kFramerate = 25;
131 SimulatedClock clock(0);
132 VCMTiming timing(&clock);
133 // Provoke a wrap-around. The forth frame will have wrapped at 25 fps.
134 uint32_t timestamp = 0xFFFFFFFFu - 3 * 90000 / kFramerate;
135 for (int i = 0; i < 4; ++i) {
136 timing.IncomingTimestamp(timestamp, clock.TimeInMilliseconds());
137 clock.AdvanceTimeMilliseconds(1000 / kFramerate);
138 timestamp += 90000 / kFramerate;
philipel5908c712015-12-21 08:23:20 -0800139 int64_t render_time =
140 timing.RenderTimeMs(0xFFFFFFFFu, clock.TimeInMilliseconds());
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000141 EXPECT_EQ(3 * 1000 / kFramerate, render_time);
142 render_time = timing.RenderTimeMs(89u, // One second later in 90 kHz.
143 clock.TimeInMilliseconds());
144 EXPECT_EQ(3 * 1000 / kFramerate + 1, render_time);
145 }
146}
147
148} // namespace webrtc