test_jitterbuf.c 35 KB

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