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