Add tests for main/jitterbuf.c
[asterisk/asterisk.git] / tests / test_jitterbuf.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2012, Matt Jordan
5  *
6  * Matt Jordan <mjordan@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*!
20  * \file
21  * \brief Unit tests for jitterbuf.c
22  *
23  * \author\verbatim Matt Jordan <mjordan@digium.com> \endverbatim
24  *
25  * \ingroup tests
26  */
27
28 /*** MODULEINFO
29         <depend>TEST_FRAMEWORK</depend>
30         <support_level>core</support_level>
31  ***/
32
33 #include "asterisk.h"
34
35 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
36
37 #include "asterisk/utils.h"
38 #include "asterisk/module.h"
39 #include "asterisk/test.h"
40 #include "jitterbuf.h"
41
42 #define DEFAULT_MAX_JITTERBUFFER 1000
43 #define DEFAULT_RESYNCH_THRESHOLD 1000
44 #define DEFAULT_MAX_CONTIG_INTERP 10
45 #define DEFAULT_TARGET_EXTRA -1
46 #define DEFAULT_CODEC_INTERP_LEN 20
47
48 /*! \internal
49  * Test two numeric (long int) values.  Failure automatically attempts
50  * to jump to a cleanup tag
51  */
52 #define JB_NUMERIC_TEST(attribute, expected) do { \
53         if ((attribute) != (expected)) { \
54                 ast_test_status_update(test, #attribute ": expected [%ld]; actual [%ld]\n", (long int)(expected), (attribute)); \
55                 goto cleanup; \
56         } \
57 } while (0)
58
59 /*! \internal
60  * Print out as debug the frame related contents of a jb_info object
61  */
62 #define JB_INFO_PRINT_FRAME_DEBUG(jbinfo) do { \
63         ast_debug(1, "JitterBuffer Frame Info:\n" \
64                 "\tFrames In: %ld\n\tFrames Out: %ld\n" \
65                 "\tDropped Frames: %ld\n\tLate Frames: %ld\n" \
66                 "\tLost Frames: %ld\n\tOut of Order Frames: %ld\n" \
67                 "\tCurrent Frame: %ld\n", jbinfo.frames_in, jbinfo.frames_out, \
68                 jbinfo.frames_dropped, jbinfo.frames_late, jbinfo.frames_lost, \
69                 jbinfo.frames_ooo, jbinfo.frames_cur); \
70 } while (0)
71
72 /*! \internal
73  * This macro installs the error, warning, and debug functions for a test.  It is
74  * expected that at the end of a test, the functions are removed.
75  * Note that the debug statement is in here merely to aid in tracing in a log where
76  * the jitter buffer debug output begins.
77  */
78 #define JB_TEST_BEGIN(test_name) do { \
79         jb_setoutput(test_jb_error_output, test_jb_warn_output, test_jb_debug_output); \
80         ast_debug(1, "Starting %s\n", test_name); \
81 } while (0)
82
83 /*! \internal
84  * Uninstall the error, warning, and debug functions from a test
85  */
86 #define JB_TEST_END do { \
87         jb_setoutput(NULL, NULL, NULL); \
88 } while (0)
89
90 static const char *jitter_buffer_return_codes[] = {
91         "JB_OK",            /* 0 */
92         "JB_EMPTY",         /* 1 */
93         "JB_NOFRAME",       /* 2 */
94         "JB_INTERP",        /* 3 */
95         "JB_DROP",          /* 4 */
96         "JB_SCHED"          /* 5 */
97 };
98
99 /*! \internal \brief Make a default jitter buffer configuration */
100 static void test_jb_populate_config(struct jb_conf *jbconf)
101 {
102         if (!jbconf) {
103                 return;
104         }
105
106         jbconf->max_jitterbuf = DEFAULT_MAX_JITTERBUFFER;
107         jbconf->resync_threshold = DEFAULT_RESYNCH_THRESHOLD;
108         jbconf->max_contig_interp = DEFAULT_MAX_CONTIG_INTERP;
109         jbconf->target_extra = 0;
110 }
111
112 /*! \internal \brief Debug callback function for the jitter buffer's jb_dbg function */
113 static void __attribute__((format(printf, 1, 2))) test_jb_debug_output(const char *fmt, ...)
114 {
115         va_list args;
116         char buf[1024];
117
118         va_start(args, fmt);
119         vsnprintf(buf, sizeof(buf), fmt, args);
120         va_end(args);
121
122         ast_debug(1, "%s", buf);
123 }
124
125 /*! \internal \brief Warning callback function for the jitter buffer's jb_warn function */
126 static void __attribute__((format(printf, 1, 2))) test_jb_warn_output(const char *fmt, ...)
127 {
128         va_list args;
129         char buf[1024];
130
131         va_start(args, fmt);
132         vsnprintf(buf, sizeof(buf), fmt, args);
133         va_end(args);
134
135         ast_log(AST_LOG_WARNING, "%s", buf);
136 }
137
138 /*! \internal \brief Error callback function for the jitter buffer's jb_err function */
139 static void __attribute__((format(printf, 1, 2))) test_jb_error_output(const char *fmt, ...)
140 {
141         va_list args;
142         char buf[1024];
143
144         va_start(args, fmt);
145         vsnprintf(buf, sizeof(buf), fmt, args);
146         va_end(args);
147
148         ast_log(AST_LOG_ERROR, "%s", buf);
149 }
150
151 /*! \internal \brief Insert frames into the jitter buffer for the nominal tests */
152 static int test_jb_nominal_frame_insertion(struct ast_test *test, struct jitterbuf *jb, enum jb_frame_type frame_type)
153 {
154         int i = 0, ret = 0;
155
156         for (i = 0; i < 40; i++) {
157                 if (jb_put(jb, NULL, frame_type, 20, i * 20, i * 20 + 5) == JB_DROP) {
158                         ast_test_status_update(test, "Jitter buffer dropped packet %d\n", i);
159                         ret = 1;
160                         break;
161                 }
162         }
163
164         return ret;
165 }
166
167 AST_TEST_DEFINE(jitterbuffer_nominal_voice_frames)
168 {
169         enum ast_test_result_state result = AST_TEST_FAIL;
170         struct jitterbuf *jb = NULL;
171         struct jb_frame frame;
172         struct jb_conf jbconf;
173         struct jb_info jbinfo;
174         int i = 0;
175
176         switch (cmd) {
177         case TEST_INIT:
178                 info->name = "jitterbuffer_nominal_voice_frames";
179                 info->category = "/main/jitterbuf/";
180                 info->summary = "Nominal operation of jitter buffer with audio data";
181                 info->description =
182                         "Tests the nominal case of putting audio data into a jitter buffer, "
183                         "retrieving the frames, and querying for the next frame";
184                 return AST_TEST_NOT_RUN;
185         case TEST_EXECUTE:
186                 break;
187         }
188
189         JB_TEST_BEGIN("jitterbuffer_nominal_voice_frames");
190
191         if (!(jb = jb_new())) {
192                 ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
193                 goto cleanup;
194         }
195
196         test_jb_populate_config(&jbconf);
197         if (jb_setconf(jb, &jbconf) != JB_OK) {
198                 ast_test_status_update(test, "Failed to set jitterbuffer configuration\n");
199                 goto cleanup;
200         }
201
202         if (test_jb_nominal_frame_insertion(test, jb, JB_TYPE_VOICE)) {
203                 goto cleanup;
204         }
205
206         for (i = 0; i < 40; i++) {
207                 enum jb_return_code ret;
208                 /* We should have a frame for each point in time */
209                 if ((ret = jb_get(jb, &frame, i * 20 + 5, DEFAULT_CODEC_INTERP_LEN)) != JB_OK) {
210                         ast_test_status_update(test,
211                                 "Unexpected jitter buffer return code [%s] when retrieving frame %d\n",
212                                 jitter_buffer_return_codes[ret], i);
213                         goto cleanup;
214                 }
215                 JB_NUMERIC_TEST(frame.ms, 20);
216                 JB_NUMERIC_TEST(frame.ts, i * 20 - jb->info.resync_offset);
217                 JB_NUMERIC_TEST(jb_next(jb), (i + 1) * 20 + 5);
218         }
219
220         result = AST_TEST_PASS;
221
222         if (jb_getinfo(jb, &jbinfo) != JB_OK) {
223                 ast_test_status_update(test, "Failed to get jitterbuffer information\n");
224                 goto cleanup;
225         }
226         JB_INFO_PRINT_FRAME_DEBUG(jbinfo);
227         JB_NUMERIC_TEST(jbinfo.frames_dropped, 0);
228         JB_NUMERIC_TEST(jbinfo.frames_in, 40);
229         JB_NUMERIC_TEST(jbinfo.frames_out, 40);
230         JB_NUMERIC_TEST(jbinfo.frames_late, 0);
231         JB_NUMERIC_TEST(jbinfo.frames_lost, 0);
232         JB_NUMERIC_TEST(jbinfo.frames_ooo, 0);
233
234 cleanup:
235         if (jb) {
236                 /* No need to do anything - this will put all frames on the 'free' list,
237                  * so jb_destroy will dispose of them */
238                 while (jb_getall(jb, &frame) == JB_OK) { }
239                 jb_destroy(jb);
240         }
241
242         JB_TEST_END;
243
244         return result;
245 }
246
247 AST_TEST_DEFINE(jitterbuffer_nominal_control_frames)
248 {
249         enum ast_test_result_state result = AST_TEST_FAIL;
250         struct jitterbuf *jb = NULL;
251         struct jb_frame frame;
252         struct jb_conf jbconf;
253         struct jb_info jbinfo;
254         int i = 0;
255
256         switch (cmd) {
257         case TEST_INIT:
258                 info->name = "jitterbuffer_nominal_control_frames";
259                 info->category = "/main/jitterbuf/";
260                 info->summary = "Nominal operation of jitter buffer with control frames";
261                 info->description =
262                         "Tests the nominal case of putting control frames into a jitter buffer, "
263                         "retrieving the frames, and querying for the next frame";
264                 return AST_TEST_NOT_RUN;
265         case TEST_EXECUTE:
266                 break;
267         }
268
269         JB_TEST_BEGIN("jitterbuffer_nominal_control_frames");
270
271         if (!(jb = jb_new())) {
272                 ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
273                 goto cleanup;
274         }
275
276         test_jb_populate_config(&jbconf);
277         if (jb_setconf(jb, &jbconf) != JB_OK) {
278                 ast_test_status_update(test, "Failed to set jitterbuffer configuration\n");
279                 goto cleanup;
280         }
281
282         if (test_jb_nominal_frame_insertion(test, jb, JB_TYPE_CONTROL)) {
283                 goto cleanup;
284         }
285
286         for (i = 0; i < 40; i++) {
287                 enum jb_return_code ret;
288                 /* We should have a frame for each point in time */
289                 if ((ret = jb_get(jb, &frame, i * 20 + 5, DEFAULT_CODEC_INTERP_LEN)) != JB_OK) {
290                         ast_test_status_update(test,
291                                 "Unexpected jitter buffer return code [%s] when retrieving frame %d\n",
292                                 jitter_buffer_return_codes[ret], i);
293                         goto cleanup;
294                 }
295                 JB_NUMERIC_TEST(frame.ms, 20);
296                 JB_NUMERIC_TEST(frame.ts, i * 20 - jb->info.resync_offset);
297         }
298
299         if (jb_getinfo(jb, &jbinfo) != JB_OK) {
300                 ast_test_status_update(test, "Failed to get jitterbuffer information\n");
301                 goto cleanup;
302         }
303         JB_INFO_PRINT_FRAME_DEBUG(jbinfo);
304         JB_NUMERIC_TEST(jbinfo.frames_dropped, 0);
305         JB_NUMERIC_TEST(jbinfo.frames_in, 40);
306         JB_NUMERIC_TEST(jbinfo.frames_out, 40);
307         JB_NUMERIC_TEST(jbinfo.frames_late, 0);
308         JB_NUMERIC_TEST(jbinfo.frames_lost, 0);
309         JB_NUMERIC_TEST(jbinfo.frames_ooo, 0);
310
311         result = AST_TEST_PASS;
312
313 cleanup:
314         if (jb) {
315                 /* No need to do anything - this will put all frames on the 'free' list,
316                  * so jb_destroy will dispose of them */
317                 while (jb_getall(jb, &frame) == JB_OK) { }
318                 jb_destroy(jb);
319         }
320
321         JB_TEST_END;
322
323         return result;
324 }
325
326 /*! \internal \brief Insert frames into the jitter buffer for the out of order tests */
327 static int test_jb_out_of_order_frame_insertion(struct ast_test *test, struct jitterbuf *jb, enum jb_frame_type frame_type)
328 {
329         int i = 0, ret = 0;
330
331         for (i = 0; i < 40; i++) {
332                 if (i % 4 == 0) {
333                         /* Add the next frame */
334                         if (jb_put(jb, NULL, frame_type, 20, (i + 1) * 20, (i + 1) * 20 + 5) == JB_DROP) {
335                                 ast_test_status_update(test, "Jitter buffer dropped packet %d\n", (i+1));
336                                 ret = 1;
337                                 break;
338                         }
339                         /* Add the current frame */
340                         if (jb_put(jb, NULL, frame_type, 20, i * 20, i * 20 + 5) == JB_DROP) {
341                                 ast_test_status_update(test, "Jitter buffer dropped packet %d\n", i);
342                                 ret = 1;
343                                 break;
344                         }
345                         i++;
346                 } else {
347                         if (jb_put(jb, NULL, frame_type, 20, i * 20, i * 20 + 5) == JB_DROP) {
348                                 ast_test_status_update(test, "Jitter buffer dropped packet %d\n", i);
349                                 ret = 1;
350                                 break;
351                         }
352                 }
353         }
354
355         return ret;
356 }
357
358 AST_TEST_DEFINE(jitterbuffer_out_of_order_voice)
359 {
360         enum ast_test_result_state result = AST_TEST_FAIL;
361         struct jitterbuf *jb = NULL;
362         struct jb_frame frame;
363         struct jb_info jbinfo;
364         struct jb_conf jbconf;
365         int i;
366
367         switch (cmd) {
368         case TEST_INIT:
369                 info->name = "jitterbuffer_out_of_order_voice";
370                 info->category = "/main/jitterbuf/";
371                 info->summary = "Tests sending out of order audio frames to a jitter buffer";
372                 info->description =
373                         "Every 5th frame sent to a jitter buffer is reversed with the previous "
374                         "frame.  The expected result is to have a jitter buffer with the frames "
375                         "in order, while a total of 10 frames should be recorded as having been "
376                         "received out of order.";
377                 return AST_TEST_NOT_RUN;
378         case TEST_EXECUTE:
379                 break;
380         }
381
382         JB_TEST_BEGIN("jitterbuffer_out_of_order_voice");
383
384         if (!(jb = jb_new())) {
385                 ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
386                 goto cleanup;
387         }
388
389         test_jb_populate_config(&jbconf);
390         if (jb_setconf(jb, &jbconf) != JB_OK) {
391                 ast_test_status_update(test, "Failed to set jitterbuffer configuration\n");
392                 goto cleanup;
393         }
394
395         if (test_jb_out_of_order_frame_insertion(test, jb, JB_TYPE_VOICE)) {
396                 goto cleanup;
397         }
398
399         for (i = 0; i < 40; i++) {
400                 enum jb_return_code ret;
401                 /* We should have a frame for each point in time */
402                 if ((ret = jb_get(jb, &frame, i * 20 + 5, DEFAULT_CODEC_INTERP_LEN)) != JB_OK) {
403                         ast_test_status_update(test,
404                                 "Unexpected jitter buffer return code [%s] when retrieving frame %d\n",
405                                 jitter_buffer_return_codes[ret], i);
406                         goto cleanup;
407                 }
408                 JB_NUMERIC_TEST(frame.ms, 20);
409                 JB_NUMERIC_TEST(frame.ts, i * 20 - jb->info.resync_offset);
410         }
411
412         if (jb_getinfo(jb, &jbinfo) != JB_OK) {
413                 ast_test_status_update(test, "Failed to get jitterbuffer information\n");
414                 goto cleanup;
415         }
416         JB_INFO_PRINT_FRAME_DEBUG(jbinfo);
417         JB_NUMERIC_TEST(jbinfo.frames_dropped, 0);
418         JB_NUMERIC_TEST(jbinfo.frames_in, 40);
419         JB_NUMERIC_TEST(jbinfo.frames_out, 40);
420         JB_NUMERIC_TEST(jbinfo.frames_late, 0);
421         JB_NUMERIC_TEST(jbinfo.frames_lost, 0);
422         JB_NUMERIC_TEST(jbinfo.frames_ooo, 10);
423
424         result = AST_TEST_PASS;
425
426 cleanup:
427         if (jb) {
428                 /* No need to do anything - this will put all frames on the 'free' list,
429                  * so jb_destroy will dispose of them */
430                 while (jb_getall(jb, &frame) == JB_OK) { }
431                 jb_destroy(jb);
432         }
433
434         JB_TEST_END;
435
436         return result;
437 }
438
439 AST_TEST_DEFINE(jitterbuffer_out_of_order_control)
440 {
441         enum ast_test_result_state result = AST_TEST_FAIL;
442         struct jitterbuf *jb = NULL;
443         struct jb_frame frame;
444         struct jb_info jbinfo;
445         struct jb_conf jbconf;
446         int i;
447
448         switch (cmd) {
449         case TEST_INIT:
450                 info->name = "jitterbuffer_out_of_order_voice";
451                 info->category = "/main/jitterbuf/";
452                 info->summary = "Tests sending out of order audio frames to a jitter buffer";
453                 info->description =
454                         "Every 5th frame sent to a jitter buffer is reversed with the previous "
455                         "frame.  The expected result is to have a jitter buffer with the frames "
456                         "in order, while a total of 10 frames should be recorded as having been "
457                         "received out of order.";
458                 return AST_TEST_NOT_RUN;
459         case TEST_EXECUTE:
460                 break;
461         }
462
463         JB_TEST_BEGIN("jitterbuffer_out_of_order_control");
464
465         if (!(jb = jb_new())) {
466                 ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
467                 goto cleanup;
468         }
469
470         test_jb_populate_config(&jbconf);
471         if (jb_setconf(jb, &jbconf) != JB_OK) {
472                 ast_test_status_update(test, "Failed to set jitterbuffer configuration\n");
473                 goto cleanup;
474         }
475
476         if (test_jb_out_of_order_frame_insertion(test, jb, JB_TYPE_CONTROL)) {
477                 goto cleanup;
478         }
479
480         for (i = 0; i < 40; i++) {
481                 enum jb_return_code ret;
482                 /* We should have a frame for each point in time */
483                 if ((ret = jb_get(jb, &frame, i * 20 + 5, DEFAULT_CODEC_INTERP_LEN)) != JB_OK) {
484                         ast_test_status_update(test,
485                                 "Unexpected jitter buffer return code [%s] when retrieving frame %d\n",
486                                 jitter_buffer_return_codes[ret], i);
487                         goto cleanup;
488                 }
489                 JB_NUMERIC_TEST(frame.ms, 20);
490                 JB_NUMERIC_TEST(frame.ts, i * 20 - jb->info.resync_offset);
491         }
492
493         if (jb_getinfo(jb, &jbinfo) != JB_OK) {
494                 ast_test_status_update(test, "Failed to get jitterbuffer information\n");
495                 goto cleanup;
496         }
497         JB_INFO_PRINT_FRAME_DEBUG(jbinfo);
498         JB_NUMERIC_TEST(jbinfo.frames_dropped, 0);
499         JB_NUMERIC_TEST(jbinfo.frames_in, 40);
500         JB_NUMERIC_TEST(jbinfo.frames_out, 40);
501         JB_NUMERIC_TEST(jbinfo.frames_late, 0);
502         JB_NUMERIC_TEST(jbinfo.frames_lost, 0);
503         JB_NUMERIC_TEST(jbinfo.frames_ooo, 10);
504
505         result = AST_TEST_PASS;
506
507 cleanup:
508         if (jb) {
509                 /* No need to do anything - this will put all frames on the 'free' list,
510                  * so jb_destroy will dispose of them */
511                 while (jb_getall(jb, &frame) == JB_OK) { }
512                 jb_destroy(jb);
513         }
514
515         JB_TEST_END;
516
517         return result;
518 }
519
520 /*! \internal \brief Insert frames into the jitter buffer for the lost frame tests */
521 static int test_jb_lost_frame_insertion(struct ast_test *test, struct jitterbuf *jb, enum jb_frame_type frame_type)
522 {
523         int i = 0, ret = 0;
524
525         for (i = 0; i < 40; i++) {
526                 if (i % 5 == 0) {
527                         i++;
528                 }
529                 if (jb_put(jb, NULL, frame_type, 20, i * 20, i * 20 + 5) == JB_DROP) {
530                         ast_test_status_update(test, "Jitter buffer dropped packet %d\n", i);
531                         ret = 1;
532                         break;
533                 }
534         }
535
536         return ret;
537 }
538
539 AST_TEST_DEFINE(jitterbuffer_lost_voice)
540 {
541         enum ast_test_result_state result = AST_TEST_FAIL;
542         struct jitterbuf *jb = NULL;
543         struct jb_frame frame;
544         struct jb_conf jbconf;
545         struct jb_info jbinfo;
546         int i;
547
548         switch (cmd) {
549         case TEST_INIT:
550                 info->name = "jitterbuffer_lost_voice";
551                 info->category = "/main/jitterbuf/";
552                 info->summary = "Tests missing frames in the jitterbuffer";
553                 info->description =
554                         "Every 5th frame that would be sent to a jitter buffer is instead"
555                         "dropped.  When reading data from the jitter buffer, the jitter buffer"
556                         "should interpolate the voice frame.";
557                 return AST_TEST_NOT_RUN;
558         case TEST_EXECUTE:
559                 break;
560         }
561
562         JB_TEST_BEGIN("jitterbuffer_lost_voice");
563
564         if (!(jb = jb_new())) {
565                 ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
566                 goto cleanup;
567         }
568
569         test_jb_populate_config(&jbconf);
570         if (jb_setconf(jb, &jbconf) != JB_OK) {
571                 ast_test_status_update(test, "Failed to set jitterbuffer configuration\n");
572                 goto cleanup;
573         }
574
575         if (test_jb_lost_frame_insertion(test, jb, JB_TYPE_VOICE)) {
576                 goto cleanup;
577         }
578
579         for (i = 0; i < 40; i++) {
580                 enum jb_return_code ret;
581                 if ((ret = jb_get(jb, &frame, i * 20 + 5, DEFAULT_CODEC_INTERP_LEN)) != JB_OK) {
582                         /* If we didn't get an OK, make sure that it was an expected lost frame */
583                         if (!((ret == JB_INTERP && i % 5 == 0) || (ret == JB_NOFRAME && i == 0))) {
584                                 ast_test_status_update(test,
585                                         "Unexpected jitter buffer return code [%s] when retrieving frame %d\n",
586                                         jitter_buffer_return_codes[ret], i);
587                                 goto cleanup;
588                         }
589                 } else {
590                         JB_NUMERIC_TEST(frame.ms, 20);
591                         JB_NUMERIC_TEST(frame.ts, i * 20 - jb->info.resync_offset);
592                 }
593         }
594
595         if (jb_getinfo(jb, &jbinfo) != JB_OK) {
596                 ast_test_status_update(test, "Failed to get jitterbuffer information\n");
597                 goto cleanup;
598         }
599         JB_INFO_PRINT_FRAME_DEBUG(jbinfo);
600         /* Note: The first frame (at i = 0) never got added, so nothing existed at that point.
601          * Its neither dropped nor lost.
602          */
603         JB_NUMERIC_TEST(jbinfo.frames_ooo, 0);
604         JB_NUMERIC_TEST(jbinfo.frames_late, 0);
605         JB_NUMERIC_TEST(jbinfo.frames_lost, 7);
606         JB_NUMERIC_TEST(jbinfo.frames_in, 32);
607         JB_NUMERIC_TEST(jbinfo.frames_out, 32);
608         JB_NUMERIC_TEST(jbinfo.frames_dropped, 0);
609
610         result = AST_TEST_PASS;
611
612 cleanup:
613         if (jb) {
614                 /* No need to do anything - this will put all frames on the 'free' list,
615                  * so jb_destroy will dispose of them */
616                 while (jb_getall(jb, &frame) == JB_OK) { }
617                 jb_destroy(jb);
618         }
619
620         JB_TEST_END;
621
622         return result;
623 }
624
625 AST_TEST_DEFINE(jitterbuffer_lost_control)
626 {
627         enum ast_test_result_state result = AST_TEST_FAIL;
628         struct jitterbuf *jb = NULL;
629         struct jb_frame frame;
630         struct jb_conf jbconf;
631         struct jb_info jbinfo;
632         int i;
633
634         switch (cmd) {
635         case TEST_INIT:
636                 info->name = "jitterbuffer_lost_control";
637                 info->category = "/main/jitterbuf/";
638                 info->summary = "Tests missing frames in the jitterbuffer";
639                 info->description =
640                         "Every 5th frame that would be sent to a jitter buffer is instead"
641                         "dropped.  When reading data from the jitter buffer, the jitter buffer"
642                         "simply reports that no frame exists for that time slot";
643                 return AST_TEST_NOT_RUN;
644         case TEST_EXECUTE:
645                 break;
646         }
647
648         JB_TEST_BEGIN("jitterbuffer_lost_control");
649
650         if (!(jb = jb_new())) {
651                 ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
652                 goto cleanup;
653         }
654
655         test_jb_populate_config(&jbconf);
656         if (jb_setconf(jb, &jbconf) != JB_OK) {
657                 ast_test_status_update(test, "Failed to set jitterbuffer configuration\n");
658                 goto cleanup;
659         }
660
661         if (test_jb_lost_frame_insertion(test, jb, JB_TYPE_CONTROL)) {
662                 goto cleanup;
663         }
664
665         for (i = 0; i < 40; i++) {
666                 enum jb_return_code ret;
667                 if ((ret = jb_get(jb, &frame, i * 20 + 5, DEFAULT_CODEC_INTERP_LEN)) != JB_OK) {
668                         /* If we didn't get an OK, make sure that it was an expected lost frame */
669                         if (!(ret == JB_NOFRAME && i % 5 == 0)) {
670                                 ast_test_status_update(test,
671                                         "Unexpected jitter buffer return code [%s] when retrieving frame %d\n",
672                                         jitter_buffer_return_codes[ret], i);
673                                 goto cleanup;
674                         }
675                 } else {
676                         JB_NUMERIC_TEST(frame.ms, 20);
677                         JB_NUMERIC_TEST(frame.ts, i * 20 - jb->info.resync_offset);
678                 }
679         }
680
681         if (jb_getinfo(jb, &jbinfo) != JB_OK) {
682                 ast_test_status_update(test, "Failed to get jitterbuffer information\n");
683                 goto cleanup;
684         }
685         JB_INFO_PRINT_FRAME_DEBUG(jbinfo);
686         /* Note: The first frame (at i = 0) never got added, so nothing existed at that point.
687          * Its neither dropped nor lost.
688          */
689         JB_NUMERIC_TEST(jbinfo.frames_ooo, 0);
690         JB_NUMERIC_TEST(jbinfo.frames_late, 0);
691         JB_NUMERIC_TEST(jbinfo.frames_lost, 0);
692         JB_NUMERIC_TEST(jbinfo.frames_in, 32);
693         JB_NUMERIC_TEST(jbinfo.frames_out, 32);
694         JB_NUMERIC_TEST(jbinfo.frames_dropped, 0);
695
696         result = AST_TEST_PASS;
697
698 cleanup:
699         if (jb) {
700                 /* No need to do anything - this will put all frames on the 'free' list,
701                  * so jb_destroy will dispose of them */
702                 while (jb_getall(jb, &frame) == JB_OK) { }
703                 jb_destroy(jb);
704         }
705
706         JB_TEST_END;
707
708         return result;
709 }
710
711 /*! \internal \brief Insert frames into the jitter buffer for the late frame tests */
712 static int test_jb_late_frame_insertion(struct ast_test *test, struct jitterbuf *jb, enum jb_frame_type frame_type)
713 {
714         int i = 0, ret = 0;
715
716         for (i = 0; i < 40; i++) {
717                 if (i % 5 == 0) {
718                         /* Add 5th frame */
719                         if (jb_put(jb, NULL, frame_type, 20, i * 20, i * 20 + 20) == JB_DROP) {
720                                 ast_test_status_update(test, "Jitter buffer dropped packet %d\n", (i+1));
721                                 ret = 1;
722                                 break;
723                         }
724                 } else {
725                         if (jb_put(jb, NULL, frame_type, 20, i * 20, i * 20 + 5) == JB_DROP) {
726                                 ast_test_status_update(test, "Jitter buffer dropped packet %d\n", i);
727                                 ret = 1;
728                                 break;
729                         }
730                 }
731         }
732
733         return ret;
734 }
735
736 AST_TEST_DEFINE(jitterbuffer_late_voice)
737 {
738         enum ast_test_result_state result = AST_TEST_FAIL;
739         struct jitterbuf *jb = NULL;
740         struct jb_frame frame;
741         struct jb_info jbinfo;
742         struct jb_conf jbconf;
743         int i;
744
745         switch (cmd) {
746         case TEST_INIT:
747                 info->name = "jitterbuffer_late_voice";
748                 info->category = "/main/jitterbuf/";
749                 info->summary = "Tests sending frames to a jitter buffer that arrive late";
750                 info->description =
751                         "Every 5th frame sent to a jitter buffer arrives late, but still in "
752                         "order with respect to the previous and next packet";
753                 return AST_TEST_NOT_RUN;
754         case TEST_EXECUTE:
755                 break;
756         }
757
758         JB_TEST_BEGIN("jitterbuffer_late_voice");
759
760         if (!(jb = jb_new())) {
761                 ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
762                 goto cleanup;
763         }
764
765         test_jb_populate_config(&jbconf);
766         if (jb_setconf(jb, &jbconf) != JB_OK) {
767                 ast_test_status_update(test, "Failed to set jitterbuffer configuration\n");
768                 goto cleanup;
769         }
770
771         if (test_jb_late_frame_insertion(test, jb, JB_TYPE_VOICE)) {
772                 goto cleanup;
773         }
774
775         for (i = 0; i < 40; i++) {
776                 enum jb_return_code ret;
777                 /* We should have a frame for each point in time */
778                 if ((ret = jb_get(jb, &frame, i * 20 + 5, DEFAULT_CODEC_INTERP_LEN)) != JB_OK) {
779                         ast_test_status_update(test,
780                                 "Unexpected jitter buffer return code [%s] when retrieving frame %d\n",
781                                 jitter_buffer_return_codes[ret], i);
782                         goto cleanup;
783                 }
784                 JB_NUMERIC_TEST(frame.ms, 20);
785                 JB_NUMERIC_TEST(frame.ts, i * 20 - jb->info.resync_offset);
786         }
787
788         if (jb_getinfo(jb, &jbinfo) != JB_OK) {
789                 ast_test_status_update(test, "Failed to get jitterbuffer information\n");
790                 goto cleanup;
791         }
792         JB_INFO_PRINT_FRAME_DEBUG(jbinfo);
793         JB_NUMERIC_TEST(jbinfo.frames_ooo, 0);
794         JB_NUMERIC_TEST(jbinfo.frames_late, 0);
795         JB_NUMERIC_TEST(jbinfo.frames_lost, 0);
796         JB_NUMERIC_TEST(jbinfo.frames_in, 40);
797         JB_NUMERIC_TEST(jbinfo.frames_out, 40);
798         JB_NUMERIC_TEST(jbinfo.frames_dropped, 0);
799
800         result = AST_TEST_PASS;
801
802 cleanup:
803         if (jb) {
804                 /* No need to do anything - this will put all frames on the 'free' list,
805                  * so jb_destroy will dispose of them */
806                 while (jb_getall(jb, &frame) == JB_OK) { }
807                 jb_destroy(jb);
808         }
809
810         JB_TEST_END;
811
812         return result;
813 }
814
815 AST_TEST_DEFINE(jitterbuffer_late_control)
816 {
817         enum ast_test_result_state result = AST_TEST_FAIL;
818         struct jitterbuf *jb = NULL;
819         struct jb_frame frame;
820         struct jb_info jbinfo;
821         struct jb_conf jbconf;
822         int i;
823
824         switch (cmd) {
825         case TEST_INIT:
826                 info->name = "jitterbuffer_late_control";
827                 info->category = "/main/jitterbuf/";
828                 info->summary = "Tests sending frames to a jitter buffer that arrive late";
829                 info->description =
830                         "Every 5th frame sent to a jitter buffer arrives late, but still in "
831                         "order with respect to the previous and next packet";
832                 return AST_TEST_NOT_RUN;
833         case TEST_EXECUTE:
834                 break;
835         }
836
837         JB_TEST_BEGIN("jitterbuffer_late_voice");
838
839         if (!(jb = jb_new())) {
840                 ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
841                 goto cleanup;
842         }
843
844         test_jb_populate_config(&jbconf);
845         if (jb_setconf(jb, &jbconf) != JB_OK) {
846                 ast_test_status_update(test, "Failed to set jitterbuffer configuration\n");
847                 goto cleanup;
848         }
849
850         if (test_jb_late_frame_insertion(test, jb, JB_TYPE_CONTROL)) {
851                 goto cleanup;
852         }
853
854         for (i = 0; i < 40; i++) {
855                 enum jb_return_code ret;
856                 /* We should have a frame for each point in time */
857                 if ((ret = jb_get(jb, &frame, i * 20 + 5, DEFAULT_CODEC_INTERP_LEN)) != JB_OK) {
858                         ast_test_status_update(test,
859                                 "Unexpected jitter buffer return code [%s] when retrieving frame %d\n",
860                                 jitter_buffer_return_codes[ret], i);
861                         goto cleanup;
862                 }
863                 JB_NUMERIC_TEST(frame.ms, 20);
864                 JB_NUMERIC_TEST(frame.ts, i * 20 - jb->info.resync_offset);
865         }
866
867         if (jb_getinfo(jb, &jbinfo) != JB_OK) {
868                 ast_test_status_update(test, "Failed to get jitterbuffer information\n");
869                 goto cleanup;
870         }
871         JB_INFO_PRINT_FRAME_DEBUG(jbinfo);
872         JB_NUMERIC_TEST(jbinfo.frames_ooo, 0);
873         JB_NUMERIC_TEST(jbinfo.frames_late, 0);
874         JB_NUMERIC_TEST(jbinfo.frames_lost, 0);
875         JB_NUMERIC_TEST(jbinfo.frames_in, 40);
876         JB_NUMERIC_TEST(jbinfo.frames_out, 40);
877         JB_NUMERIC_TEST(jbinfo.frames_dropped, 0);
878
879         result = AST_TEST_PASS;
880
881 cleanup:
882         if (jb) {
883                 /* No need to do anything - this will put all frames on the 'free' list,
884                  * so jb_destroy will dispose of them */
885                 while (jb_getall(jb, &frame) == JB_OK) { }
886                 jb_destroy(jb);
887         }
888
889         JB_TEST_END;
890
891         return result;
892 }
893
894 /*! \internal \brief Insert frames into the jitter buffer for the overflow tests */
895 static void test_jb_overflow_frame_insertion(struct jitterbuf *jb, enum jb_frame_type frame_type)
896 {
897         int i = 0;
898
899         for (i = 0; i < 100; i++) {
900                 jb_put(jb, NULL, frame_type, 20, i * 20, i * 20 + 5);
901         }
902 }
903
904 AST_TEST_DEFINE(jitterbuffer_overflow_voice)
905 {
906         enum ast_test_result_state result = AST_TEST_FAIL;
907         struct jitterbuf *jb = NULL;
908         struct jb_frame frame;
909         struct jb_info jbinfo;
910         struct jb_conf jbconf;
911         int i = 0;
912
913         switch (cmd) {
914         case TEST_INIT:
915                 info->name = "jitterbuffer_overflow_voice";
916                 info->category = "/main/jitterbuf/";
917                 info->summary = "Tests overfilling a jitter buffer with voice frames";
918                 info->description = "Tests overfilling a jitter buffer with voice frames";
919                 return AST_TEST_NOT_RUN;
920         case TEST_EXECUTE:
921                 break;
922         }
923
924         JB_TEST_BEGIN("jitterbuffer_overflow_voice");
925
926         if (!(jb = jb_new())) {
927                 ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
928                 goto cleanup;
929         }
930
931         test_jb_populate_config(&jbconf);
932         if (jb_setconf(jb, &jbconf) != JB_OK) {
933                 ast_test_status_update(test, "Failed to set jitterbuffer configuration\n");
934                 goto cleanup;
935         }
936
937         test_jb_overflow_frame_insertion(jb, JB_TYPE_VOICE);
938
939         while (jb_get(jb, &frame, i * 20 + 5, DEFAULT_CODEC_INTERP_LEN) == JB_OK) {
940                 JB_NUMERIC_TEST(frame.ms, 20);
941                 JB_NUMERIC_TEST(frame.ts, i * 20 - jb->info.resync_offset);
942                 ++i;
943         }
944
945         if (jb_getinfo(jb, &jbinfo) != JB_OK) {
946                 ast_test_status_update(test, "Failed to get jitterbuffer information\n");
947                 goto cleanup;
948         }
949
950         JB_INFO_PRINT_FRAME_DEBUG(jbinfo);
951         JB_NUMERIC_TEST(jbinfo.frames_dropped, 49);
952         JB_NUMERIC_TEST(jbinfo.frames_out, 51);
953         JB_NUMERIC_TEST(jbinfo.frames_in, 51);
954         JB_NUMERIC_TEST(jbinfo.frames_late, 0);
955         /* Note that the last frame will be interpolated */
956         JB_NUMERIC_TEST(jbinfo.frames_lost, 1);
957         JB_NUMERIC_TEST(jbinfo.frames_ooo, 0);
958
959         result = AST_TEST_PASS;
960
961 cleanup:
962         if (jb) {
963                 /* No need to do anything - this will put all frames on the 'free' list,
964                  * so jb_destroy will dispose of them */
965                 while (jb_getall(jb, &frame) == JB_OK) { }
966                 jb_destroy(jb);
967         }
968
969         JB_TEST_END;
970
971         return result;
972 }
973
974 AST_TEST_DEFINE(jitterbuffer_overflow_control)
975 {
976         enum ast_test_result_state result = AST_TEST_FAIL;
977         struct jitterbuf *jb = NULL;
978         struct jb_frame frame;
979         struct jb_info jbinfo;
980         struct jb_conf jbconf;
981         int i = 0;
982
983         switch (cmd) {
984         case TEST_INIT:
985                 info->name = "jitterbuffer_overflow_control";
986                 info->category = "/main/jitterbuf/";
987                 info->summary = "Tests overfilling a jitter buffer with control frames";
988                 info->description = "Tests overfilling a jitter buffer with control frames";
989                 return AST_TEST_NOT_RUN;
990         case TEST_EXECUTE:
991                 break;
992         }
993
994         JB_TEST_BEGIN("jitterbuffer_overflow_control");
995
996         if (!(jb = jb_new())) {
997                 ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
998                 goto cleanup;
999         }
1000
1001         test_jb_populate_config(&jbconf);
1002         if (jb_setconf(jb, &jbconf) != JB_OK) {
1003                 ast_test_status_update(test, "Failed to set jitterbuffer configuration\n");
1004                 goto cleanup;
1005         }
1006
1007         test_jb_overflow_frame_insertion(jb, JB_TYPE_CONTROL);
1008
1009         while (jb_get(jb, &frame, i * 20 + 5, DEFAULT_CODEC_INTERP_LEN) == JB_OK) {
1010                 JB_NUMERIC_TEST(frame.ms, 20);
1011                 JB_NUMERIC_TEST(frame.ts, i * 20 - jb->info.resync_offset);
1012                 ++i;
1013         }
1014
1015         if (jb_getinfo(jb, &jbinfo) != JB_OK) {
1016                 ast_test_status_update(test, "Failed to get jitterbuffer information\n");
1017                 goto cleanup;
1018         }
1019
1020         JB_INFO_PRINT_FRAME_DEBUG(jbinfo);
1021         JB_NUMERIC_TEST(jbinfo.frames_dropped, 49);
1022         JB_NUMERIC_TEST(jbinfo.frames_out, 51);
1023         JB_NUMERIC_TEST(jbinfo.frames_in, 51);
1024         JB_NUMERIC_TEST(jbinfo.frames_late, 0);
1025         JB_NUMERIC_TEST(jbinfo.frames_lost, 0);
1026         JB_NUMERIC_TEST(jbinfo.frames_ooo, 0);
1027
1028         result = AST_TEST_PASS;
1029
1030 cleanup:
1031         if (jb) {
1032                 /* No need to do anything - this will put all frames on the 'free' list,
1033                  * so jb_destroy will dispose of them */
1034                 while (jb_getall(jb, &frame) == JB_OK) { }
1035                 jb_destroy(jb);
1036         }
1037
1038         JB_TEST_END;
1039
1040         return result;
1041 }
1042
1043 /*! \internal \brief Insert frames into the jitter buffer for the resynch tests */
1044 static void test_jb_resynch_frame_insertion(struct jitterbuf *jb, enum jb_frame_type frame_type)
1045 {
1046         int i = 0;
1047
1048         for (i = 0; i < 20; i++) {
1049                 jb_put(jb, NULL, frame_type, 20, i * 20, i * 20 + 5);
1050         }
1051
1052         for (i = 20; i < 40; i++) {
1053                 jb_put(jb, NULL, frame_type, 20, i * 20 + 500, i * 20 + 5);
1054         }
1055 }
1056
1057 AST_TEST_DEFINE(jitterbuffer_resynch_control)
1058 {
1059         enum ast_test_result_state result = AST_TEST_FAIL;
1060         struct jitterbuf *jb = NULL;
1061         struct jb_frame frame;
1062         struct jb_info jbinfo;
1063         struct jb_conf jbconf;
1064         int interpolated_frames = 0;
1065         int i;
1066
1067         switch (cmd) {
1068         case TEST_INIT:
1069                 info->name = "jitterbuffer_resynch_control";
1070                 info->category = "/main/jitterbuf/";
1071                 info->summary = "Tests sending control frames that force a resynch";
1072                 info->description = "Control frames are sent to a jitter buffer.  After some "
1073                         "number of frames, the source timestamps jump, forcing a resync of "
1074                         "the jitter buffer.  Since the frames are control, the resync happens "
1075                         "immediately.";
1076                 return AST_TEST_NOT_RUN;
1077         case TEST_EXECUTE:
1078                 break;
1079         }
1080
1081         JB_TEST_BEGIN("jitterbuffer_resynch_control");
1082
1083         if (!(jb = jb_new())) {
1084                 ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
1085                 goto cleanup;
1086         }
1087
1088         test_jb_populate_config(&jbconf);
1089         jbconf.resync_threshold = 200;
1090         if (jb_setconf(jb, &jbconf) != JB_OK) {
1091                 ast_test_status_update(test, "Failed to set jitterbuffer configuration\n");
1092                 goto cleanup;
1093         }
1094
1095         test_jb_resynch_frame_insertion(jb, JB_TYPE_CONTROL);
1096
1097         for (i = 0; i <= 40; i++) {
1098                 if (jb_get(jb, &frame, i * 20 + 5, DEFAULT_CODEC_INTERP_LEN) == JB_INTERP) {
1099                         ++interpolated_frames;
1100                 }
1101         }
1102
1103         if (jb_getinfo(jb, &jbinfo) != JB_OK) {
1104                 ast_test_status_update(test, "Failed to get jitterbuffer information\n");
1105                 goto cleanup;
1106         }
1107         /* With control frames, a resync happens automatically */
1108         JB_INFO_PRINT_FRAME_DEBUG(jbinfo);
1109         JB_NUMERIC_TEST(jbinfo.frames_dropped, 0);
1110         JB_NUMERIC_TEST(jbinfo.frames_out, 40);
1111         JB_NUMERIC_TEST(jbinfo.frames_in, 40);
1112         /* Verify that each of the interpolated frames is counted */
1113         JB_NUMERIC_TEST(jbinfo.frames_lost, interpolated_frames);
1114         JB_NUMERIC_TEST(jbinfo.frames_late, 0);
1115         JB_NUMERIC_TEST(jbinfo.frames_ooo, 0);
1116
1117         result = AST_TEST_PASS;
1118
1119 cleanup:
1120         if (jb) {
1121                 /* No need to do anything - this will put all frames on the 'free' list,
1122                  * so jb_destroy will dispose of them */
1123                 while (jb_getall(jb, &frame) == JB_OK) { }
1124                 jb_destroy(jb);
1125         }
1126
1127         JB_TEST_END;
1128
1129         return result;
1130 }
1131
1132 AST_TEST_DEFINE(jitterbuffer_resynch_voice)
1133 {
1134         enum ast_test_result_state result = AST_TEST_FAIL;
1135         struct jitterbuf *jb = NULL;
1136         struct jb_frame frame;
1137         struct jb_info jbinfo;
1138         struct jb_conf jbconf;
1139         int interpolated_frames = 0;
1140         int i;
1141
1142         switch (cmd) {
1143         case TEST_INIT:
1144                 info->name = "jitterbuffer_resynch_voice";
1145                 info->category = "/main/jitterbuf/";
1146                 info->summary = "Tests sending voice frames that force a resynch";
1147                 info->description = "Voice frames are sent to a jitter buffer.  After some "
1148                         "number of frames, the source timestamps jump, forcing a resync of "
1149                         "the jitter buffer.  Since the frames are voice, the resync happens "
1150                         "after observing three packets that break the resync threshold.";
1151                 return AST_TEST_NOT_RUN;
1152         case TEST_EXECUTE:
1153                 break;
1154         }
1155
1156         JB_TEST_BEGIN("jitterbuffer_resynch_voice");
1157
1158         if (!(jb = jb_new())) {
1159                 ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
1160                 goto cleanup;
1161         }
1162
1163         test_jb_populate_config(&jbconf);
1164         jbconf.resync_threshold = 200;
1165         if (jb_setconf(jb, &jbconf) != JB_OK) {
1166                 ast_test_status_update(test, "Failed to set jitterbuffer configuration\n");
1167                 goto cleanup;
1168         }
1169
1170         test_jb_resynch_frame_insertion(jb, JB_TYPE_VOICE);
1171
1172         for (i = 0; i <= 40; i++) {
1173                 if (jb_get(jb, &frame, i * 20 + 5, DEFAULT_CODEC_INTERP_LEN) == JB_INTERP) {
1174                         ++interpolated_frames;
1175                 }
1176         }
1177
1178         if (jb_getinfo(jb, &jbinfo) != JB_OK) {
1179                 ast_test_status_update(test, "Failed to get jitterbuffer information\n");
1180                 goto cleanup;
1181         }
1182         /* The first three packets before the resync should be dropped */
1183         JB_INFO_PRINT_FRAME_DEBUG(jbinfo);
1184         JB_NUMERIC_TEST(jbinfo.frames_dropped, 3);
1185         JB_NUMERIC_TEST(jbinfo.frames_out, 37);
1186         JB_NUMERIC_TEST(jbinfo.frames_in, 37);
1187         /* Verify that each of the interpolated frames is counted */
1188         JB_NUMERIC_TEST(jbinfo.frames_lost, interpolated_frames);
1189         JB_NUMERIC_TEST(jbinfo.frames_late, 0);
1190         JB_NUMERIC_TEST(jbinfo.frames_ooo, 0);
1191
1192
1193         result = AST_TEST_PASS;
1194
1195 cleanup:
1196         if (jb) {
1197                 /* No need to do anything - this will put all frames on the 'free' list,
1198                  * so jb_destroy will dispose of them */
1199                 while (jb_getall(jb, &frame) == JB_OK) { }
1200                 jb_destroy(jb);
1201         }
1202
1203         JB_TEST_END;
1204
1205         return result;
1206 }
1207
1208 static int unload_module(void)
1209 {
1210         AST_TEST_UNREGISTER(jitterbuffer_nominal_voice_frames);
1211         AST_TEST_UNREGISTER(jitterbuffer_nominal_control_frames);
1212         AST_TEST_UNREGISTER(jitterbuffer_out_of_order_voice);
1213         AST_TEST_UNREGISTER(jitterbuffer_out_of_order_control);
1214         AST_TEST_UNREGISTER(jitterbuffer_lost_voice);
1215         AST_TEST_UNREGISTER(jitterbuffer_lost_control);
1216         AST_TEST_UNREGISTER(jitterbuffer_late_voice);
1217         AST_TEST_UNREGISTER(jitterbuffer_late_control);
1218         AST_TEST_UNREGISTER(jitterbuffer_overflow_voice);
1219         AST_TEST_UNREGISTER(jitterbuffer_overflow_control);
1220         AST_TEST_UNREGISTER(jitterbuffer_resynch_voice);
1221         AST_TEST_UNREGISTER(jitterbuffer_resynch_control);
1222         return 0;
1223 }
1224
1225 static int load_module(void)
1226 {
1227         /* Nominal - put / get frames */
1228         AST_TEST_REGISTER(jitterbuffer_nominal_voice_frames);
1229         AST_TEST_REGISTER(jitterbuffer_nominal_control_frames);
1230
1231         /* Out of order frame arrival */
1232         AST_TEST_REGISTER(jitterbuffer_out_of_order_voice);
1233         AST_TEST_REGISTER(jitterbuffer_out_of_order_control);
1234
1235         /* Lost frame arrival */
1236         AST_TEST_REGISTER(jitterbuffer_lost_voice);
1237         AST_TEST_REGISTER(jitterbuffer_lost_control);
1238
1239         /* Late frame arrival */
1240         AST_TEST_REGISTER(jitterbuffer_late_voice);
1241         AST_TEST_REGISTER(jitterbuffer_late_control);
1242
1243         /* Buffer overflow */
1244         AST_TEST_REGISTER(jitterbuffer_overflow_voice);
1245         AST_TEST_REGISTER(jitterbuffer_overflow_control);
1246
1247         /* Buffer resynch */
1248         AST_TEST_REGISTER(jitterbuffer_resynch_voice);
1249         AST_TEST_REGISTER(jitterbuffer_resynch_control);
1250
1251         return AST_MODULE_LOAD_SUCCESS;
1252 }
1253
1254 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Jitter Buffer Tests");