blob: 602bd770a23f4ddc97ef7f2316ed3cf0ed23e550 [file] [log] [blame]
stefan@webrtc.orgc7979e02013-05-17 12:55:071/*
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.org3f45c2e2013-08-05 16:22:5311#include <math.h>
12#include <stdio.h>
13#include <stdlib.h>
14
Henrik Kjellanderfe7633e2015-11-18 21:00:2115#include "webrtc/modules/video_coding/include/video_coding.h"
16#include "webrtc/modules/video_coding/internal_defines.h"
kwiberg36a24792016-10-01 05:29:4317#include "webrtc/modules/video_coding/timing.h"
Henrik Kjellander78f65d02015-10-28 17:17:4018#include "webrtc/system_wrappers/include/clock.h"
kwiberg36a24792016-10-01 05:29:4319#include "webrtc/test/gtest.h"
stefan@webrtc.orgc7979e02013-05-17 12:55:0720#include "webrtc/test/testsupport/fileutils.h"
21
22namespace webrtc {
23
24TEST(ReceiverTiming, Tests) {
25 SimulatedClock clock(0);
26 VCMTiming timing(&clock);
27 uint32_t waitTime = 0;
28 uint32_t jitterDelayMs = 0;
magjed42c4e1a2016-03-22 12:12:0929 uint32_t requiredDecodeTimeMs = 0;
stefan@webrtc.orgc7979e02013-05-17 12:55:0730 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.orge4775742013-05-30 16:20:1840 timing.SetJitterDelay(jitterDelayMs);
stefan@webrtc.orgc7979e02013-05-17 12:55:0741 timing.UpdateCurrentDelay(timeStamp);
mikhal@webrtc.orge4775742013-05-30 16:20:1842 timing.set_render_delay(0);
stefan@webrtc.orgc7979e02013-05-17 12:55:0743 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.orge4775742013-05-30 16:20:1853 timing.SetJitterDelay(jitterDelayMs);
stefan@webrtc.orgc7979e02013-05-17 12:55:0754 timing.UpdateCurrentDelay(timeStamp);
philipel288c2b62015-12-21 16:23:2055 waitTime = timing.MaxWaitingTime(
56 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()),
57 clock.TimeInMilliseconds());
stefan@webrtc.orgc7979e02013-05-17 12:55:0758 // 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);
philipel288c2b62015-12-21 16:23:2086 timing.StopDecodeTimer(
87 timeStamp, clock.TimeInMilliseconds() - startTimeMs,
88 clock.TimeInMilliseconds(),
89 timing.RenderTimeMs(timeStamp, clock.TimeInMilliseconds()));
stefan@webrtc.orgc7979e02013-05-17 12:55:0790 timeStamp += 90000 / 25;
91 clock.AdvanceTimeMilliseconds(1000 / 25 - 10);
92 timing.IncomingTimestamp(timeStamp, clock.TimeInMilliseconds());
93 }
magjed42c4e1a2016-03-22 12:12:0994 requiredDecodeTimeMs = 10;
mikhal@webrtc.orge4775742013-05-30 16:20:1895 timing.SetJitterDelay(jitterDelayMs);
stefan@webrtc.orgc7979e02013-05-17 12:55:0796 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
isheriff00cc0452016-06-08 07:24:21104 int minTotalDelayMs = 200;
mikhal@webrtc.orge4775742013-05-30 16:20:18105 timing.set_min_playout_delay(minTotalDelayMs);
stefan@webrtc.orgc7979e02013-05-17 12:55:07106 clock.AdvanceTimeMilliseconds(5000);
philipel288c2b62015-12-21 16:23:20107 timeStamp += 5 * 90000;
stefan@webrtc.orgc7979e02013-05-17 12:55:07108 timing.UpdateCurrentDelay(timeStamp);
109 const int kRenderDelayMs = 10;
mikhal@webrtc.orge4775742013-05-30 16:20:18110 timing.set_render_delay(kRenderDelayMs);
stefan@webrtc.orgc7979e02013-05-17 12:55:07111 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.
magjed42c4e1a2016-03-22 12:12:09116 EXPECT_EQ(waitTime, minTotalDelayMs - requiredDecodeTimeMs - kRenderDelayMs);
stefan@webrtc.orgc7979e02013-05-17 12:55:07117 // The total video delay should be equal to the min total delay.
118 EXPECT_EQ(minTotalDelayMs, timing.TargetVideoDelay());
119
mikhal@webrtc.orge4775742013-05-30 16:20:18120 // Reset playout delay.
121 timing.set_min_playout_delay(0);
stefan@webrtc.orgc7979e02013-05-17 12:55:07122 clock.AdvanceTimeMilliseconds(5000);
philipel288c2b62015-12-21 16:23:20123 timeStamp += 5 * 90000;
stefan@webrtc.orgc7979e02013-05-17 12:55:07124 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;
philipel288c2b62015-12-21 16:23:20137 int64_t render_time =
138 timing.RenderTimeMs(0xFFFFFFFFu, clock.TimeInMilliseconds());
stefan@webrtc.orgc7979e02013-05-17 12:55:07139 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