Asterisk - The Open Source Telephony Project GIT-master-a358458
test_abstract_jb.c
Go to the documentation of this file.
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 Abstract Jitterbuffer Tests
22 *
23 * \author \verbatim Matt Jordan <mjordan@digium.com> \endverbatim
24 *
25 * Tests the abstract jitter buffer API. This tests both adaptive and fixed
26 * jitter buffers. Functions defined in abstract_jb that are not part of the
27 * abstract jitter buffer API are not tested by this unit test.
28 *
29 * \ingroup tests
30 */
31
32/*** MODULEINFO
33 <depend>TEST_FRAMEWORK</depend>
34 <support_level>core</support_level>
35 ***/
36
37#include "asterisk.h"
38
39#include "asterisk/utils.h"
40#include "asterisk/module.h"
41#include "asterisk/test.h"
43#include "asterisk/frame.h"
45
46#define DEFAULT_FRAME_MS 160
47#define DEFAULT_CONFIG_FLAGS 0
48#define DEFAULT_CONFIG_SIZE (DEFAULT_FRAME_MS) * 10
49#define DEFAULT_CONFIG_RESYNC_THRESHOLD (DEFAULT_FRAME_MS) * 2
50#define DEFAULT_CONFIG_TARGET_EXTRA -1
51
52/*!
53 * \internal
54 * \brief Destructor for a jitter buffer
55 *
56 * \param jb The jitter buffer to destroy
57 *
58 * \note This will destroy all frames still in the jitter buffer
59 */
60static void dispose_jitterbuffer(struct ast_jb *jb)
61{
62 if (!jb || !jb->impl || !jb->jbobj) {
63 return;
64 }
65
66 jb->impl->empty_and_reset(jb->jbobj);
67
68 jb->impl->destroy(jb->jbobj);
69 jb->impl = NULL;
70 jb->jbobj = NULL;
71}
72
73/*!
74 * \internal
75 * \brief Create a test frame
76 *
77 * \param timestamp the time in ms of the frame
78 * \param seqno the frame's sequence number
79 *
80 * \returns a malloc'd frame
81 */
82static struct ast_frame *create_test_frame(long timestamp,
83 int seqno)
84{
85 struct ast_frame f = {0};
86
89 f.src = "TEST";
90 f.ts = timestamp;
92 f.seqno = seqno;
93
94 return ast_frisolate(&f);
95}
96
97/*! \internal
98 * \brief Test two numeric (long int) values.
99*/
100#define LONG_INT_TEST(actual, expected) do { \
101 if ((actual) != (expected)) { \
102 ast_test_status_update(test, #actual ": expected [%ld]; actual [%ld]\n", (long int)(expected), (long int)(actual)); \
103 return AST_TEST_FAIL; \
104 } } while (0)
105
106/*! \internal
107 * \brief Test two numeric (int) values.
108*/
109#define INT_TEST(actual, expected) do { \
110 if ((actual) != (expected)) { \
111 ast_test_status_update(test, #actual ": expected [%d]; actual [%d]\n", (expected), (actual)); \
112 return AST_TEST_FAIL; \
113 } } while (0)
114
115/*! \internal
116 * \brief Test two numeric (unsigned int) values.
117*/
118#define UINT_TEST(actual, expected) do { \
119 if ((actual) != (expected)) { \
120 ast_test_status_update(test, #actual ": expected [%u]; actual [%u]\n", (expected), (actual)); \
121 return AST_TEST_FAIL; \
122 } } while (0)
123
124/*! \internal
125 * \brief Test two string values
126*/
127#define STRING_TEST(actual, expected) do { \
128 if (strcmp((actual), (expected))) { \
129 ast_test_status_update(test, #actual ": expected [%s]; actual [%s]\n", (expected), (actual)); \
130 return AST_TEST_FAIL; \
131 } } while (0)
132
133/*! \internal
134 * \brief Verify that two frames have the same properties
135 */
136#define VERIFY_FRAME(actual, expected) do { \
137 UINT_TEST((actual)->frametype, (expected)->frametype); \
138 INT_TEST((actual)->seqno, (expected)->seqno); \
139 LONG_INT_TEST((actual)->ts, (expected)->ts); \
140 LONG_INT_TEST((actual)->len, (expected)->len); \
141 STRING_TEST((actual)->src, (expected)->src); \
142} while (0)
143
144/*! \internal
145 * \brief Get the implementation for a jitter buffer
146 */
147#define OBTAIN_JITTERBUFFER_IMPL(impl, ast_jb_type, literal_name) do { \
148 (impl) = ast_jb_get_impl((ast_jb_type)); \
149 if (!(impl)) { \
150 ast_test_status_update(test, "Error: no %s jitterbuffer defined\n", (literal_name)); \
151 return AST_TEST_FAIL; \
152 } \
153 if (strcmp((impl)->name, (literal_name))) { \
154 ast_test_status_update(test, "Error: requested %s jitterbuffer and received %s\n", (literal_name), (impl)->name); \
155 return AST_TEST_FAIL; \
156 } } while (0)
157
158/*! \internal
159 * \brief Make a jitter buffer configuration object with default values
160 */
161#define MAKE_DEFAULT_CONFIG(conf, impl) do { \
162 (conf)->flags = DEFAULT_CONFIG_FLAGS; \
163 strcpy((conf)->impl, (impl)->name); \
164 (conf)->max_size = DEFAULT_CONFIG_SIZE; \
165 (conf)->resync_threshold = DEFAULT_CONFIG_RESYNC_THRESHOLD; \
166 (conf)->target_extra = DEFAULT_CONFIG_TARGET_EXTRA; \
167 } while (0)
168
169/*!
170 * \internal
171 * \brief A container object for the jitter buffers, used for all tests
172 */
173static struct ast_jb default_jb = {
174 .impl = NULL,
175 .jbobj = NULL
176};
177
178/*!
179 * \internal
180 * \brief Construct a test name
181 */
182#define TEST_NAME(type_name, specifier) type_name ## _ ## specifier
183
184#define TEST_NAME2(test_name) #test_name
185#define STRINGIFY_TESTNAME(test_name) TEST_NAME2(test_name)
186
187/*!
188 * \internal
189 * \brief Test nominal construction of a jitter buffer
190 *
191 * \param type_name The enum type of the jitter buffer to create
192 * \param literal_type_name The literal name of the type - "fixed" or "adaptive"
193 */
194#define test_create_nominal(type_name, literal_type_name) AST_TEST_DEFINE(TEST_NAME(type_name, create)) {\
195 RAII_VAR(struct ast_jb *, jb, &default_jb, dispose_jitterbuffer); \
196 const struct ast_jb_impl *impl; \
197 struct ast_jb_conf conf; \
198\
199 switch (cmd) { \
200 case TEST_INIT: \
201 info->name = STRINGIFY_TESTNAME(TEST_NAME(type_name, create)); \
202 info->category = "/main/abstract_jb/"; \
203 info->summary = "Test nominal creation of a " literal_type_name " jitterbuffer"; \
204 info->description = \
205 "Tests nominal creation of a " literal_type_name " jitterbuffer using the " \
206 " jitterbuffer API."; \
207 return AST_TEST_NOT_RUN; \
208 case TEST_EXECUTE: \
209 break; \
210 } \
211 \
212 ast_test_status_update(test, "Executing " STRINGIFY_TESTNAME(TEST_NAME(type_name, create))"...\n"); \
213 OBTAIN_JITTERBUFFER_IMPL(impl, (type_name), (literal_type_name)); \
214 MAKE_DEFAULT_CONFIG(&conf, impl); \
215 \
216 jb->jbobj = impl->create(&conf); \
217 jb->impl = impl; \
218 if (!jb->jbobj) { \
219 ast_test_status_update(test, "Error: Failed to adaptive jitterbuffer\n"); \
220 return AST_TEST_FAIL; \
221 } \
222 \
223 return AST_TEST_PASS; \
224}
225
226/*!
227 * \internal
228 * \brief Test putting the initial frame into a jitter buffer
229 *
230 * \param type_name The enum type of the jitter buffer to create
231 * \param literal_type_name The literal name of the type - "fixed" or "adaptive"
232 */
233#define test_put_first(type_name, literal_type_name) AST_TEST_DEFINE(TEST_NAME(type_name, put_first)) {\
234 RAII_VAR(struct ast_jb *, jb, &default_jb, dispose_jitterbuffer); \
235 const struct ast_jb_impl *impl; \
236 struct ast_jb_conf conf; \
237 RAII_VAR(struct ast_frame *, expected_frame, NULL, ast_frame_dtor); \
238 RAII_VAR(struct ast_frame *, actual_frame, NULL, ast_frame_dtor); \
239 int res; \
240\
241 switch (cmd) { \
242 case TEST_INIT: \
243 info->name = STRINGIFY_TESTNAME(TEST_NAME(type_name, put_first)); \
244 info->category = "/main/abstract_jb/"; \
245 info->summary = "Test putting a frame into a " literal_type_name " jitterbuffer"; \
246 info->description = \
247 "This tests putting a single frame into a " literal_type_name " jitterbuffer " \
248 "when the jitterbuffer is empty and verifying that it is indeed " \
249 "the first frame on the jitterbuffer"; \
250 return AST_TEST_NOT_RUN; \
251 case TEST_EXECUTE: \
252 break; \
253 } \
254\
255 ast_test_status_update(test, "Executing " STRINGIFY_TESTNAME(TEST_NAME(type_name, create))"...\n"); \
256 OBTAIN_JITTERBUFFER_IMPL(impl, (type_name), (literal_type_name)); \
257 MAKE_DEFAULT_CONFIG(&conf, impl); \
258 jb->jbobj = impl->create(&conf); \
259 jb->impl = impl; \
260 if (!jb->jbobj) { \
261 ast_test_status_update(test, "Error: Failed to adaptive jitterbuffer\n"); \
262 return AST_TEST_FAIL; \
263 } \
264\
265 expected_frame = create_test_frame(1000, 0); \
266 res = jb->impl->put_first(jb->jbobj, \
267 expected_frame, \
268 1100); \
269 if (res != AST_JB_IMPL_OK) { \
270 ast_test_status_update(test, "Error: Got %d back from put_first (expected %d)\n", \
271 res, AST_JB_IMPL_OK); \
272 return AST_TEST_FAIL; \
273 } \
274\
275 res = jb->impl->remove(jb->jbobj, &actual_frame); \
276 if (!actual_frame || res != AST_JB_IMPL_OK) { \
277 ast_test_status_update(test, "Error: failed to retrieve first frame\n"); \
278 return AST_TEST_FAIL; \
279 } \
280 expected_frame = create_test_frame(1000, 0); \
281 VERIFY_FRAME(actual_frame, expected_frame); \
282 return AST_TEST_PASS; \
283}
284
285/*!
286 * \internal
287 * \brief Test putting a voice frames into a jitter buffer
288 *
289 * \param type_name The enum type of the jitter buffer to create
290 * \param literal_type_name The literal name of the type - "fixed" or "adaptive"
291 */
292#define test_put(type_name, literal_type_name) AST_TEST_DEFINE(TEST_NAME(type_name, put)) {\
293 RAII_VAR(struct ast_jb *, jb, &default_jb, dispose_jitterbuffer); \
294 const struct ast_jb_impl *impl; \
295 struct ast_jb_conf conf; \
296 struct ast_frame *expected_frame = NULL; \
297 struct ast_frame *actual_frame = NULL; \
298 int res; \
299 long next; \
300 int i; \
301\
302 switch (cmd) { \
303 case TEST_INIT: \
304 info->name = STRINGIFY_TESTNAME(TEST_NAME(type_name, put)); \
305 info->category = "/main/abstract_jb/"; \
306 info->summary = "Test putting frames onto a " literal_type_name " jitterbuffer"; \
307 info->description = \
308 "This tests putting multiple frames into a " literal_type_name " jitterbuffer"; \
309 return AST_TEST_NOT_RUN; \
310 case TEST_EXECUTE: \
311 break; \
312 } \
313\
314 ast_test_status_update(test, "Executing "STRINGIFY_TESTNAME(TEST_NAME(type_name, put))"...\n"); \
315 OBTAIN_JITTERBUFFER_IMPL(impl, (type_name), (literal_type_name)); \
316 MAKE_DEFAULT_CONFIG(&conf, impl); \
317 jb->jbobj = impl->create(&conf); \
318 jb->impl = impl; \
319\
320 expected_frame = create_test_frame(1000, 0); \
321 res = jb->impl->put_first(jb->jbobj, \
322 expected_frame, \
323 1100); \
324 if (res != AST_JB_IMPL_OK) { \
325 ast_test_status_update(test, "Error: On first frame, got %d back from put_first (expected %d)\n", \
326 res, AST_JB_IMPL_OK); \
327 ast_frame_dtor(expected_frame); \
328 return AST_TEST_FAIL; \
329 } \
330 for (i = 1; i < 10; i++) { \
331 expected_frame = create_test_frame(1000 + i * DEFAULT_FRAME_MS, 0); \
332 res = jb->impl->put(jb->jbobj, \
333 expected_frame, \
334 1100 + i * DEFAULT_FRAME_MS); \
335 if (res != AST_JB_IMPL_OK) { \
336 ast_test_status_update(test, "Error: On frame %d, got %d back from put (expected %d)\n", \
337 i, res, AST_JB_IMPL_OK); \
338 ast_frame_dtor(expected_frame); \
339 return AST_TEST_FAIL; \
340 } \
341 } \
342\
343 for (i = 0; i < 10; i++) { \
344 expected_frame = create_test_frame(1000 + i * DEFAULT_FRAME_MS, 0); \
345 next = jb->impl->next(jb->jbobj); \
346 res = jb->impl->get(jb->jbobj, &actual_frame, next, DEFAULT_FRAME_MS); \
347 if (res != AST_JB_IMPL_OK) { \
348 ast_test_status_update(test, "Error: failed to retrieve frame %i at time %ld\n", \
349 i, next); \
350 ast_frame_dtor(expected_frame); \
351 return AST_TEST_FAIL; \
352 } \
353 VERIFY_FRAME(actual_frame, expected_frame); \
354 ast_frame_dtor(expected_frame); \
355 ast_frame_dtor(actual_frame); \
356 } \
357 return AST_TEST_PASS; \
358}
359
360/*!
361 * \internal
362 * \brief Test overflowing the limits of a jitter buffer
363 *
364 * \param type_name The enum type of the jitter buffer to create
365 * \param literal_type_name The literal name of the type - "fixed" or "adaptive"
366 * \param overflow_limit The number of frames at which we expect the buffer to overflow
367 */
368#define test_put_overflow(type_name, literal_type_name, overflow_limit) AST_TEST_DEFINE(TEST_NAME(type_name, put_overflow)) {\
369 RAII_VAR(struct ast_jb *, jb, &default_jb, dispose_jitterbuffer); \
370 const struct ast_jb_impl *impl; \
371 struct ast_jb_conf conf; \
372 RAII_VAR(struct ast_frame *, expected_frame, NULL, ast_frame_dtor); \
373 int res; \
374 int i; \
375\
376 switch (cmd) { \
377 case TEST_INIT: \
378 info->name = STRINGIFY_TESTNAME(TEST_NAME(type_name, put_overflow)); \
379 info->category = "/main/abstract_jb/"; \
380 info->summary = "Test putting frames onto a " literal_type_name " jitterbuffer " \
381 "that ends up overflowing the maximum allowed slots in the buffer"; \
382 info->description = \
383 "This tests putting multiple frames into a " literal_type_name " jitterbuffer " \
384 "until the jitterbuffer overflows"; \
385 return AST_TEST_NOT_RUN; \
386 case TEST_EXECUTE: \
387 break; \
388 } \
389\
390 ast_test_status_update(test, "Executing "STRINGIFY_TESTNAME(TEST_NAME(type_name, put_overflow))"...\n"); \
391 OBTAIN_JITTERBUFFER_IMPL(impl, (type_name), (literal_type_name)); \
392 MAKE_DEFAULT_CONFIG(&conf, impl); \
393 jb->jbobj = impl->create(&conf); \
394 jb->impl = impl; \
395\
396 expected_frame = create_test_frame(1000, 0); \
397 jb->impl->put_first(jb->jbobj, expected_frame, 1100); \
398 for (i = 1; i <= (overflow_limit); i++) { \
399 expected_frame = create_test_frame(1000 + i * DEFAULT_FRAME_MS, 0); \
400 res = jb->impl->put(jb->jbobj, \
401 expected_frame, \
402 1100 + i * DEFAULT_FRAME_MS); \
403 if (res != AST_JB_IMPL_OK) { \
404 ast_test_status_update(test, "Error: On frame %d, got %d back from put (expected %d)\n", \
405 i, res, AST_JB_IMPL_OK); \
406 return AST_TEST_FAIL; \
407 } \
408 } \
409\
410 for (i = (overflow_limit)+1; i < (overflow_limit) + 5; i++) { \
411 expected_frame = create_test_frame(1000 + i * DEFAULT_FRAME_MS, 0); \
412 res = jb->impl->put(jb->jbobj, \
413 expected_frame, \
414 1100 + i * DEFAULT_FRAME_MS); \
415 if (res != AST_JB_IMPL_DROP) { \
416 expected_frame = NULL; \
417 ast_test_status_update(test, "Error: On frame %d, got %d back from put (expected %d)\n", \
418 i, res, AST_JB_IMPL_DROP); \
419 return AST_TEST_FAIL; \
420 } \
421 ast_frfree(expected_frame); \
422 expected_frame = NULL;\
423 } \
424\
425 return AST_TEST_PASS; \
426}
427
428/*!
429 * \internal
430 * \brief Test putting voice frames into a jitter buffer out of order
431 *
432 * \param type_name The enum type of the jitter buffer to create
433 * \param literal_type_name The literal name of the type - "fixed" or "adaptive"
434 * \param synch_limit The synchronization limit for this particular type of jitter buffer
435 */
436#define test_put_out_of_order(type_name, literal_type_name, synch_limit) AST_TEST_DEFINE(TEST_NAME(type_name, put_out_of_order)) {\
437 RAII_VAR(struct ast_jb *, jb, &default_jb, dispose_jitterbuffer); \
438 const struct ast_jb_impl *impl; \
439 struct ast_jb_conf conf; \
440 struct ast_frame *expected_frame = NULL; \
441 struct ast_frame *actual_frame = NULL; \
442 int res; \
443 long next; \
444 int i; \
445\
446 switch (cmd) { \
447 case TEST_INIT: \
448 info->name = STRINGIFY_TESTNAME(TEST_NAME(type_name, put_out_of_order)); \
449 info->category = "/main/abstract_jb/"; \
450 info->summary = "Test putting out of order frames onto a " literal_type_name " jitterbuffer"; \
451 info->description = \
452 "This tests putting multiple frames into a " literal_type_name " jitterbuffer " \
453 "that arrive out of order. Every 3rd frame is put in out of order."; \
454 return AST_TEST_NOT_RUN; \
455 case TEST_EXECUTE: \
456 break; \
457 } \
458\
459 ast_test_status_update(test, "Executing " STRINGIFY_TESTNAME(TEST_NAME(type_name, put_out_of_order)) "...\n"); \
460 OBTAIN_JITTERBUFFER_IMPL(impl, (type_name), (literal_type_name)); \
461 MAKE_DEFAULT_CONFIG(&conf, impl); \
462 conf.resync_threshold = (synch_limit); \
463 jb->jbobj = impl->create(&conf); \
464 jb->impl = impl; \
465\
466 expected_frame = create_test_frame(1000, 0); \
467 res = jb->impl->put_first(jb->jbobj, expected_frame, 1100); \
468 if (res != AST_JB_IMPL_OK) { \
469 ast_test_status_update(test, "Error: On first frame, got %d back from put_first (expected %d)\n", \
470 res, AST_JB_IMPL_OK); \
471 ast_frame_dtor(expected_frame); \
472 return AST_TEST_FAIL; \
473 } \
474 for (i = 1; i <= 10; i++) { \
475 if (i % 3 == 1 && i != 10) { \
476 expected_frame = create_test_frame(1000 + ((i + 1) * DEFAULT_FRAME_MS), 0); \
477 } else if (i % 3 == 2) { \
478 expected_frame = create_test_frame(1000 + ((i - 1) * DEFAULT_FRAME_MS), 0); \
479 } else { \
480 expected_frame = create_test_frame(1000 + i * DEFAULT_FRAME_MS, 0); \
481 } \
482 res = jb->impl->put(jb->jbobj, \
483 expected_frame, \
484 1100 + i * DEFAULT_FRAME_MS); \
485 if (res != AST_JB_IMPL_OK) { \
486 ast_test_status_update(test, "Error: On frame %d, got %d back from put (expected %d)\n", \
487 i, res, AST_JB_IMPL_OK); \
488 ast_frame_dtor(expected_frame); \
489 return AST_TEST_FAIL; \
490 } \
491 } \
492\
493 for (i = 0; i <= 10; i++) { \
494 expected_frame = create_test_frame(1000 + i * DEFAULT_FRAME_MS, 0); \
495 next = jb->impl->next(jb->jbobj); \
496 res = jb->impl->get(jb->jbobj, &actual_frame, next, DEFAULT_FRAME_MS); \
497 if (res != AST_JB_IMPL_OK) { \
498 ast_test_status_update(test, "Error: failed to retrieve frame at %ld\n", \
499 next); \
500 ast_frame_dtor(expected_frame); \
501 return AST_TEST_FAIL; \
502 } \
503 VERIFY_FRAME(actual_frame, expected_frame); \
504 ast_frame_dtor(expected_frame); \
505 ast_frame_dtor(actual_frame); \
506 expected_frame = NULL; \
507 } \
508\
509 return AST_TEST_PASS; \
510}
511
512
514
516
517test_put(AST_JB_ADAPTIVE, "adaptive")
518
519test_put_overflow(AST_JB_ADAPTIVE, "adaptive", 10)
520
522
524
526
527test_put(AST_JB_FIXED, "fixed")
528
530
532
533static int unload_module(void)
534{
540
545 AST_TEST_UNREGISTER(TEST_NAME(AST_JB_FIXED, put_out_of_order));
546
547 return 0;
548}
549
550static int load_module(void)
551{
556 AST_TEST_REGISTER(TEST_NAME(AST_JB_ADAPTIVE, put_out_of_order));
557
562 AST_TEST_REGISTER(TEST_NAME(AST_JB_FIXED, put_out_of_order));
563
565}
566
567AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Abstract JitterBuffer API Tests");
Common implementation-independent jitterbuffer stuff.
@ AST_JB_ADAPTIVE
Definition: abstract_jb.h:53
@ AST_JB_FIXED
Definition: abstract_jb.h:52
#define unload_module
Definition: agent.c:79
Asterisk main include file. File version handling, generic pbx functions.
Media Format Cache API.
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
Asterisk internal frame definitions.
#define ast_frisolate(fr)
Makes a frame independent of any static storage.
@ AST_FRAME_VOICE
Asterisk module definitions.
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:567
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
#define NULL
Definition: resample.c:96
struct ast_format * format
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
enum ast_frame_type frametype
const char * src
jb_destroy_impl destroy
Definition: abstract_jb.h:126
jb_empty_and_reset_impl empty_and_reset
Definition: abstract_jb.h:133
General jitterbuffer state.
Definition: abstract_jb.h:141
void * jbobj
Jitterbuffer object, passed to the implementation.
Definition: abstract_jb.h:147
const struct ast_jb_impl * impl
Jitterbuffer implementation to be used.
Definition: abstract_jb.h:145
Test Framework API.
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
static struct ast_jb default_jb
#define test_put_first(type_name, literal_type_name)
#define test_put(type_name, literal_type_name)
#define test_create_nominal(type_name, literal_type_name)
static struct ast_frame * create_test_frame(long timestamp, int seqno)
#define test_put_overflow(type_name, literal_type_name, overflow_limit)
#define test_put_out_of_order(type_name, literal_type_name, synch_limit)
#define DEFAULT_FRAME_MS
static void dispose_jitterbuffer(struct ast_jb *jb)
static int load_module(void)
#define DEFAULT_CONFIG_RESYNC_THRESHOLD
#define TEST_NAME(type_name, specifier)
Utility functions.