blob: 69c1a214d72efee33cdc754b17f3b2f78c042f1d [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"
kwibergac9f8762016-09-30 22:29:43 -070017#include "webrtc/modules/video_coding/timing.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010018#include "webrtc/system_wrappers/include/clock.h"
19#include "webrtc/system_wrappers/include/trace.h"
kwibergac9f8762016-09-30 22:29:43 -070020#include "webrtc/test/gtest.h"
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000021#include "webrtc/test/testsupport/fileutils.h"
22
23namespace webrtc {
24
25TEST(ReceiverTiming, Tests) {
26 SimulatedClock clock(0);
27 VCMTiming timing(&clock);
28 uint32_t waitTime = 0;
29 uint32_t jitterDelayMs = 0;
magjed2943f012016-03-22 05:12:09 -070030 uint32_t requiredDecodeTimeMs = 0;
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000031 uint32_t timeStamp = 0;
32
33 timing.Reset();
34
35 timing.UpdateCurrentDelay(timeStamp);
36
37 timing.Reset();
38
39 timing.IncomingTimestamp(timeStamp, clock.TimeInMilliseconds());
40 jitterDelayMs = 20;
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +000041 timing.SetJitterDelay(jitterDelayMs);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000042 timing.UpdateCurrentDelay(timeStamp);
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +000043 timing.set_render_delay(0);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000044 waitTime = timing.MaxWaitingTime(
45 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()),
46 clock.TimeInMilliseconds());
47 // First update initializes the render time. Since we have no decode delay
48 // we get waitTime = renderTime - now - renderDelay = jitter.
49 EXPECT_EQ(jitterDelayMs, waitTime);
50
51 jitterDelayMs += VCMTiming::kDelayMaxChangeMsPerS + 10;
52 timeStamp += 90000;
53 clock.AdvanceTimeMilliseconds(1000);
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +000054 timing.SetJitterDelay(jitterDelayMs);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000055 timing.UpdateCurrentDelay(timeStamp);
philipel5908c712015-12-21 08:23:20 -080056 waitTime = timing.MaxWaitingTime(
57 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()),
58 clock.TimeInMilliseconds());
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000059 // Since we gradually increase the delay we only get 100 ms every second.
60 EXPECT_EQ(jitterDelayMs - 10, waitTime);
61
62 timeStamp += 90000;
63 clock.AdvanceTimeMilliseconds(1000);
64 timing.UpdateCurrentDelay(timeStamp);
65 waitTime = timing.MaxWaitingTime(
66 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()),
67 clock.TimeInMilliseconds());
68 EXPECT_EQ(waitTime, jitterDelayMs);
69
70 // 300 incoming frames without jitter, verify that this gives the exact wait
71 // time.
72 for (int i = 0; i < 300; i++) {
73 clock.AdvanceTimeMilliseconds(1000 / 25);
74 timeStamp += 90000 / 25;
75 timing.IncomingTimestamp(timeStamp, clock.TimeInMilliseconds());
76 }
77 timing.UpdateCurrentDelay(timeStamp);
78 waitTime = timing.MaxWaitingTime(
79 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()),
80 clock.TimeInMilliseconds());
81 EXPECT_EQ(waitTime, jitterDelayMs);
82
83 // Add decode time estimates.
84 for (int i = 0; i < 10; i++) {
85 int64_t startTimeMs = clock.TimeInMilliseconds();
86 clock.AdvanceTimeMilliseconds(10);
philipel5908c712015-12-21 08:23:20 -080087 timing.StopDecodeTimer(
88 timeStamp, clock.TimeInMilliseconds() - startTimeMs,
89 clock.TimeInMilliseconds(),
90 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()));
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000091 timeStamp += 90000 / 25;
92 clock.AdvanceTimeMilliseconds(1000 / 25 - 10);
93 timing.IncomingTimestamp(timeStamp, clock.TimeInMilliseconds());
94 }
magjed2943f012016-03-22 05:12:09 -070095 requiredDecodeTimeMs = 10;
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +000096 timing.SetJitterDelay(jitterDelayMs);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000097 clock.AdvanceTimeMilliseconds(1000);
98 timeStamp += 90000;
99 timing.UpdateCurrentDelay(timeStamp);
100 waitTime = timing.MaxWaitingTime(
101 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()),
102 clock.TimeInMilliseconds());
103 EXPECT_EQ(waitTime, jitterDelayMs);
104
isheriff6b4b5f32016-06-08 00:24:21 -0700105 int minTotalDelayMs = 200;
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +0000106 timing.set_min_playout_delay(minTotalDelayMs);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000107 clock.AdvanceTimeMilliseconds(5000);
philipel5908c712015-12-21 08:23:20 -0800108 timeStamp += 5 * 90000;
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000109 timing.UpdateCurrentDelay(timeStamp);
110 const int kRenderDelayMs = 10;
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +0000111 timing.set_render_delay(kRenderDelayMs);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000112 waitTime = timing.MaxWaitingTime(
113 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()),
114 clock.TimeInMilliseconds());
115 // We should at least have minTotalDelayMs - decodeTime (10) - renderTime
116 // (10) to wait.
magjed2943f012016-03-22 05:12:09 -0700117 EXPECT_EQ(waitTime, minTotalDelayMs - requiredDecodeTimeMs - kRenderDelayMs);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000118 // The total video delay should be equal to the min total delay.
119 EXPECT_EQ(minTotalDelayMs, timing.TargetVideoDelay());
120
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +0000121 // Reset playout delay.
122 timing.set_min_playout_delay(0);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000123 clock.AdvanceTimeMilliseconds(5000);
philipel5908c712015-12-21 08:23:20 -0800124 timeStamp += 5 * 90000;
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000125 timing.UpdateCurrentDelay(timeStamp);
126}
127
128TEST(ReceiverTiming, WrapAround) {
129 const int kFramerate = 25;
130 SimulatedClock clock(0);
131 VCMTiming timing(&clock);
132 // Provoke a wrap-around. The forth frame will have wrapped at 25 fps.
133 uint32_t timestamp = 0xFFFFFFFFu - 3 * 90000 / kFramerate;
134 for (int i = 0; i < 4; ++i) {
135 timing.IncomingTimestamp(timestamp, clock.TimeInMilliseconds());
136 clock.AdvanceTimeMilliseconds(1000 / kFramerate);
137 timestamp += 90000 / kFramerate;
philipel5908c712015-12-21 08:23:20 -0800138 int64_t render_time =
139 timing.RenderTimeMs(0xFFFFFFFFu, clock.TimeInMilliseconds());
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000140 EXPECT_EQ(3 * 1000 / kFramerate, render_time);
141 render_time = timing.RenderTimeMs(89u, // One second later in 90 kHz.
142 clock.TimeInMilliseconds());
143 EXPECT_EQ(3 * 1000 / kFramerate + 1, render_time);
144 }
145}
146
147} // namespace webrtc