• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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