1 /* GStreamer
2 *
3 * Copyright (C) 2019 Net Insight AB
4 * Author: Nicolas Dufresne <nicolas.dufresne@collabora.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22 #include <gst/check/gstcheck.h>
23 #include "gst/rtpmanager/rtptimerqueue.h"
24
GST_START_TEST(test_timer_queue_set_timer)25 GST_START_TEST (test_timer_queue_set_timer)
26 {
27 RtpTimerQueue *queue = rtp_timer_queue_new ();
28 RtpTimer *timer10, *timer0;
29
30 rtp_timer_queue_set_timer (queue, RTP_TIMER_EXPECTED, 10,
31 1 * GST_SECOND, 2 * GST_SECOND, 5 * GST_SECOND, 0);
32 timer10 = rtp_timer_queue_find (queue, 10);
33 fail_unless (timer10);
34 fail_unless_equals_int (10, timer10->seqnum);
35 fail_unless_equals_int (RTP_TIMER_EXPECTED, timer10->type);
36 /* timer10->timeout = timerout + delay */
37 fail_unless_equals_uint64 (3 * GST_SECOND, timer10->timeout);
38 fail_unless_equals_uint64 (5 * GST_SECOND, timer10->duration);
39 fail_unless_equals_uint64 (1 * GST_SECOND, timer10->rtx_base);
40 fail_unless_equals_uint64 (GST_CLOCK_TIME_NONE, timer10->rtx_last);
41 fail_unless_equals_int (0, timer10->num_rtx_retry);
42 fail_unless_equals_int (0, timer10->num_rtx_received);
43
44 rtp_timer_queue_set_timer (queue, RTP_TIMER_LOST, 0,
45 0 * GST_SECOND, 2 * GST_SECOND, 0, 0);
46 timer0 = rtp_timer_queue_find (queue, 0);
47 fail_unless (timer0);
48 fail_unless_equals_int (0, timer0->seqnum);
49 fail_unless_equals_int (RTP_TIMER_LOST, timer0->type);
50 fail_unless_equals_uint64 (2 * GST_SECOND, timer0->timeout);
51 fail_unless_equals_uint64 (0, timer0->duration);
52 fail_unless_equals_uint64 (0, timer0->rtx_base);
53 fail_unless_equals_uint64 (GST_CLOCK_TIME_NONE, timer0->rtx_last);
54 fail_unless_equals_int (0, timer0->num_rtx_retry);
55 fail_unless_equals_int (0, timer0->num_rtx_received);
56
57 /* also check order while at it */
58 fail_unless (timer10->list.next == NULL);
59 fail_unless (timer10->list.prev == (GList *) timer0);
60 fail_unless (timer0->list.next == (GList *) timer10);
61 fail_unless (timer0->list.prev == NULL);
62
63 g_object_unref (queue);
64 }
65
66 GST_END_TEST;
67
GST_START_TEST(test_timer_queue_insert_head)68 GST_START_TEST (test_timer_queue_insert_head)
69 {
70 RtpTimerQueue *queue = rtp_timer_queue_new ();
71 RtpTimer *timer, *next, *prev;
72
73 rtp_timer_queue_set_deadline (queue, 1, -1, 0);
74 rtp_timer_queue_set_deadline (queue, 3, -1, 0);
75 rtp_timer_queue_set_deadline (queue, 2, -1, 0);
76 rtp_timer_queue_set_deadline (queue, 0, -1, 0);
77
78 timer = rtp_timer_queue_find (queue, 0);
79 fail_if (timer == NULL);
80 fail_unless_equals_int (0, timer->seqnum);
81 next = (RtpTimer *) timer->list.next;
82 prev = (RtpTimer *) timer->list.prev;
83 fail_unless (prev == NULL);
84 fail_if (next == NULL);
85 fail_unless_equals_int (1, next->seqnum);
86
87 timer = rtp_timer_queue_find (queue, 3);
88 fail_if (timer == NULL);
89 fail_unless_equals_int (3, timer->seqnum);
90 next = (RtpTimer *) timer->list.next;
91 prev = (RtpTimer *) timer->list.prev;
92 fail_if (prev == NULL);
93 fail_unless_equals_int (2, prev->seqnum);
94 fail_unless (next == NULL);
95
96 timer = rtp_timer_queue_find (queue, 2);
97 fail_if (timer == NULL);
98 fail_unless_equals_int (2, timer->seqnum);
99 next = (RtpTimer *) timer->list.next;
100 prev = (RtpTimer *) timer->list.prev;
101 fail_if (prev == NULL);
102 fail_if (next == NULL);
103 fail_unless_equals_int (1, prev->seqnum);
104 fail_unless_equals_int (3, next->seqnum);
105
106 timer = rtp_timer_queue_find (queue, 1);
107 fail_if (timer == NULL);
108 fail_unless_equals_int (1, timer->seqnum);
109 next = (RtpTimer *) timer->list.next;
110 prev = (RtpTimer *) timer->list.prev;
111 fail_if (prev == NULL);
112 fail_if (next == NULL);
113 fail_unless_equals_int (0, prev->seqnum);
114 fail_unless_equals_int (2, next->seqnum);
115
116 g_object_unref (queue);
117 }
118
119 GST_END_TEST;
120
GST_START_TEST(test_timer_queue_reschedule)121 GST_START_TEST (test_timer_queue_reschedule)
122 {
123 RtpTimerQueue *queue = rtp_timer_queue_new ();
124 RtpTimer *timer, *next, *prev;
125
126 rtp_timer_queue_set_deadline (queue, 3, 1 * GST_SECOND, 0);
127 rtp_timer_queue_set_deadline (queue, 1, 2 * GST_SECOND, 0);
128 rtp_timer_queue_set_deadline (queue, 2, 3 * GST_SECOND, 0);
129 rtp_timer_queue_set_deadline (queue, 0, 4 * GST_SECOND, 0);
130
131 timer = rtp_timer_queue_find (queue, 1);
132 fail_if (timer == NULL);
133
134 /* move to head, making sure seqnum order is respected */
135 rtp_timer_queue_set_deadline (queue, 1, 1 * GST_SECOND, 0);
136 next = (RtpTimer *) timer->list.next;
137 prev = (RtpTimer *) timer->list.prev;
138 fail_unless (prev == NULL);
139 fail_if (next == NULL);
140 fail_unless_equals_int (3, next->seqnum);
141
142 /* move head back */
143 rtp_timer_queue_set_deadline (queue, 1, 2 * GST_SECOND, 0);
144 next = (RtpTimer *) timer->list.next;
145 prev = (RtpTimer *) timer->list.prev;
146 fail_if (prev == NULL);
147 fail_if (next == NULL);
148 fail_unless_equals_int (3, prev->seqnum);
149 fail_unless_equals_int (2, next->seqnum);
150
151 /* move to tail */
152 timer = rtp_timer_queue_find (queue, 2);
153 fail_if (timer == NULL);
154 rtp_timer_queue_set_deadline (queue, 2, 4 * GST_SECOND, 0);
155 next = (RtpTimer *) timer->list.next;
156 prev = (RtpTimer *) timer->list.prev;
157 fail_if (prev == NULL);
158 fail_unless (next == NULL);
159 fail_unless_equals_int (0, prev->seqnum);
160
161 /* move tail back */
162 rtp_timer_queue_set_deadline (queue, 2, 3 * GST_SECOND, 0);
163 next = (RtpTimer *) timer->list.next;
164 prev = (RtpTimer *) timer->list.prev;
165 fail_if (prev == NULL);
166 fail_if (next == NULL);
167 fail_unless_equals_int (1, prev->seqnum);
168 fail_unless_equals_int (0, next->seqnum);
169
170 /* not moving toward head */
171 rtp_timer_queue_set_deadline (queue, 2, 2 * GST_SECOND, 0);
172 next = (RtpTimer *) timer->list.next;
173 prev = (RtpTimer *) timer->list.prev;
174 fail_if (prev == NULL);
175 fail_if (next == NULL);
176 fail_unless_equals_int (1, prev->seqnum);
177 fail_unless_equals_int (0, next->seqnum);
178
179 /* not moving toward tail */
180 rtp_timer_queue_set_deadline (queue, 2, 3 * GST_SECOND, 0);
181 next = (RtpTimer *) timer->list.next;
182 prev = (RtpTimer *) timer->list.prev;
183 fail_if (prev == NULL);
184 fail_if (next == NULL);
185 fail_unless_equals_int (1, prev->seqnum);
186 fail_unless_equals_int (0, next->seqnum);
187
188 /* inner move toward head */
189 rtp_timer_queue_set_deadline (queue, 2, GST_SECOND + GST_SECOND / 2, 0);
190 next = (RtpTimer *) timer->list.next;
191 prev = (RtpTimer *) timer->list.prev;
192 fail_if (prev == NULL);
193 fail_if (next == NULL);
194 fail_unless_equals_int (3, prev->seqnum);
195 fail_unless_equals_int (1, next->seqnum);
196
197 /* inner move toward tail */
198 rtp_timer_queue_set_deadline (queue, 2, 3 * GST_SECOND, 0);
199 next = (RtpTimer *) timer->list.next;
200 prev = (RtpTimer *) timer->list.prev;
201 fail_if (prev == NULL);
202 fail_if (next == NULL);
203 fail_unless_equals_int (1, prev->seqnum);
204 fail_unless_equals_int (0, next->seqnum);
205
206 g_object_unref (queue);
207 }
208
209 GST_END_TEST;
210
GST_START_TEST(test_timer_queue_pop_until)211 GST_START_TEST (test_timer_queue_pop_until)
212 {
213 RtpTimerQueue *queue = rtp_timer_queue_new ();
214 RtpTimer *timer;
215
216 rtp_timer_queue_set_deadline (queue, 2, 2 * GST_SECOND, 0);
217 rtp_timer_queue_set_deadline (queue, 1, 1 * GST_SECOND, 0);
218 rtp_timer_queue_set_deadline (queue, 0, -1, 0);
219
220 timer = rtp_timer_queue_pop_until (queue, 1 * GST_SECOND);
221 fail_if (timer == NULL);
222 fail_unless_equals_int (0, timer->seqnum);
223 rtp_timer_free (timer);
224
225 timer = rtp_timer_queue_pop_until (queue, 1 * GST_SECOND);
226 fail_if (timer == NULL);
227 fail_unless_equals_int (1, timer->seqnum);
228 rtp_timer_free (timer);
229
230 timer = rtp_timer_queue_pop_until (queue, 1 * GST_SECOND);
231 fail_unless (timer == NULL);
232
233 g_object_unref (queue);
234 }
235
236 GST_END_TEST;
237
GST_START_TEST(test_timer_queue_update_timer_seqnum)238 GST_START_TEST (test_timer_queue_update_timer_seqnum)
239 {
240 RtpTimerQueue *queue = rtp_timer_queue_new ();
241 RtpTimer *timer;
242
243 rtp_timer_queue_set_deadline (queue, 2, 2 * GST_SECOND, 0);
244
245 timer = rtp_timer_queue_find (queue, 2);
246 fail_if (timer == NULL);
247
248 rtp_timer_queue_update_timer (queue, timer, 3, 3 * GST_SECOND, 0, 0, FALSE);
249
250 timer = rtp_timer_queue_find (queue, 2);
251 fail_unless (timer == NULL);
252 timer = rtp_timer_queue_find (queue, 3);
253 fail_if (timer == NULL);
254
255 fail_unless_equals_int (1, rtp_timer_queue_length (queue));
256
257 g_object_unref (queue);
258 }
259
260 GST_END_TEST;
261
GST_START_TEST(test_timer_queue_dup_timer)262 GST_START_TEST (test_timer_queue_dup_timer)
263 {
264 RtpTimerQueue *queue = rtp_timer_queue_new ();
265 RtpTimer *timer;
266
267 rtp_timer_queue_set_deadline (queue, 2, 2 * GST_SECOND, 0);
268
269 timer = rtp_timer_queue_find (queue, 2);
270 fail_if (timer == NULL);
271
272 timer = rtp_timer_dup (timer);
273 timer->seqnum = 3;
274 rtp_timer_queue_insert (queue, timer);
275
276 fail_unless_equals_int (2, rtp_timer_queue_length (queue));
277
278 g_object_unref (queue);
279 }
280
281 GST_END_TEST;
282
GST_START_TEST(test_timer_queue_timer_offset)283 GST_START_TEST (test_timer_queue_timer_offset)
284 {
285 RtpTimerQueue *queue = rtp_timer_queue_new ();
286 RtpTimer *timer;
287
288 rtp_timer_queue_set_timer (queue, RTP_TIMER_EXPECTED, 2, 2 * GST_SECOND,
289 GST_MSECOND, 0, GST_USECOND);
290
291 timer = rtp_timer_queue_find (queue, 2);
292 fail_if (timer == NULL);
293 fail_unless_equals_uint64 (2 * GST_SECOND + GST_MSECOND + GST_USECOND,
294 timer->timeout);
295 fail_unless_equals_int64 (GST_USECOND, timer->offset);
296
297 rtp_timer_queue_update_timer (queue, timer, 2, 3 * GST_SECOND,
298 2 * GST_MSECOND, 2 * GST_USECOND, FALSE);
299 fail_unless_equals_uint64 (3 * GST_SECOND + 2 * GST_MSECOND +
300 2 * GST_USECOND, timer->timeout);
301 fail_unless_equals_int64 (2 * GST_USECOND, timer->offset);
302
303 g_object_unref (queue);
304 }
305
306 GST_END_TEST;
307
308 static Suite *
rtptimerqueue_suite(void)309 rtptimerqueue_suite (void)
310 {
311 Suite *s = suite_create ("rtptimerqueue");
312 TCase *tc_chain = tcase_create ("general");
313
314 suite_add_tcase (s, tc_chain);
315 tcase_add_test (tc_chain, test_timer_queue_set_timer);
316 tcase_add_test (tc_chain, test_timer_queue_insert_head);
317 tcase_add_test (tc_chain, test_timer_queue_reschedule);
318 tcase_add_test (tc_chain, test_timer_queue_pop_until);
319 tcase_add_test (tc_chain, test_timer_queue_update_timer_seqnum);
320 tcase_add_test (tc_chain, test_timer_queue_dup_timer);
321 tcase_add_test (tc_chain, test_timer_queue_timer_offset);
322
323 return s;
324 }
325
326 GST_CHECK_MAIN (rtptimerqueue);
327