1 /*
2 * GStreamer AVTP Plugin
3 * Copyright (C) 2019 Intel Corporation
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later
9 * 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 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA
20 */
21 #include "../../../ext/avtp/gstavtpcrfbase.c"
22 #undef GST_CAT_DEFAULT
23
24 #include <glib.h>
25 #include <avtp_crf.h>
26 #include <gst/check/gstcheck.h>
27 #include <gst/check/gstharness.h>
28
29 static struct avtp_crf_pdu *
generate_crf_pdu(int data_len,guint64 first_tstamp)30 generate_crf_pdu (int data_len, guint64 first_tstamp)
31 {
32 const guint64 base_freq = 48000;
33 const guint64 interval = 160;
34 const gdouble interval_time = 1.0e9 / base_freq * interval;
35
36 struct avtp_crf_pdu *crf_pdu =
37 g_malloc0 (sizeof (struct avtp_crf_pdu) + data_len);
38
39 avtp_crf_pdu_init (crf_pdu);
40 avtp_crf_pdu_set (crf_pdu, AVTP_CRF_FIELD_SV, 1);
41 avtp_crf_pdu_set (crf_pdu, AVTP_CRF_FIELD_STREAM_ID, 0xABCD1234ABCD1234);
42 avtp_crf_pdu_set (crf_pdu, AVTP_CRF_FIELD_TYPE, AVTP_CRF_TYPE_AUDIO_SAMPLE);
43 avtp_crf_pdu_set (crf_pdu, AVTP_CRF_FIELD_BASE_FREQ, base_freq);
44 avtp_crf_pdu_set (crf_pdu, AVTP_CRF_FIELD_PULL, 1);
45 avtp_crf_pdu_set (crf_pdu, AVTP_CRF_FIELD_CRF_DATA_LEN, data_len);
46 avtp_crf_pdu_set (crf_pdu, AVTP_CRF_FIELD_TIMESTAMP_INTERVAL, interval);
47 for (int i = 0; i < data_len / 8; i++) {
48 const guint64 offset = i * interval_time;
49 crf_pdu->crf_data[i] = htobe64 (first_tstamp + offset);
50 }
51
52 return crf_pdu;
53 }
54
GST_START_TEST(test_validate_crf_pdu_success)55 GST_START_TEST (test_validate_crf_pdu_success)
56 {
57 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
58 struct avtp_crf_pdu *crf_pdu = generate_crf_pdu (64, 1000);
59 GstAvtpCrfThreadData *thread_data = &avtpcrfbase->thread_data;
60 gboolean ret;
61
62 avtpcrfbase->streamid = 0xABCD1234ABCD1234;
63
64 ret =
65 validate_crf_pdu (avtpcrfbase, crf_pdu,
66 sizeof (struct avtp_crf_pdu) + 64);
67 fail_unless (ret == TRUE);
68
69 /* Validate thread_data fields. */
70 fail_unless (thread_data->base_freq == 48000);
71 fail_unless (thread_data->pull == 1);
72 fail_unless (thread_data->type == AVTP_CRF_TYPE_AUDIO_SAMPLE);
73 fail_unless (thread_data->mr == 0);
74 fail_unless (thread_data->timestamp_interval == 160);
75
76 g_free (crf_pdu);
77 gst_object_unref (avtpcrfbase);
78 }
79
80 GST_END_TEST;
81
GST_START_TEST(test_validate_crf_pdu_multiple_packets_success)82 GST_START_TEST (test_validate_crf_pdu_multiple_packets_success)
83 {
84 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
85 struct avtp_crf_pdu *crf_pdu1 = generate_crf_pdu (64, 1000);
86 struct avtp_crf_pdu *crf_pdu2 = generate_crf_pdu (64, 1800);
87 GstAvtpCrfThreadData *thread_data = &avtpcrfbase->thread_data;
88 gboolean ret;
89
90 avtpcrfbase->streamid = 0xABCD1234ABCD1234;
91
92 ret =
93 validate_crf_pdu (avtpcrfbase, crf_pdu1,
94 sizeof (struct avtp_crf_pdu) + 64);
95 fail_unless (ret == TRUE);
96
97 /* Validate thread_data fields. */
98 fail_unless (thread_data->base_freq == 48000);
99 fail_unless (thread_data->pull == 1);
100 fail_unless (thread_data->type == AVTP_CRF_TYPE_AUDIO_SAMPLE);
101 fail_unless (thread_data->mr == 0);
102 fail_unless (thread_data->timestamp_interval == 160);
103
104 ret =
105 validate_crf_pdu (avtpcrfbase, crf_pdu2,
106 sizeof (struct avtp_crf_pdu) + 64);
107 fail_unless (ret == TRUE);
108
109 g_free (crf_pdu1);
110 g_free (crf_pdu2);
111 gst_object_unref (avtpcrfbase);
112 }
113
114 GST_END_TEST;
115
GST_START_TEST(test_validate_crf_pdu_wrong_subtype)116 GST_START_TEST (test_validate_crf_pdu_wrong_subtype)
117 {
118 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
119 struct avtp_crf_pdu *crf_pdu = generate_crf_pdu (64, 1000);
120 gboolean ret;
121
122 avtpcrfbase->streamid = 0xABCD1234ABCD1234;
123
124 avtp_pdu_set ((struct avtp_common_pdu *) crf_pdu, AVTP_FIELD_SUBTYPE,
125 AVTP_SUBTYPE_CVF);
126
127 ret =
128 validate_crf_pdu (avtpcrfbase, crf_pdu,
129 sizeof (struct avtp_crf_pdu) + 64);
130 fail_unless (ret == FALSE);
131
132 g_free (crf_pdu);
133 gst_object_unref (avtpcrfbase);
134 }
135
136 GST_END_TEST;
137
GST_START_TEST(test_validate_crf_pdu_streamid_invalid)138 GST_START_TEST (test_validate_crf_pdu_streamid_invalid)
139 {
140 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
141 struct avtp_crf_pdu *crf_pdu = generate_crf_pdu (64, 1000);
142 gboolean ret;
143
144 avtpcrfbase->streamid = 0xABCD1234ABCD1234;
145
146 avtp_crf_pdu_set (crf_pdu, AVTP_CRF_FIELD_SV, 0);
147
148 ret =
149 validate_crf_pdu (avtpcrfbase, crf_pdu,
150 sizeof (struct avtp_crf_pdu) + 64);
151 fail_unless (ret == FALSE);
152
153 g_free (crf_pdu);
154 gst_object_unref (avtpcrfbase);
155 }
156
157 GST_END_TEST;
158
GST_START_TEST(test_validate_crf_pdu_streamid_different)159 GST_START_TEST (test_validate_crf_pdu_streamid_different)
160 {
161 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
162 struct avtp_crf_pdu *crf_pdu = generate_crf_pdu (64, 1000);
163 gboolean ret;
164
165 avtpcrfbase->streamid = 0xABCD1234ABCDABCD;
166
167 ret =
168 validate_crf_pdu (avtpcrfbase, crf_pdu,
169 sizeof (struct avtp_crf_pdu) + 64);
170 fail_unless (ret == FALSE);
171
172 g_free (crf_pdu);
173 gst_object_unref (avtpcrfbase);
174 }
175
176 GST_END_TEST;
177
GST_START_TEST(test_validate_crf_pdu_data_len_too_long)178 GST_START_TEST (test_validate_crf_pdu_data_len_too_long)
179 {
180 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
181 struct avtp_crf_pdu *crf_pdu = generate_crf_pdu (64, 1000);
182 gboolean ret;
183
184 avtpcrfbase->streamid = 0xABCD1234ABCD1234;
185
186 ret =
187 validate_crf_pdu (avtpcrfbase, crf_pdu,
188 sizeof (struct avtp_crf_pdu) + 40);
189 fail_unless (ret == FALSE);
190
191 g_free (crf_pdu);
192 gst_object_unref (avtpcrfbase);
193 }
194
195 GST_END_TEST;
196
GST_START_TEST(test_validate_crf_pdu_timestamp_interval_zero)197 GST_START_TEST (test_validate_crf_pdu_timestamp_interval_zero)
198 {
199 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
200 struct avtp_crf_pdu *crf_pdu = generate_crf_pdu (64, 1000);
201 gboolean ret;
202
203 avtpcrfbase->streamid = 0xABCD1234ABCD1234;
204
205 avtp_crf_pdu_set (crf_pdu, AVTP_CRF_FIELD_TIMESTAMP_INTERVAL, 0);
206
207 ret =
208 validate_crf_pdu (avtpcrfbase, crf_pdu,
209 sizeof (struct avtp_crf_pdu) + 64);
210 fail_unless (ret == FALSE);
211
212 g_free (crf_pdu);
213 gst_object_unref (avtpcrfbase);
214 }
215
216 GST_END_TEST;
217
GST_START_TEST(test_validate_crf_pdu_base_freq_zero)218 GST_START_TEST (test_validate_crf_pdu_base_freq_zero)
219 {
220 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
221 struct avtp_crf_pdu *crf_pdu = generate_crf_pdu (64, 1000);
222 gboolean ret;
223
224 avtpcrfbase->streamid = 0xABCD1234ABCD1234;
225
226 avtp_crf_pdu_set (crf_pdu, AVTP_CRF_FIELD_BASE_FREQ, 0);
227
228 ret =
229 validate_crf_pdu (avtpcrfbase, crf_pdu,
230 sizeof (struct avtp_crf_pdu) + 64);
231 fail_unless (ret == FALSE);
232
233 g_free (crf_pdu);
234 gst_object_unref (avtpcrfbase);
235 }
236
237 GST_END_TEST;
238
GST_START_TEST(test_validate_crf_pdu_pull_invalid)239 GST_START_TEST (test_validate_crf_pdu_pull_invalid)
240 {
241 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
242 struct avtp_crf_pdu *crf_pdu = generate_crf_pdu (64, 1000);
243 gboolean ret;
244
245 avtpcrfbase->streamid = 0xABCD1234ABCD1234;
246
247 avtp_crf_pdu_set (crf_pdu, AVTP_CRF_FIELD_PULL, 7);
248
249 ret =
250 validate_crf_pdu (avtpcrfbase, crf_pdu,
251 sizeof (struct avtp_crf_pdu) + 64);
252 fail_unless (ret == FALSE);
253
254 g_free (crf_pdu);
255 gst_object_unref (avtpcrfbase);
256 }
257
258 GST_END_TEST;
259
GST_START_TEST(test_validate_crf_pdu_type_invalid)260 GST_START_TEST (test_validate_crf_pdu_type_invalid)
261 {
262 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
263 struct avtp_crf_pdu *crf_pdu = generate_crf_pdu (64, 1000);
264 gboolean ret;
265
266 avtpcrfbase->streamid = 0xABCD1234ABCD1234;
267
268 avtp_crf_pdu_set (crf_pdu, AVTP_CRF_FIELD_TYPE, 8);
269
270 ret =
271 validate_crf_pdu (avtpcrfbase, crf_pdu,
272 sizeof (struct avtp_crf_pdu) + 64);
273 fail_unless (ret == FALSE);
274
275 g_free (crf_pdu);
276 gst_object_unref (avtpcrfbase);
277 }
278
279 GST_END_TEST;
280
GST_START_TEST(test_validate_crf_pdu_data_len_invalid)281 GST_START_TEST (test_validate_crf_pdu_data_len_invalid)
282 {
283 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
284 struct avtp_crf_pdu *crf_pdu = generate_crf_pdu (64, 1000);
285 gboolean ret;
286
287 avtpcrfbase->streamid = 0xABCD1234ABCD1234;
288
289 avtp_crf_pdu_set (crf_pdu, AVTP_CRF_FIELD_CRF_DATA_LEN, 20);
290
291 ret =
292 validate_crf_pdu (avtpcrfbase, crf_pdu,
293 sizeof (struct avtp_crf_pdu) + 64);
294 fail_unless (ret == FALSE);
295
296 g_free (crf_pdu);
297 gst_object_unref (avtpcrfbase);
298 }
299
300 GST_END_TEST;
301
GST_START_TEST(test_validate_crf_pdu_timestamp_interval_mismatch)302 GST_START_TEST (test_validate_crf_pdu_timestamp_interval_mismatch)
303 {
304 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
305 struct avtp_crf_pdu *crf_pdu = generate_crf_pdu (64, 1000);
306 GstAvtpCrfThreadData *thread_data = &avtpcrfbase->thread_data;
307 gboolean ret;
308
309 avtpcrfbase->streamid = 0xABCD1234ABCD1234;
310 thread_data->timestamp_interval = 120;
311 thread_data->base_freq = 48000;
312 thread_data->pull = 1;
313 thread_data->type = AVTP_CRF_TYPE_AUDIO_SAMPLE;
314 thread_data->num_pkt_tstamps = 8;
315
316 ret =
317 validate_crf_pdu (avtpcrfbase, crf_pdu,
318 sizeof (struct avtp_crf_pdu) + 64);
319 fail_unless (ret == FALSE);
320
321 g_free (crf_pdu);
322 gst_object_unref (avtpcrfbase);
323 }
324
325 GST_END_TEST;
326
GST_START_TEST(test_validate_crf_pdu_base_freq_mismatch)327 GST_START_TEST (test_validate_crf_pdu_base_freq_mismatch)
328 {
329 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
330 struct avtp_crf_pdu *crf_pdu = generate_crf_pdu (64, 1000);
331 GstAvtpCrfThreadData *thread_data = &avtpcrfbase->thread_data;
332 gboolean ret;
333
334 avtpcrfbase->streamid = 0xABCD1234ABCD1234;
335 thread_data->timestamp_interval = 160;
336 thread_data->base_freq = 44100;
337 thread_data->pull = 1;
338 thread_data->type = AVTP_CRF_TYPE_AUDIO_SAMPLE;
339 thread_data->num_pkt_tstamps = 8;
340
341 ret =
342 validate_crf_pdu (avtpcrfbase, crf_pdu,
343 sizeof (struct avtp_crf_pdu) + 64);
344 fail_unless (ret == FALSE);
345
346 g_free (crf_pdu);
347 gst_object_unref (avtpcrfbase);
348 }
349
350 GST_END_TEST;
351
GST_START_TEST(test_validate_crf_pdu_pull_mismatch)352 GST_START_TEST (test_validate_crf_pdu_pull_mismatch)
353 {
354 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
355 struct avtp_crf_pdu *crf_pdu = generate_crf_pdu (64, 1000);
356 GstAvtpCrfThreadData *thread_data = &avtpcrfbase->thread_data;
357 gboolean ret;
358
359 avtpcrfbase->streamid = 0xABCD1234ABCD1234;
360 thread_data->timestamp_interval = 160;
361 thread_data->base_freq = 48000;
362 thread_data->pull = 2;
363 thread_data->type = AVTP_CRF_TYPE_AUDIO_SAMPLE;
364 thread_data->num_pkt_tstamps = 8;
365
366 ret =
367 validate_crf_pdu (avtpcrfbase, crf_pdu,
368 sizeof (struct avtp_crf_pdu) + 64);
369 fail_unless (ret == FALSE);
370
371 g_free (crf_pdu);
372 gst_object_unref (avtpcrfbase);
373 }
374
375 GST_END_TEST;
376
GST_START_TEST(test_validate_crf_pdu_type_mismatch)377 GST_START_TEST (test_validate_crf_pdu_type_mismatch)
378 {
379 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
380 struct avtp_crf_pdu *crf_pdu = generate_crf_pdu (64, 1000);
381 GstAvtpCrfThreadData *thread_data = &avtpcrfbase->thread_data;
382 gboolean ret;
383
384 avtpcrfbase->streamid = 0xABCD1234ABCD1234;
385 thread_data->timestamp_interval = 160;
386 thread_data->base_freq = 48000;
387 thread_data->pull = 1;
388 thread_data->type = AVTP_CRF_TYPE_VIDEO_FRAME;
389 thread_data->num_pkt_tstamps = 8;
390
391 ret =
392 validate_crf_pdu (avtpcrfbase, crf_pdu,
393 sizeof (struct avtp_crf_pdu) + 64);
394 fail_unless (ret == FALSE);
395
396 g_free (crf_pdu);
397 gst_object_unref (avtpcrfbase);
398 }
399
400 GST_END_TEST;
401
GST_START_TEST(test_validate_crf_pdu_data_len_mismatch)402 GST_START_TEST (test_validate_crf_pdu_data_len_mismatch)
403 {
404 int data_len = 48;
405 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
406 struct avtp_crf_pdu *crf_pdu = generate_crf_pdu (data_len, 1000);
407 GstAvtpCrfThreadData *thread_data = &avtpcrfbase->thread_data;
408 gboolean ret;
409
410 avtpcrfbase->streamid = 0xABCD1234ABCD1234;
411 thread_data->timestamp_interval = 160;
412 thread_data->base_freq = 48000;
413 thread_data->pull = 1;
414 thread_data->type = AVTP_CRF_TYPE_AUDIO_SAMPLE;
415 thread_data->num_pkt_tstamps = 6;
416
417 avtp_crf_pdu_set (crf_pdu, AVTP_CRF_FIELD_CRF_DATA_LEN, 20);
418
419 ret =
420 validate_crf_pdu (avtpcrfbase, crf_pdu,
421 sizeof (struct avtp_crf_pdu) + data_len);
422 fail_unless (ret == FALSE);
423
424 g_free (crf_pdu);
425 gst_object_unref (avtpcrfbase);
426 }
427
428 GST_END_TEST;
429
GST_START_TEST(test_validate_crf_pdu_tstamps_not_monotonic)430 GST_START_TEST (test_validate_crf_pdu_tstamps_not_monotonic)
431 {
432 int data_len = 48;
433 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
434 struct avtp_crf_pdu *crf_pdu = generate_crf_pdu (data_len, 1000);
435 GstAvtpCrfThreadData *thread_data = &avtpcrfbase->thread_data;
436 gboolean ret;
437
438 avtpcrfbase->streamid = 0xABCD1234ABCD1234;
439 thread_data->timestamp_interval = 160;
440 thread_data->base_freq = 48000;
441 thread_data->pull = 1;
442 thread_data->type = AVTP_CRF_TYPE_AUDIO_SAMPLE;
443 thread_data->num_pkt_tstamps = 6;
444
445 crf_pdu->crf_data[3] = 1145;
446
447 ret =
448 validate_crf_pdu (avtpcrfbase, crf_pdu,
449 sizeof (struct avtp_crf_pdu) + data_len);
450 fail_unless (ret == FALSE);
451
452 g_free (crf_pdu);
453 gst_object_unref (avtpcrfbase);
454 }
455
456 GST_END_TEST;
457
GST_START_TEST(test_gst_base_freq_multiplier)458 GST_START_TEST (test_gst_base_freq_multiplier)
459 {
460 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
461 gdouble ret;
462
463 ret = get_base_freq_multiplier (avtpcrfbase, 0);
464 fail_unless_equals_float (ret, 1.0);
465
466 ret = get_base_freq_multiplier (avtpcrfbase, 1);
467 fail_unless_equals_float (ret, 1 / 1.001);
468
469 ret = get_base_freq_multiplier (avtpcrfbase, 2);
470 fail_unless_equals_float (ret, 1.001);
471
472 ret = get_base_freq_multiplier (avtpcrfbase, 3);
473 fail_unless_equals_float (ret, 24.0 / 25);
474
475 ret = get_base_freq_multiplier (avtpcrfbase, 4);
476 fail_unless_equals_float (ret, 25.0 / 24);
477
478 ret = get_base_freq_multiplier (avtpcrfbase, 5);
479 fail_unless_equals_float (ret, 1.0 / 8);
480
481 ret = get_base_freq_multiplier (avtpcrfbase, 6);
482 fail_unless_equals_float (ret, -1);
483 gst_object_unref (avtpcrfbase);
484
485 }
486
487 GST_END_TEST;
488
489 static void
setup_thread_defaults(GstAvtpCrfBase * avtpcrfbase,gdouble * past_periods)490 setup_thread_defaults (GstAvtpCrfBase * avtpcrfbase, gdouble * past_periods)
491 {
492 GstAvtpCrfThreadData *thread_data = &avtpcrfbase->thread_data;
493
494 avtpcrfbase->streamid = 0xABCD1234ABCD1234;
495 thread_data->base_freq = 48000;
496 thread_data->pull = 1;
497 thread_data->type = AVTP_CRF_TYPE_AUDIO_SAMPLE;
498 thread_data->past_periods = past_periods;
499 }
500
501 /*
502 * Test for more than 1 timestamp per CRF AVTPDU. This is just a simple success
503 * case.
504 */
GST_START_TEST(test_calculate_average_period_multiple_crf_tstamps)505 GST_START_TEST (test_calculate_average_period_multiple_crf_tstamps)
506 {
507 int data_len = 64;
508 struct avtp_crf_pdu *crf_pdu = generate_crf_pdu (data_len, 1000);
509 gdouble past_periods[10] = { 21000, 20500, 0, 0, 0, 0, 0, 0, 0, 0 };
510 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
511 GstAvtpCrfThreadData *thread_data = &avtpcrfbase->thread_data;
512
513 setup_thread_defaults (avtpcrfbase, past_periods);
514
515 thread_data->timestamp_interval = 160;
516 thread_data->num_pkt_tstamps = 6;
517 thread_data->past_periods_iter = 2;
518 thread_data->periods_stored = 2;
519
520 calculate_average_period (avtpcrfbase, crf_pdu);
521 fail_unless_equals_float (thread_data->average_period, 20777.7775);
522 fail_unless_equals_float (thread_data->past_periods[2], 20833.3325);
523 fail_unless_equals_uint64 (thread_data->current_ts, 1000);
524
525 gst_object_unref (avtpcrfbase);
526 g_free (crf_pdu);
527 }
528
529 GST_END_TEST;
530
531 /*
532 * Test for rounding error
533 */
GST_START_TEST(test_calculate_average_period_rounding_error)534 GST_START_TEST (test_calculate_average_period_rounding_error)
535 {
536 /* the presentation time in ns */
537 const GstClockTimeDiff ptime = 50000000;
538 /* the time in ns of one sync event e.g. one audio sample @48kHz */
539 const gdouble event_interval = 1.0e9 / 48000;
540 /* the presentation time measured in sync events (e.g. sample rate)
541 * for class B traffic with a presentation time of 50ms.
542 */
543 const GstClockTime ptime_in_events = ptime / event_interval;
544
545 /* With 4 timestamps generate_crf_pdu() multiples the interval time
546 * with 3. This results into an integer time stamp in nsi without decimal
547 * digits. Therefore the rounding issue when generating the timestamps for
548 * the CRF PDU is avoided here.
549 */
550 int data_len = 32;
551 struct avtp_crf_pdu *crf_pdu = generate_crf_pdu (data_len, 1000);
552 gdouble past_periods[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
553 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
554 GstAvtpCrfThreadData *thread_data = &avtpcrfbase->thread_data;
555
556 setup_thread_defaults (avtpcrfbase, past_periods);
557
558 thread_data->timestamp_interval = 160;
559 thread_data->num_pkt_tstamps = data_len / sizeof (uint64_t);
560 thread_data->past_periods_iter = 0;
561 thread_data->periods_stored = 0;
562
563 calculate_average_period (avtpcrfbase, crf_pdu);
564
565 /* When internally using integer for average_period calculation the following
566 * multiplication will result to (20833 * 2400=) 49999200ns. This value
567 * differs by 800ns from the original presentation time of 50ms. When using
568 * double this rounding error is avoided.
569 */
570 fail_unless_equals_float ((thread_data->average_period * ptime_in_events),
571 ptime);
572
573 gst_object_unref (avtpcrfbase);
574 g_free (crf_pdu);
575 }
576
577 GST_END_TEST;
578
579 /*
580 * Test for an overflow in the 64-bit CRF timestamp in the CRF AVTPDU when
581 * there are multiple CRF timestamps in a packet.
582 */
GST_START_TEST(test_calculate_average_period_multiple_crf_tstamps_64_bit_overflow)583 GST_START_TEST
584 (test_calculate_average_period_multiple_crf_tstamps_64_bit_overflow) {
585 int data_len = 64;
586 struct avtp_crf_pdu *crf_pdu =
587 generate_crf_pdu (data_len, 18446744073709501615ULL);
588 gdouble past_periods[10] =
589 { 21000, 20500, 21220, 21345, 20990, 21996, 20220, 20915, 21324, 23123 };
590 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
591 GstAvtpCrfThreadData *thread_data = &avtpcrfbase->thread_data;
592
593 setup_thread_defaults (avtpcrfbase, past_periods);
594
595 thread_data->timestamp_interval = 160;
596 thread_data->num_pkt_tstamps = 6;
597 thread_data->past_periods_iter = 5;
598 thread_data->periods_stored = 10;
599
600 calculate_average_period (avtpcrfbase, crf_pdu);
601 fail_unless_equals_float (thread_data->average_period, 21147.03325);
602 fail_unless_equals_float (thread_data->past_periods[5], 20833.3325);
603 fail_unless_equals_uint64 (thread_data->current_ts, 18446744073709501615ULL);
604
605 g_free (crf_pdu);
606 gst_object_unref (avtpcrfbase);
607 }
608
609 GST_END_TEST;
610
611 /*
612 * Test case for single timestamp per CRF AVTPDU. This is just a simple success
613 * case.
614 */
GST_START_TEST(test_calculate_average_period_single_crf_tstamp)615 GST_START_TEST (test_calculate_average_period_single_crf_tstamp)
616 {
617 int data_len = 8;
618 struct avtp_crf_pdu *crf_pdu = generate_crf_pdu (data_len, 21833);
619 gdouble past_periods[10] = { 21000, 20500, 0, 0, 0, 0, 0, 0, 0, 0 };
620 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
621 GstAvtpCrfThreadData *thread_data = &avtpcrfbase->thread_data;
622
623 setup_thread_defaults (avtpcrfbase, past_periods);
624
625 thread_data->timestamp_interval = 1;
626 thread_data->num_pkt_tstamps = 1;
627 thread_data->past_periods_iter = 2;
628 thread_data->periods_stored = 2;
629 thread_data->last_received_tstamp = 1000;
630 thread_data->last_seqnum = 9;
631
632 avtp_crf_pdu_set (crf_pdu, AVTP_CRF_FIELD_SEQ_NUM, 10);
633
634 calculate_average_period (avtpcrfbase, crf_pdu);
635 fail_unless_equals_float (thread_data->average_period, 20777.6666666);
636 fail_unless_equals_float (thread_data->past_periods[2], 20833);
637 fail_unless_equals_uint64 (thread_data->last_seqnum, 10);
638 fail_unless_equals_uint64 (thread_data->last_received_tstamp, 21833);
639 fail_unless_equals_uint64 (thread_data->current_ts, 21833);
640
641 g_free (crf_pdu);
642 gst_object_unref (avtpcrfbase);
643 }
644
645 GST_END_TEST;
646
647 /*
648 * Test to ensure all members of thread_data struct are initialized as expected
649 * when receiving multiple CRF AVTPDUs with single CRF timestamp.
650 */
GST_START_TEST(test_calculate_average_period_single_crf_tstamp_init)651 GST_START_TEST (test_calculate_average_period_single_crf_tstamp_init)
652 {
653 int data_len = 8;
654 struct avtp_crf_pdu *crf_pdu1 = generate_crf_pdu (data_len, 1000);
655 struct avtp_crf_pdu *crf_pdu2 = generate_crf_pdu (data_len, 21833);
656 gdouble past_periods[10] = { 0 };
657 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
658 GstAvtpCrfThreadData *thread_data = &avtpcrfbase->thread_data;
659
660 setup_thread_defaults (avtpcrfbase, past_periods);
661
662 thread_data->timestamp_interval = 1;
663 thread_data->num_pkt_tstamps = 1;
664
665 avtp_crf_pdu_set (crf_pdu1, AVTP_CRF_FIELD_SEQ_NUM, 10);
666 avtp_crf_pdu_set (crf_pdu2, AVTP_CRF_FIELD_SEQ_NUM, 11);
667
668 calculate_average_period (avtpcrfbase, crf_pdu1);
669 fail_unless_equals_float (thread_data->past_periods[0], 0);
670 fail_unless_equals_uint64 (thread_data->last_seqnum, 10);
671 fail_unless_equals_float (thread_data->average_period, 20854);
672 fail_unless_equals_uint64 (thread_data->current_ts, 1000);
673
674 calculate_average_period (avtpcrfbase, crf_pdu2);
675 fail_unless_equals_float (thread_data->past_periods[0], 20833);
676 fail_unless_equals_uint64 (thread_data->last_seqnum, 11);
677 fail_unless_equals_float (thread_data->average_period, 20833);
678 fail_unless_equals_uint64 (thread_data->current_ts, 21833);
679
680 g_free (crf_pdu1);
681 g_free (crf_pdu2);
682 gst_object_unref (avtpcrfbase);
683 }
684
685 GST_END_TEST;
686
687 /*
688 * Test to ensure average_period is calculated correctly
689 * when receiving multiple CRF AVTPDUs with single CRF timestamp
690 * with timestamp_interval > 1
691 */
GST_START_TEST(test_calculate_average_period_single_crf_tstamp_interval)692 GST_START_TEST (test_calculate_average_period_single_crf_tstamp_interval)
693 {
694 int data_len = 8;
695 struct avtp_crf_pdu *crf_pdu1 = generate_crf_pdu (data_len, 1000);
696 /* Used timestamp
697 * = sample_time * timestamp_interval + first_tstamp
698 * = 1/48kHz * 160 + 1000
699 */
700 struct avtp_crf_pdu *crf_pdu2 = generate_crf_pdu (data_len, 3334280);
701 gdouble past_periods[10] = { 0 };
702 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
703 GstAvtpCrfThreadData *thread_data = &avtpcrfbase->thread_data;
704
705 setup_thread_defaults (avtpcrfbase, past_periods);
706
707 thread_data->timestamp_interval = 160;
708 thread_data->num_pkt_tstamps = 1;
709
710 avtp_crf_pdu_set (crf_pdu1, AVTP_CRF_FIELD_SEQ_NUM, 10);
711 avtp_crf_pdu_set (crf_pdu2, AVTP_CRF_FIELD_SEQ_NUM, 11);
712
713 calculate_average_period (avtpcrfbase, crf_pdu1);
714 fail_unless_equals_float (thread_data->past_periods[0], 0);
715 fail_unless_equals_uint64 (thread_data->last_seqnum, 10);
716 fail_unless_equals_float (thread_data->average_period, 20854);
717 fail_unless_equals_uint64 (thread_data->current_ts, 1000);
718
719 calculate_average_period (avtpcrfbase, crf_pdu2);
720 fail_unless_equals_float (thread_data->past_periods[0], 20833);
721 fail_unless_equals_uint64 (thread_data->last_seqnum, 11);
722 fail_unless_equals_float (thread_data->average_period, 20833);
723 fail_unless_equals_uint64 (thread_data->current_ts, 3334280);
724
725 g_free (crf_pdu1);
726 g_free (crf_pdu2);
727 gst_object_unref (avtpcrfbase);
728 }
729
730 GST_END_TEST;
731
732 /*
733 * Test for an overflow in the 64-bit CRF timestamp in the CRF AVTPDU when
734 * there is a single CRF timestamp in a packet.
735 */
GST_START_TEST(test_calculate_average_period_single_crf_tstamp_64_bit_overflow)736 GST_START_TEST (test_calculate_average_period_single_crf_tstamp_64_bit_overflow)
737 {
738 int data_len = 8;
739 struct avtp_crf_pdu *crf_pdu = generate_crf_pdu (data_len, 20833);
740 gdouble past_periods[10] = { 21000, 20500, 0, 0, 0, 0, 0, 0, 0, 0 };
741 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
742 GstAvtpCrfThreadData *thread_data = &avtpcrfbase->thread_data;
743
744 setup_thread_defaults (avtpcrfbase, past_periods);
745
746 thread_data->timestamp_interval = 1;
747 thread_data->num_pkt_tstamps = 1;
748 thread_data->past_periods_iter = 2;
749 thread_data->periods_stored = 2;
750 thread_data->last_received_tstamp = 18446744073709551615ULL;
751 thread_data->last_seqnum = 9;
752
753 avtp_crf_pdu_set (crf_pdu, AVTP_CRF_FIELD_SEQ_NUM, 10);
754
755 calculate_average_period (avtpcrfbase, crf_pdu);
756 fail_unless_equals_float (thread_data->average_period, 20778);
757 fail_unless_equals_float (thread_data->past_periods[2], 20834);
758 fail_unless_equals_uint64 (thread_data->last_seqnum, 10);
759 fail_unless_equals_uint64 (thread_data->last_received_tstamp, 20833);
760 fail_unless_equals_uint64 (thread_data->current_ts, 20833);
761
762 g_free (crf_pdu);
763 gst_object_unref (avtpcrfbase);
764 }
765
766 GST_END_TEST;
767
768 /*
769 * Test to ensure expected behevior when a sequence number is skipped (probably
770 * due to packet loss or delay) in CRF AVTPDUs with single timestamp per
771 * AVTPDU.
772 */
GST_START_TEST(test_calculate_average_period_single_crf_tstamp_seq_num_skip)773 GST_START_TEST (test_calculate_average_period_single_crf_tstamp_seq_num_skip)
774 {
775 int data_len = 8;
776 struct avtp_crf_pdu *crf_pdu = generate_crf_pdu (data_len, 21833);
777 gdouble past_periods[10] = { 21000, 20500, 0, 0, 0, 0, 0, 0, 0, 0 };
778 GstAvtpCrfBase *avtpcrfbase = g_object_new (GST_TYPE_AVTP_CRF_BASE, NULL);
779 GstAvtpCrfThreadData *thread_data = &avtpcrfbase->thread_data;
780
781 setup_thread_defaults (avtpcrfbase, past_periods);
782
783 thread_data->timestamp_interval = 1;
784 thread_data->num_pkt_tstamps = 1;
785 thread_data->past_periods_iter = 2;
786 thread_data->last_received_tstamp = 1000;
787 thread_data->last_seqnum = 9;
788 thread_data->average_period = 20750;
789
790 avtp_crf_pdu_set (crf_pdu, AVTP_CRF_FIELD_SEQ_NUM, 12);
791
792 calculate_average_period (avtpcrfbase, crf_pdu);
793 fail_unless_equals_float (thread_data->average_period, 20750);
794 fail_unless_equals_float (thread_data->past_periods[2], 0);
795 fail_unless_equals_uint64 (thread_data->last_seqnum, 12);
796 fail_unless_equals_uint64 (thread_data->last_received_tstamp, 21833);
797 fail_unless_equals_uint64 (thread_data->current_ts, 21833);
798
799 g_free (crf_pdu);
800 gst_object_unref (avtpcrfbase);
801 }
802
803 GST_END_TEST;
804
805 static Suite *
avtpcrfbase_suite(void)806 avtpcrfbase_suite (void)
807 {
808 Suite *s = suite_create ("avtpcrfbase");
809 TCase *tc_chain = tcase_create ("general");
810
811 GST_DEBUG_CATEGORY_INIT (avtpcrfbase_debug, "avtpcrfbase", 0, "CRF Base");
812
813 suite_add_tcase (s, tc_chain);
814 tcase_add_test (tc_chain, test_validate_crf_pdu_success);
815 tcase_add_test (tc_chain, test_validate_crf_pdu_multiple_packets_success);
816 tcase_add_test (tc_chain, test_validate_crf_pdu_wrong_subtype);
817 tcase_add_test (tc_chain, test_validate_crf_pdu_streamid_invalid);
818 tcase_add_test (tc_chain, test_validate_crf_pdu_streamid_different);
819 tcase_add_test (tc_chain, test_validate_crf_pdu_data_len_too_long);
820 tcase_add_test (tc_chain, test_validate_crf_pdu_timestamp_interval_zero);
821 tcase_add_test (tc_chain, test_validate_crf_pdu_base_freq_zero);
822 tcase_add_test (tc_chain, test_validate_crf_pdu_pull_invalid);
823 tcase_add_test (tc_chain, test_validate_crf_pdu_type_invalid);
824 tcase_add_test (tc_chain, test_validate_crf_pdu_data_len_invalid);
825 tcase_add_test (tc_chain, test_validate_crf_pdu_timestamp_interval_mismatch);
826 tcase_add_test (tc_chain, test_validate_crf_pdu_base_freq_mismatch);
827 tcase_add_test (tc_chain, test_validate_crf_pdu_pull_mismatch);
828 tcase_add_test (tc_chain, test_validate_crf_pdu_type_mismatch);
829 tcase_add_test (tc_chain, test_validate_crf_pdu_data_len_mismatch);
830 tcase_add_test (tc_chain, test_validate_crf_pdu_tstamps_not_monotonic);
831 tcase_add_test (tc_chain, test_gst_base_freq_multiplier);
832 tcase_add_test (tc_chain, test_calculate_average_period_multiple_crf_tstamps);
833 tcase_add_test (tc_chain, test_calculate_average_period_rounding_error);
834 tcase_add_test (tc_chain,
835 test_calculate_average_period_multiple_crf_tstamps_64_bit_overflow);
836 tcase_add_test (tc_chain, test_calculate_average_period_single_crf_tstamp);
837 tcase_add_test (tc_chain,
838 test_calculate_average_period_single_crf_tstamp_init);
839 tcase_add_test (tc_chain,
840 test_calculate_average_period_single_crf_tstamp_interval);
841 tcase_add_test (tc_chain,
842 test_calculate_average_period_single_crf_tstamp_64_bit_overflow);
843 tcase_add_test (tc_chain,
844 test_calculate_average_period_single_crf_tstamp_seq_num_skip);
845
846 return s;
847 }
848
849 GST_CHECK_MAIN (avtpcrfbase);
850