blob: 40c9f1f38d1ca22aedfdfeab2dee0b077522d865 [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "modules/video_coding/include/video_coding.h"
16#include "modules/video_coding/internal_defines.h"
17#include "modules/video_coding/timing.h"
18#include "system_wrappers/include/clock.h"
19#include "test/gtest.h"
20#include "test/testsupport/fileutils.h"
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000021
22namespace webrtc {
23
24TEST(ReceiverTiming, Tests) {
25 SimulatedClock clock(0);
26 VCMTiming timing(&clock);
27 uint32_t waitTime = 0;
28 uint32_t jitterDelayMs = 0;
magjed2943f012016-03-22 05:12:09 -070029 uint32_t requiredDecodeTimeMs = 0;
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000030 uint32_t timeStamp = 0;
31
32 timing.Reset();
33
34 timing.UpdateCurrentDelay(timeStamp);
35
36 timing.Reset();
37
38 timing.IncomingTimestamp(timeStamp, clock.TimeInMilliseconds());
39 jitterDelayMs = 20;
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +000040 timing.SetJitterDelay(jitterDelayMs);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000041 timing.UpdateCurrentDelay(timeStamp);
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +000042 timing.set_render_delay(0);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000043 waitTime = timing.MaxWaitingTime(
44 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()),
45 clock.TimeInMilliseconds());
46 // First update initializes the render time. Since we have no decode delay
47 // we get waitTime = renderTime - now - renderDelay = jitter.
48 EXPECT_EQ(jitterDelayMs, waitTime);
49
50 jitterDelayMs += VCMTiming::kDelayMaxChangeMsPerS + 10;
51 timeStamp += 90000;
52 clock.AdvanceTimeMilliseconds(1000);
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +000053 timing.SetJitterDelay(jitterDelayMs);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000054 timing.UpdateCurrentDelay(timeStamp);
philipel5908c712015-12-21 08:23:20 -080055 waitTime = timing.MaxWaitingTime(
56 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()),
57 clock.TimeInMilliseconds());
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000058 // Since we gradually increase the delay we only get 100 ms every second.
59 EXPECT_EQ(jitterDelayMs - 10, waitTime);
60
61 timeStamp += 90000;
62 clock.AdvanceTimeMilliseconds(1000);
63 timing.UpdateCurrentDelay(timeStamp);
64 waitTime = timing.MaxWaitingTime(
65 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()),
66 clock.TimeInMilliseconds());
67 EXPECT_EQ(waitTime, jitterDelayMs);
68
69 // 300 incoming frames without jitter, verify that this gives the exact wait
70 // time.
71 for (int i = 0; i < 300; i++) {
72 clock.AdvanceTimeMilliseconds(1000 / 25);
73 timeStamp += 90000 / 25;
74 timing.IncomingTimestamp(timeStamp, clock.TimeInMilliseconds());
75 }
76 timing.UpdateCurrentDelay(timeStamp);
77 waitTime = timing.MaxWaitingTime(
78 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()),
79 clock.TimeInMilliseconds());
80 EXPECT_EQ(waitTime, jitterDelayMs);
81
82 // Add decode time estimates.
83 for (int i = 0; i < 10; i++) {
84 int64_t startTimeMs = clock.TimeInMilliseconds();
85 clock.AdvanceTimeMilliseconds(10);
philipel5908c712015-12-21 08:23:20 -080086 timing.StopDecodeTimer(
87 timeStamp, clock.TimeInMilliseconds() - startTimeMs,
88 clock.TimeInMilliseconds(),
89 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()));
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000090 timeStamp += 90000 / 25;
91 clock.AdvanceTimeMilliseconds(1000 / 25 - 10);
92 timing.IncomingTimestamp(timeStamp, clock.TimeInMilliseconds());
93 }
magjed2943f012016-03-22 05:12:09 -070094 requiredDecodeTimeMs = 10;
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +000095 timing.SetJitterDelay(jitterDelayMs);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000096 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
isheriff6b4b5f32016-06-08 00:24:21 -0700104 int minTotalDelayMs = 200;
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +0000105 timing.set_min_playout_delay(minTotalDelayMs);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000106 clock.AdvanceTimeMilliseconds(5000);
philipel5908c712015-12-21 08:23:20 -0800107 timeStamp += 5 * 90000;
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000108 timing.UpdateCurrentDelay(timeStamp);
109 const int kRenderDelayMs = 10;
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +0000110 timing.set_render_delay(kRenderDelayMs);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000111 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.
magjed2943f012016-03-22 05:12:09 -0700116 EXPECT_EQ(waitTime, minTotalDelayMs - requiredDecodeTimeMs - kRenderDelayMs);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000117 // The total video delay should be equal to the min total delay.
118 EXPECT_EQ(minTotalDelayMs, timing.TargetVideoDelay());
119
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +0000120 // Reset playout delay.
121 timing.set_min_playout_delay(0);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000122 clock.AdvanceTimeMilliseconds(5000);
philipel5908c712015-12-21 08:23:20 -0800123 timeStamp += 5 * 90000;
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000124 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;
philipel5908c712015-12-21 08:23:20 -0800137 int64_t render_time =
138 timing.RenderTimeMs(0xFFFFFFFFu, clock.TimeInMilliseconds());
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000139 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