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