[asterisk-commits] mjordan: branch mjordan/trunk_jitter_tests r358809 - /team/mjordan/trunk_jitt...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Mar 12 21:44:09 CDT 2012
Author: mjordan
Date: Mon Mar 12 21:44:07 2012
New Revision: 358809
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=358809
Log:
Add remaining tests for jitterbuffer
Add the remaining tests, which were mostly permutations of the
existing tests added earlier.
Modified:
team/mjordan/trunk_jitter_tests/tests/test_jitterbuffer.c
Modified: team/mjordan/trunk_jitter_tests/tests/test_jitterbuffer.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/trunk_jitter_tests/tests/test_jitterbuffer.c?view=diff&rev=358809&r1=358808&r2=358809
==============================================================================
--- team/mjordan/trunk_jitter_tests/tests/test_jitterbuffer.c (original)
+++ team/mjordan/trunk_jitter_tests/tests/test_jitterbuffer.c Mon Mar 12 21:44:07 2012
@@ -1,9 +1,9 @@
/*
* Asterisk -- An open source telephony toolkit.
*
- * Copyright (C) <Year>, <Your Name Here>
+ * Copyright (C) 2012, Matt Jordan
*
- * <Your Name Here> <<Your Email Here>>
+ * Matt Jordan <mjordan at digium.com>
*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
@@ -18,11 +18,10 @@
/*!
* \file
- * \brief Skeleton Test
+ * \brief Unit tests for channel jitter buffers
*
- * \author\verbatim <Your Name Here> <<Your Email Here>> \endverbatim
+ * \author\verbatim Matt Jordan <mjordan at digium.com> \endverbatim
*
- * This is a skeleton for development of an Asterisk test module
* \ingroup tests
*/
@@ -47,11 +46,10 @@
#define DEFAULT_CODEC_INTERP_LEN 20
/*! \internal
- * Test two numeric (long int) values. It is expected that the attribute value is
- * some numeric attribute in a jb_info object. Failure automatically attempts
+ * Test two numeric (long int) values. Failure automatically attempts
* to jump to a cleanup tag
*/
-#define JB_INFO_NUMERIC_TEST(attribute, expected) do { \
+#define JB_NUMERIC_TEST(attribute, expected) do { \
if (attribute != expected) { \
ast_test_status_update(test, #attribute ": expected [%ld]; actual [%ld]\n", (long int)expected, attribute); \
goto cleanup; \
@@ -62,7 +60,7 @@
* Print out as debug the frame related contents of a jb_info object
*/
#define JB_INFO_PRINT_FRAME_DEBUG(jbinfo) do { \
- ast_verb(1, "JitterBuffer Frame Info:\n" \
+ ast_debug(1, "JitterBuffer Frame Info:\n" \
"\tFrames In: %ld\n\tFrames Out: %ld\n" \
"\tDropped Frames: %ld\n\tLate Frames: %ld\n" \
"\tLost Frames: %ld\n\tOut of Order Frames: %ld\n" \
@@ -75,7 +73,7 @@
* This macro installs the error, warning, and debug functions for a test. It is
* expected that at the end of a test, the functions are removed.
* Note that the debug statement is in here merely to aid in tracing in a lot where
- * the jitterbuffer debug begins.
+ * the jitter buffer debug begins.
*/
#define JB_TEST_BEGIN(test_name) do { \
jb_setoutput(test_jb_error_output, test_jb_warn_output, test_jb_debug_output); \
@@ -165,7 +163,8 @@
info->category = "/main/jitterbuffer/";
info->summary = "Nominal operation of jitterbuffer with audio data";
info->description =
- "Tests the nominal case of putting audio data into a jitter buffer";
+ "Tests the nominal case of putting audio data into a jitter buffer, "
+ "retrieving the frames, and querying for the next frame";
return AST_TEST_NOT_RUN;
case TEST_EXECUTE:
break;
@@ -200,16 +199,9 @@
jitter_buffer_return_codes[ret], i);
goto cleanup;
}
- if (frame.ms != 20) {
- ast_test_status_update(test,
- "Unexpected ms value [%ld] on frame %d - expected %d\n", frame.ms, i, 20);
- goto cleanup;
- }
- if (frame.ts != i * 20 - jb->info.resync_offset) {
- ast_test_status_update(test,
- "Unexpected ts value [%ld] on frame %d - expected %ld\n", frame.ts, i, i * 20 - jb->info.resync_offset);
- goto cleanup;
- }
+ JB_NUMERIC_TEST(frame.ms, 20);
+ JB_NUMERIC_TEST(frame.ts, i * 20 - jb->info.resync_offset);
+ JB_NUMERIC_TEST(jb_next(jb), (i + 1) * 20 + 5);
}
result = AST_TEST_PASS;
@@ -218,12 +210,13 @@
ast_test_status_update(test, "Failed to get jitterbuffer information\n");
goto cleanup;
}
- JB_INFO_NUMERIC_TEST(jbinfo.frames_dropped, 0);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_in, 40);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_out, 40);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_late, 0);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_lost, 0);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_ooo, 0);
+ JB_INFO_PRINT_FRAME_DEBUG(jbinfo);
+ JB_NUMERIC_TEST(jbinfo.frames_dropped, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_in, 40);
+ JB_NUMERIC_TEST(jbinfo.frames_out, 40);
+ JB_NUMERIC_TEST(jbinfo.frames_late, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_lost, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_ooo, 0);
cleanup:
if (jb) {
@@ -253,7 +246,8 @@
info->category = "/main/jitterbuffer/";
info->summary = "Nominal operation of jitterbuffer with control frames";
info->description =
- "Tests the nominal case of putting control frames into a jitter buffer";
+ "Tests the nominal case of putting control frames into a jitter buffer, "
+ "retrieving the frames, and querying for the next frame";
return AST_TEST_NOT_RUN;
case TEST_EXECUTE:
break;
@@ -288,28 +282,22 @@
jitter_buffer_return_codes[ret], i);
goto cleanup;
}
- if (frame.ms != 20) {
- ast_test_status_update(test,
- "Unexpected ms value [%ld] on frame %d - expected %d\n", frame.ms, i, 20);
- goto cleanup;
- }
- if (frame.ts != i * 20 - jb->info.resync_offset) {
- ast_test_status_update(test,
- "Unexpected ts value [%ld] on frame %d - expected %ld\n", frame.ts, i, i * 20 - jb->info.resync_offset);
- goto cleanup;
- }
+ JB_NUMERIC_TEST(frame.ms, 20);
+ JB_NUMERIC_TEST(frame.ts, i * 20 - jb->info.resync_offset);
+ JB_NUMERIC_TEST(jb_next(jb), (i + 1) * 20 + 5);
}
if (jb_getinfo(jb, &jbinfo) != JB_OK) {
ast_test_status_update(test, "Failed to get jitterbuffer information\n");
goto cleanup;
}
- JB_INFO_NUMERIC_TEST(jbinfo.frames_dropped, 0);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_in, 40);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_out, 40);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_late, 0);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_lost, 0);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_ooo, 0);
+ JB_INFO_PRINT_FRAME_DEBUG(jbinfo);
+ JB_NUMERIC_TEST(jbinfo.frames_dropped, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_in, 40);
+ JB_NUMERIC_TEST(jbinfo.frames_out, 40);
+ JB_NUMERIC_TEST(jbinfo.frames_late, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_lost, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_ooo, 0);
result = AST_TEST_PASS;
@@ -393,32 +381,119 @@
jitter_buffer_return_codes[ret], i);
goto cleanup;
}
- if (frame.ms != 20) {
- ast_test_status_update(test,
- "Unexpected ms value [%ld] on frame %d - expected %d\n", frame.ms, i, 20);
- goto cleanup;
- }
- if (frame.ts != i * 20 - jb->info.resync_offset) {
- ast_test_status_update(test,
- "Unexpected ts value [%ld] on frame %d - expected %ld\n", frame.ts, i, i * 20 - jb->info.resync_offset);
- goto cleanup;
- }
+ JB_NUMERIC_TEST(frame.ms, 20);
+ JB_NUMERIC_TEST(frame.ts, i * 20 - jb->info.resync_offset);
}
if (jb_getinfo(jb, &jbinfo) != JB_OK) {
ast_test_status_update(test, "Failed to get jitterbuffer information\n");
goto cleanup;
}
+ JB_INFO_PRINT_FRAME_DEBUG(jbinfo);
+ JB_NUMERIC_TEST(jbinfo.frames_dropped, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_in, 40);
+ JB_NUMERIC_TEST(jbinfo.frames_out, 40);
+ JB_NUMERIC_TEST(jbinfo.frames_late, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_lost, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_ooo, 10);
+
+ result = AST_TEST_PASS;
+
+cleanup:
+ if (jb) {
+ /* No need to do anything - this will put all frames on the 'free' list,
+ * so jb_destroy will dispose of them */
+ while (jb_getall(jb, &frame) == JB_OK) { }
+ jb_destroy(jb);
+ }
+
+ JB_TEST_END;
+
+ return result;
+}
+
+AST_TEST_DEFINE(jitterbuffer_out_of_order_control)
+{
+ enum ast_test_result_state result = AST_TEST_FAIL;
+ struct jitterbuf *jb = NULL;
+ struct jb_frame frame;
+ struct jb_info jbinfo;
+ struct jb_conf jbconf;
+ int i;
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "jitterbuffer_out_of_order_voice";
+ info->category = "/main/jitterbuffer/";
+ info->summary = "Tests sending out of order audio frames to a jitter buffer";
+ info->description =
+ "Every 5th frame sent to a jitter buffer is reversed with the previous "
+ "frame. The expected result is to have a jitter buffer with the frames "
+ "in order, while a total of 10 frames should be recorded as having been "
+ "received out of order.";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ JB_TEST_BEGIN("jitterbuffer_out_of_order_control");
+
+ if (!(jb = jb_new())) {
+ ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
+ goto cleanup;
+ }
+
+ test_jb_populate_config(&jbconf);
+ if (jb_setconf(jb, &jbconf) != JB_OK) {
+ ast_test_status_update(test, "Failed to set jitterbuffer configuration\n");
+ goto cleanup;
+ }
+
+ for (i = 0; i < 40; i++) {
+ if (i % 4 == 0) {
+ /* Add 5th frame */
+ if (jb_put(jb, NULL, JB_TYPE_CONTROL, 20, (i + 1) * 20, (i + 1) * 20 + 5) == JB_DROP) {
+ ast_test_status_update(test, "Jitter buffer dropped packet %d\n", (i+1));
+ goto cleanup;
+ }
+ /* Add 4th frame */
+ if (jb_put(jb, NULL, JB_TYPE_CONTROL, 20, i * 20, i * 20 + 5) == JB_DROP) {
+ ast_test_status_update(test, "Jitter buffer dropped packet %d\n", i);
+ goto cleanup;
+ }
+ i++;
+ } else {
+ if (jb_put(jb, NULL, JB_TYPE_CONTROL, 20, i * 20, i * 20 + 5) == JB_DROP) {
+ ast_test_status_update(test, "Jitter buffer dropped packet %d\n", i);
+ goto cleanup;
+ }
+ }
+ }
+
+ for (i = 0; i < 40; i++) {
+ enum jb_return_code ret;
+ /* We should have a frame for each point in time */
+ if ((ret = jb_get(jb, &frame, i * 20 + 5, DEFAULT_CODEC_INTERP_LEN)) != JB_OK) {
+ ast_test_status_update(test,
+ "Unexpected jitter buffer return code [%s] when retrieving frame %d\n",
+ jitter_buffer_return_codes[ret], i);
+ goto cleanup;
+ }
+ JB_NUMERIC_TEST(frame.ms, 20);
+ JB_NUMERIC_TEST(frame.ts, i * 20 - jb->info.resync_offset);
+ }
+
if (jb_getinfo(jb, &jbinfo) != JB_OK) {
ast_test_status_update(test, "Failed to get jitterbuffer information\n");
goto cleanup;
}
- JB_INFO_NUMERIC_TEST(jbinfo.frames_dropped, 0);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_in, 40);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_out, 40);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_late, 0);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_lost, 0);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_ooo, 10);
+ JB_INFO_PRINT_FRAME_DEBUG(jbinfo);
+ JB_NUMERIC_TEST(jbinfo.frames_dropped, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_in, 40);
+ JB_NUMERIC_TEST(jbinfo.frames_out, 40);
+ JB_NUMERIC_TEST(jbinfo.frames_late, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_lost, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_ooo, 10);
result = AST_TEST_PASS;
@@ -492,16 +567,8 @@
goto cleanup;
}
} else {
- if (frame.ms != 20) {
- ast_test_status_update(test,
- "Unexpected ms value [%ld] on frame %d - expected %d\n", frame.ms, i, 20);
- goto cleanup;
- }
- if (frame.ts != i * 20 - jb->info.resync_offset) {
- ast_test_status_update(test,
- "Unexpected ts value [%ld] on frame %d - expected %ld\n", frame.ts, i, i * 20 - jb->info.resync_offset);
- goto cleanup;
- }
+ JB_NUMERIC_TEST(frame.ms, 20);
+ JB_NUMERIC_TEST(frame.ts, i * 20 - jb->info.resync_offset);
}
}
@@ -513,12 +580,12 @@
/* Note: The first frame (at i = 0) never got added, so nothing existed at that point.
* Its neither dropped nor lost.
*/
- JB_INFO_NUMERIC_TEST(jbinfo.frames_ooo, 0);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_late, 0);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_lost, 7);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_in, 32);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_out, 32);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_dropped, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_ooo, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_late, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_lost, 7);
+ JB_NUMERIC_TEST(jbinfo.frames_in, 32);
+ JB_NUMERIC_TEST(jbinfo.frames_out, 32);
+ JB_NUMERIC_TEST(jbinfo.frames_dropped, 0);
result = AST_TEST_PASS;
@@ -535,6 +602,98 @@
return result;
}
+AST_TEST_DEFINE(jitterbuffer_lost_control)
+{
+ enum ast_test_result_state result = AST_TEST_FAIL;
+ struct jitterbuf *jb = NULL;
+ struct jb_frame frame;
+ struct jb_conf jbconf;
+ struct jb_info jbinfo;
+ int i;
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "jitterbuffer_lost_control";
+ info->category = "/main/jitterbuffer/";
+ info->summary = "Tests missing frames in the jitterbuffer";
+ info->description =
+ "Every 5th frame that would be sent to a jitter buffer is instead"
+ "dropped. When reading data from the jitter buffer, the jitter buffer"
+ "simply reports that no frame exists for that time slot";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ JB_TEST_BEGIN("jitterbuffer_lost_control");
+
+ if (!(jb = jb_new())) {
+ ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
+ goto cleanup;
+ }
+
+ test_jb_populate_config(&jbconf);
+ if (jb_setconf(jb, &jbconf) != JB_OK) {
+ ast_test_status_update(test, "Failed to set jitterbuffer configuration\n");
+ goto cleanup;
+ }
+
+ for (i = 0; i < 40; i++) {
+ if (i % 5 == 0) {
+ i++;
+ }
+ if (jb_put(jb, NULL, JB_TYPE_CONTROL, 20, i * 20, i * 20 + 5) == JB_DROP) {
+ ast_test_status_update(test, "Jitter buffer dropped packet %d\n", i);
+ goto cleanup;
+ }
+ }
+
+ for (i = 0; i < 40; i++) {
+ enum jb_return_code ret;
+ if ((ret = jb_get(jb, &frame, i * 20 + 5, DEFAULT_CODEC_INTERP_LEN)) != JB_OK) {
+ /* If we didn't get an OK, make sure that it was an expected lost frame */
+ if (!(ret == JB_NOFRAME && i % 5 == 0)) {
+ ast_test_status_update(test,
+ "Unexpected jitter buffer return code [%s] when retrieving frame %d\n",
+ jitter_buffer_return_codes[ret], i);
+ goto cleanup;
+ }
+ } else {
+ JB_NUMERIC_TEST(frame.ms, 20);
+ JB_NUMERIC_TEST(frame.ts, i * 20 - jb->info.resync_offset);
+ }
+ }
+
+ if (jb_getinfo(jb, &jbinfo) != JB_OK) {
+ ast_test_status_update(test, "Failed to get jitterbuffer information\n");
+ goto cleanup;
+ }
+ JB_INFO_PRINT_FRAME_DEBUG(jbinfo);
+ /* Note: The first frame (at i = 0) never got added, so nothing existed at that point.
+ * Its neither dropped nor lost.
+ */
+ JB_NUMERIC_TEST(jbinfo.frames_ooo, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_late, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_lost, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_in, 32);
+ JB_NUMERIC_TEST(jbinfo.frames_out, 32);
+ JB_NUMERIC_TEST(jbinfo.frames_dropped, 0);
+
+ result = AST_TEST_PASS;
+
+cleanup:
+ if (jb) {
+ /* No need to do anything - this will put all frames on the 'free' list,
+ * so jb_destroy will dispose of them */
+ while (jb_getall(jb, &frame) == JB_OK) { }
+ jb_destroy(jb);
+ }
+
+ JB_TEST_END;
+
+ return result;
+}
+
AST_TEST_DEFINE(jitterbuffer_late_voice)
{
enum ast_test_result_state result = AST_TEST_FAIL;
@@ -548,17 +707,16 @@
case TEST_INIT:
info->name = "jitterbuffer_late_voice";
info->category = "/main/jitterbuffer/";
- info->summary = "Tests sending frames to a jitterbuffer that are late";
+ info->summary = "Tests sending frames to a jitter buffer that arrive late";
info->description =
- "Every 5th frame sent to a jitter buffer is put into the jitterbuffer just"
- "prior to the arrival of the 6th frame. The expected result is to have a";
- /* TODO: */
+ "Every 5th frame sent to a jitter buffer arrives late, but still in "
+ "order with respect to the previous and next packet";
return AST_TEST_NOT_RUN;
case TEST_EXECUTE:
break;
}
- JB_TEST_BEGIN("jitterbuffer_late_audio");
+ JB_TEST_BEGIN("jitterbuffer_late_voice");
if (!(jb = jb_new())) {
ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
@@ -595,16 +753,8 @@
jitter_buffer_return_codes[ret], i);
goto cleanup;
}
- if (frame.ms != 20) {
- ast_test_status_update(test,
- "Unexpected ms value [%ld] on frame %d - expected %d\n", frame.ms, i, 20);
- goto cleanup;
- }
- if (frame.ts != i * 20 - jb->info.resync_offset) {
- ast_test_status_update(test,
- "Unexpected ts value [%ld] on frame %d - expected %ld\n", frame.ts, i, i * 20 - jb->info.resync_offset);
- goto cleanup;
- }
+ JB_NUMERIC_TEST(frame.ms, 20);
+ JB_NUMERIC_TEST(frame.ts, i * 20 - jb->info.resync_offset);
}
if (jb_getinfo(jb, &jbinfo) != JB_OK) {
@@ -612,12 +762,12 @@
goto cleanup;
}
JB_INFO_PRINT_FRAME_DEBUG(jbinfo);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_ooo, 0);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_late, 0);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_lost, 0);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_in, 40);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_out, 40);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_dropped, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_ooo, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_late, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_lost, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_in, 40);
+ JB_NUMERIC_TEST(jbinfo.frames_out, 40);
+ JB_NUMERIC_TEST(jbinfo.frames_dropped, 0);
result = AST_TEST_PASS;
@@ -634,7 +784,7 @@
return result;
}
-AST_TEST_DEFINE(jitterbuffer_overflow)
+AST_TEST_DEFINE(jitterbuffer_late_control)
{
enum ast_test_result_state result = AST_TEST_FAIL;
struct jitterbuf *jb = NULL;
@@ -645,16 +795,19 @@
switch (cmd) {
case TEST_INIT:
- info->name = "jitterbuffer_overflow";
+ info->name = "jitterbuffer_late_control";
info->category = "/main/jitterbuffer/";
- info->summary = "Tests sending frames to a jitterbuffer that are late";
- info->description = "Blahblah";
- /* TODO: */
+ info->summary = "Tests sending frames to a jitter buffer that arrive late";
+ info->description =
+ "Every 5th frame sent to a jitter buffer arrives late, but still in "
+ "order with respect to the previous and next packet";
return AST_TEST_NOT_RUN;
case TEST_EXECUTE:
break;
}
+ JB_TEST_BEGIN("jitterbuffer_late_voice");
+
if (!(jb = jb_new())) {
ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
goto cleanup;
@@ -666,24 +819,45 @@
goto cleanup;
}
- for (i = 0; i < 100; i++) {
- jb_put(jb, NULL, JB_TYPE_VOICE, 20, i * 20, i * 20 + 5);
- }
-
- i = 0;
- while (jb_get(jb, &frame, i * 20 + 5, DEFAULT_CODEC_INTERP_LEN) == JB_OK) {
- ++i;
- }
-
+ for (i = 0; i < 40; i++) {
+ if (i % 5 == 0) {
+ /* Add 5th frame */
+ if (jb_put(jb, NULL, JB_TYPE_CONTROL, 20, i * 20, i * 20 + 20) == JB_DROP) {
+ ast_test_status_update(test, "Jitter buffer dropped packet %d\n", (i+1));
+ goto cleanup;
+ }
+ } else {
+ if (jb_put(jb, NULL, JB_TYPE_CONTROL, 20, i * 20, i * 20 + 5) == JB_DROP) {
+ ast_test_status_update(test, "Jitter buffer dropped packet %d\n", i);
+ goto cleanup;
+ }
+ }
+ }
+
+ for (i = 0; i < 40; i++) {
+ enum jb_return_code ret;
+ /* We should have a frame for each point in time */
+ if ((ret = jb_get(jb, &frame, i * 20 + 5, DEFAULT_CODEC_INTERP_LEN)) != JB_OK) {
+ ast_test_status_update(test,
+ "Unexpected jitter buffer return code [%s] when retrieving frame %d\n",
+ jitter_buffer_return_codes[ret], i);
+ goto cleanup;
+ }
+ JB_NUMERIC_TEST(frame.ms, 20);
+ JB_NUMERIC_TEST(frame.ts, i * 20 - jb->info.resync_offset);
+ }
if (jb_getinfo(jb, &jbinfo) != JB_OK) {
ast_test_status_update(test, "Failed to get jitterbuffer information\n");
goto cleanup;
}
-
JB_INFO_PRINT_FRAME_DEBUG(jbinfo);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_dropped, 49);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_out, 51);
+ JB_NUMERIC_TEST(jbinfo.frames_ooo, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_late, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_lost, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_in, 40);
+ JB_NUMERIC_TEST(jbinfo.frames_out, 40);
+ JB_NUMERIC_TEST(jbinfo.frames_dropped, 0);
result = AST_TEST_PASS;
@@ -694,6 +868,156 @@
while (jb_getall(jb, &frame) == JB_OK) { }
jb_destroy(jb);
}
+
+ JB_TEST_END;
+
+ return result;
+}
+
+AST_TEST_DEFINE(jitterbuffer_overflow_voice)
+{
+ enum ast_test_result_state result = AST_TEST_FAIL;
+ struct jitterbuf *jb = NULL;
+ struct jb_frame frame;
+ struct jb_info jbinfo;
+ struct jb_conf jbconf;
+ int i;
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "jitterbuffer_overflow_voice";
+ info->category = "/main/jitterbuffer/";
+ info->summary = "Tests overfilling a jitter buffer with voice frames";
+ info->description = "Tests overfilling a jitter buffer with voice frames";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ JB_TEST_BEGIN("jitterbuffer_overflow_voice");
+
+ if (!(jb = jb_new())) {
+ ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
+ goto cleanup;
+ }
+
+ test_jb_populate_config(&jbconf);
+ if (jb_setconf(jb, &jbconf) != JB_OK) {
+ ast_test_status_update(test, "Failed to set jitterbuffer configuration\n");
+ goto cleanup;
+ }
+
+ for (i = 0; i < 100; i++) {
+ jb_put(jb, NULL, JB_TYPE_VOICE, 20, i * 20, i * 20 + 5);
+ }
+
+ i = 0;
+ while (jb_get(jb, &frame, i * 20 + 5, DEFAULT_CODEC_INTERP_LEN) == JB_OK) {
+ JB_NUMERIC_TEST(frame.ms, 20);
+ JB_NUMERIC_TEST(frame.ts, i * 20 - jb->info.resync_offset);
+ ++i;
+ }
+
+
+ if (jb_getinfo(jb, &jbinfo) != JB_OK) {
+ ast_test_status_update(test, "Failed to get jitterbuffer information\n");
+ goto cleanup;
+ }
+
+ JB_INFO_PRINT_FRAME_DEBUG(jbinfo);
+ JB_NUMERIC_TEST(jbinfo.frames_dropped, 49);
+ JB_NUMERIC_TEST(jbinfo.frames_out, 51);
+ JB_NUMERIC_TEST(jbinfo.frames_in, 51);
+ JB_NUMERIC_TEST(jbinfo.frames_late, 0);
+ /* Note that the last frame will be interpolated */
+ JB_NUMERIC_TEST(jbinfo.frames_lost, 1);
+ JB_NUMERIC_TEST(jbinfo.frames_ooo, 0);
+
+ result = AST_TEST_PASS;
+
+cleanup:
+ if (jb) {
+ /* No need to do anything - this will put all frames on the 'free' list,
+ * so jb_destroy will dispose of them */
+ while (jb_getall(jb, &frame) == JB_OK) { }
+ jb_destroy(jb);
+ }
+
+ JB_TEST_END;
+
+ return result;
+}
+
+AST_TEST_DEFINE(jitterbuffer_overflow_control)
+{
+ enum ast_test_result_state result = AST_TEST_FAIL;
+ struct jitterbuf *jb = NULL;
+ struct jb_frame frame;
+ struct jb_info jbinfo;
+ struct jb_conf jbconf;
+ int i;
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "jitterbuffer_overflow_control";
+ info->category = "/main/jitterbuffer/";
+ info->summary = "Tests overfilling a jitter buffer with control frames";
+ info->description = "Tests overfilling a jitter buffer with control frames";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ JB_TEST_BEGIN("jitterbuffer_overflow_control");
+
+ if (!(jb = jb_new())) {
+ ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
+ goto cleanup;
+ }
+
+ test_jb_populate_config(&jbconf);
+ if (jb_setconf(jb, &jbconf) != JB_OK) {
+ ast_test_status_update(test, "Failed to set jitterbuffer configuration\n");
+ goto cleanup;
+ }
+
+ for (i = 0; i < 100; i++) {
+ jb_put(jb, NULL, JB_TYPE_CONTROL, 20, i * 20, i * 20 + 5);
+ }
+
+ i = 0;
+ while (jb_get(jb, &frame, i * 20 + 5, DEFAULT_CODEC_INTERP_LEN) == JB_OK) {
+ JB_NUMERIC_TEST(frame.ms, 20);
+ JB_NUMERIC_TEST(frame.ts, i * 20 - jb->info.resync_offset);
+ ++i;
+ }
+
+
+ if (jb_getinfo(jb, &jbinfo) != JB_OK) {
+ ast_test_status_update(test, "Failed to get jitterbuffer information\n");
+ goto cleanup;
+ }
+
+ JB_INFO_PRINT_FRAME_DEBUG(jbinfo);
+ JB_NUMERIC_TEST(jbinfo.frames_dropped, 49);
+ JB_NUMERIC_TEST(jbinfo.frames_out, 51);
+ JB_NUMERIC_TEST(jbinfo.frames_in, 51);
+ JB_NUMERIC_TEST(jbinfo.frames_late, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_lost, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_ooo, 0);
+
+ result = AST_TEST_PASS;
+
+cleanup:
+ if (jb) {
+ /* No need to do anything - this will put all frames on the 'free' list,
+ * so jb_destroy will dispose of them */
+ while (jb_getall(jb, &frame) == JB_OK) { }
+ jb_destroy(jb);
+ }
+
+ JB_TEST_END;
+
return result;
}
@@ -711,13 +1035,17 @@
case TEST_INIT:
info->name = "jitterbuffer_resynch_control";
info->category = "/main/jitterbuffer/";
- info->summary = "Tests sending frames to a jitterbuffer that are late";
- info->description = "Blahblah";
- /* TODO: */
+ info->summary = "Tests sending control frames that force a resynch";
+ info->description = "Control frames are sent to a jitter buffer. After some "
+ "number of frames, the source timestamps jump, forcing a resync of "
+ "the jitter buffer. Since the frames are control, the resync happens "
+ "immediately.";
return AST_TEST_NOT_RUN;
case TEST_EXECUTE:
break;
}
+
+ JB_TEST_BEGIN("jitterbuffer_resynch_control");
if (!(jb = jb_new())) {
ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
@@ -751,11 +1079,13 @@
}
/* With control frames, a resync happens automatically */
JB_INFO_PRINT_FRAME_DEBUG(jbinfo);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_dropped, 0);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_out, 40);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_in, 40);
+ JB_NUMERIC_TEST(jbinfo.frames_dropped, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_out, 40);
+ JB_NUMERIC_TEST(jbinfo.frames_in, 40);
/* Verify that each of the interpolated frames is counted */
- JB_INFO_NUMERIC_TEST(jbinfo.frames_lost, interpolated_frames);
+ JB_NUMERIC_TEST(jbinfo.frames_lost, interpolated_frames);
+ JB_NUMERIC_TEST(jbinfo.frames_late, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_ooo, 0);
result = AST_TEST_PASS;
@@ -766,10 +1096,13 @@
while (jb_getall(jb, &frame) == JB_OK) { }
jb_destroy(jb);
}
+
+ JB_TEST_END;
+
return result;
}
-AST_TEST_DEFINE(jitterbuffer_resynch_audio)
+AST_TEST_DEFINE(jitterbuffer_resynch_voice)
{
enum ast_test_result_state result = AST_TEST_FAIL;
struct jitterbuf *jb = NULL;
@@ -781,15 +1114,19 @@
switch (cmd) {
case TEST_INIT:
- info->name = "jitterbuffer_resynch_audio";
+ info->name = "jitterbuffer_resynch_voice";
info->category = "/main/jitterbuffer/";
- info->summary = "Tests sending frames to a jitterbuffer that are late";
- info->description = "Blahblah";
- /* TODO: */
+ info->summary = "Tests sending voice frames that force a resynch";
+ info->description = "Voice frames are sent to a jitter buffer. After some "
+ "number of frames, the source timestamps jump, forcing a resync of "
+ "the jitter buffer. Since the frames are voice, the resync happens "
+ "after observing three packets that break the resync threshold.";
return AST_TEST_NOT_RUN;
case TEST_EXECUTE:
break;
}
+
+ JB_TEST_BEGIN("jitterbuffer_resynch_voice");
if (!(jb = jb_new())) {
ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
@@ -823,11 +1160,13 @@
}
/* The first three packets before the resync should be dropped */
JB_INFO_PRINT_FRAME_DEBUG(jbinfo);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_dropped, 3);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_out, 37);
- JB_INFO_NUMERIC_TEST(jbinfo.frames_in, 37);
+ JB_NUMERIC_TEST(jbinfo.frames_dropped, 3);
+ JB_NUMERIC_TEST(jbinfo.frames_out, 37);
+ JB_NUMERIC_TEST(jbinfo.frames_in, 37);
/* Verify that each of the interpolated frames is counted */
- JB_INFO_NUMERIC_TEST(jbinfo.frames_lost, interpolated_frames);
+ JB_NUMERIC_TEST(jbinfo.frames_lost, interpolated_frames);
+ JB_NUMERIC_TEST(jbinfo.frames_late, 0);
+ JB_NUMERIC_TEST(jbinfo.frames_ooo, 0);
result = AST_TEST_PASS;
@@ -839,6 +1178,9 @@
while (jb_getall(jb, &frame) == JB_OK) { }
jb_destroy(jb);
}
+
+ JB_TEST_END;
+
return result;
}
@@ -846,26 +1188,43 @@
{
AST_TEST_UNREGISTER(jitterbuffer_nominal_voice_frames);
AST_TEST_UNREGISTER(jitterbuffer_nominal_control_frames);
- AST_TEST_UNREGISTER(jitterbuffer_out_of_order_audio);
- AST_TEST_UNREGISTER(jitterbuffer_lost_audio);
- AST_TEST_UNREGISTER(jitterbuffer_late_audio);
- AST_TEST_UNREGISTER(jitterbuffer_overflow);
- AST_TEST_UNREGISTER(jitterbuffer_resynch_audio);
+ AST_TEST_UNREGISTER(jitterbuffer_out_of_order_voice);
+ AST_TEST_UNREGISTER(jitterbuffer_out_of_order_control);
+ AST_TEST_UNREGISTER(jitterbuffer_lost_voice);
+ AST_TEST_UNREGISTER(jitterbuffer_late_voice);
+ AST_TEST_UNREGISTER(jitterbuffer_overflow_voice);
+ AST_TEST_UNREGISTER(jitterbuffer_resynch_voice);
AST_TEST_UNREGISTER(jitterbuffer_resynch_control);
return 0;
}
static int load_module(void)
{
+ /* Nominal - put / get frames */
AST_TEST_REGISTER(jitterbuffer_nominal_voice_frames);
AST_TEST_REGISTER(jitterbuffer_nominal_control_frames);
- AST_TEST_REGISTER(jitterbuffer_out_of_order_audio);
- AST_TEST_REGISTER(jitterbuffer_lost_audio);
- AST_TEST_REGISTER(jitterbuffer_late_audio);
- AST_TEST_REGISTER(jitterbuffer_overflow);
- AST_TEST_REGISTER(jitterbuffer_resynch_audio);
+
+ /* Out of order frame arrival */
+ AST_TEST_REGISTER(jitterbuffer_out_of_order_voice);
+ AST_TEST_REGISTER(jitterbuffer_out_of_order_control);
+
+ /* Lost frame arrival */
+ AST_TEST_REGISTER(jitterbuffer_lost_voice);
+ AST_TEST_REGISTER(jitterbuffer_lost_control);
+
+ /* Late frame arrival */
+ AST_TEST_REGISTER(jitterbuffer_late_voice);
+ AST_TEST_REGISTER(jitterbuffer_late_control);
+
+ /* Buffer overflow */
+ AST_TEST_REGISTER(jitterbuffer_overflow_voice);
+ AST_TEST_REGISTER(jitterbuffer_overflow_control);
+
+ /* Buffer resynch */
+ AST_TEST_REGISTER(jitterbuffer_resynch_voice);
AST_TEST_REGISTER(jitterbuffer_resynch_control);
+
return AST_MODULE_LOAD_SUCCESS;
}
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Jitterbuffer Test");
+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Jitter Buffer Tests");
More information about the asterisk-commits
mailing list