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
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; \
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; \
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; \
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; \
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); \
147#define OBTAIN_JITTERBUFFER_IMPL(impl, ast_jb_type, literal_name) do { \
148 (impl) = ast_jb_get_impl((ast_jb_type)); \
150 ast_test_status_update(test, "Error: no %s jitterbuffer defined\n", (literal_name)); \
151 return AST_TEST_FAIL; \
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; \
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; \
182#define TEST_NAME(type_name, specifier) type_name ## _ ## specifier
184#define TEST_NAME2(test_name) #test_name
185#define STRINGIFY_TESTNAME(test_name) TEST_NAME2(test_name)
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; \
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; \
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); \
216 jb->jbobj = impl->create(&conf); \
219 ast_test_status_update(test, "Error: Failed to adaptive jitterbuffer\n"); \
220 return AST_TEST_FAIL; \
223 return AST_TEST_PASS; \
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); \
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; \
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); \
261 ast_test_status_update(test, "Error: Failed to adaptive jitterbuffer\n"); \
262 return AST_TEST_FAIL; \
265 expected_frame = create_test_frame(1000, 0); \
266 res = jb->impl->put_first(jb->jbobj, \
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; \
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; \
280 expected_frame = create_test_frame(1000, 0); \
281 VERIFY_FRAME(actual_frame, expected_frame); \
282 return AST_TEST_PASS; \
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; \
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; \
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); \
320 expected_frame = create_test_frame(1000, 0); \
321 res = jb->impl->put_first(jb->jbobj, \
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; \
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, \
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; \
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", \
350 ast_frame_dtor(expected_frame); \
351 return AST_TEST_FAIL; \
353 VERIFY_FRAME(actual_frame, expected_frame); \
354 ast_frame_dtor(expected_frame); \
355 ast_frame_dtor(actual_frame); \
357 return AST_TEST_PASS; \
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); \
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; \
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); \
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, \
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; \
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, \
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; \
421 ast_frfree(expected_frame); \
422 expected_frame = NULL;\
425 return AST_TEST_PASS; \
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; \
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; \
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); \
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; \
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); \
480 expected_frame = create_test_frame(1000 + i * DEFAULT_FRAME_MS, 0); \
482 res = jb->impl->put(jb->jbobj, \
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; \
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", \
500 ast_frame_dtor(expected_frame); \
501 return AST_TEST_FAIL; \
503 VERIFY_FRAME(actual_frame, expected_frame); \
504 ast_frame_dtor(expected_frame); \
505 ast_frame_dtor(actual_frame); \
506 expected_frame = NULL; \
509 return AST_TEST_PASS; \
Common implementation-independent jitterbuffer stuff.
Asterisk main include file. File version handling, generic pbx functions.
Asterisk internal frame definitions.
#define ast_frisolate(fr)
Makes a frame independent of any static storage.
Asterisk module definitions.
#define AST_MODULE_INFO_STANDARD(keystr, desc)
#define ASTERISK_GPL_KEY
The text the key() function should return.
@ AST_MODULE_LOAD_SUCCESS
struct ast_format * format
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
enum ast_frame_type frametype
jb_empty_and_reset_impl empty_and_reset
General jitterbuffer state.
void * jbobj
Jitterbuffer object, passed to the implementation.
const struct ast_jb_impl * impl
Jitterbuffer implementation to be used.
#define AST_TEST_REGISTER(cb)
#define AST_TEST_UNREGISTER(cb)
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)
static void dispose_jitterbuffer(struct ast_jb *jb)
static int load_module(void)
#define DEFAULT_CONFIG_RESYNC_THRESHOLD
#define TEST_NAME(type_name, specifier)