123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350 |
- /*
- * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
- * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
- #include <stdio.h>
- #include <ctype.h>
- #include <pj/pool.h>
- #include "test.h"
- #define JB_INIT_PREFETCH 0
- #define JB_MIN_PREFETCH 0
- #define JB_MAX_PREFETCH 10
- #define JB_PTIME 20
- #define JB_BUF_SIZE 50
- //#define REPORT
- //#define PRINT_COMMENT
- typedef struct test_param_t {
- pj_bool_t adaptive;
- unsigned init_prefetch;
- unsigned min_prefetch;
- unsigned max_prefetch;
- } test_param_t;
- typedef struct test_cond_t {
- int burst;
- int discard;
- int lost;
- int empty;
- int delay; /**< Average delay, in frames. */
- int delay_min; /**< Minimum delay, in frames. */
- } test_cond_t;
- static pj_bool_t parse_test_headers(char *line, test_param_t *param,
- test_cond_t *cond)
- {
- char *p = line;
- if (*p == '%') {
- /* Test params. */
- char mode_st[16];
- sscanf(p+1, "%s %u %u %u", mode_st, ¶m->init_prefetch,
- ¶m->min_prefetch, ¶m->max_prefetch);
- param->adaptive = (pj_ansi_stricmp(mode_st, "adaptive") == 0);
- } else if (*p == '!') {
- /* Success condition. */
- char cond_st[16];
- unsigned cond_val;
- sscanf(p+1, "%s %u", cond_st, &cond_val);
- if (pj_ansi_stricmp(cond_st, "burst") == 0)
- cond->burst = cond_val;
- else if (pj_ansi_stricmp(cond_st, "delay") == 0)
- cond->delay = cond_val;
- else if (pj_ansi_stricmp(cond_st, "delay_min") == 0)
- cond->delay_min = cond_val;
- else if (pj_ansi_stricmp(cond_st, "discard") == 0)
- cond->discard = cond_val;
- else if (pj_ansi_stricmp(cond_st, "empty") == 0)
- cond->empty = cond_val;
- else if (pj_ansi_stricmp(cond_st, "lost") == 0)
- cond->lost = cond_val;
- } else if (*p == '=') {
- /* Test title. */
- ++p;
- while (*p && isspace(*p)) ++p;
- printf("%s", p);
- } else if (*p == '#') {
- /* Ignore comment line. */
- } else {
- /* Unknown header, perhaps this is the test data */
- /* Skip spaces */
- while (*p && isspace(*p)) ++p;
- /* Test data started.*/
- if (*p != 0)
- return PJ_FALSE;
- }
- return PJ_TRUE;
- }
- static pj_bool_t process_test_data(char data, pjmedia_jbuf *jb,
- pj_uint16_t *seq, pj_uint16_t *last_seq)
- {
- char frame[1] = {0};
- char f_type;
- pj_bool_t print_state = PJ_TRUE;
- pj_bool_t data_eos = PJ_FALSE;
- switch (toupper(data)) {
- case 'G': /* Get */
- pjmedia_jbuf_get_frame(jb, frame, &f_type);
- break;
- case 'P': /* Put */
- pjmedia_jbuf_put_frame(jb, (void*)frame, 1, *seq);
- *last_seq = *seq;
- ++*seq;
- break;
- case 'L': /* Lost */
- *last_seq = *seq;
- ++*seq;
- printf("Lost\n");
- break;
- case 'R': /* Sequence restarts */
- *seq = 1;
- printf("Sequence restarting, from %u to %u\n", *last_seq, *seq);
- break;
- case 'J': /* Sequence jumps */
- (*seq) += 20;
- printf("Sequence jumping, from %u to %u\n", *last_seq, *seq);
- break;
- case 'D': /* Frame duplicated */
- pjmedia_jbuf_put_frame(jb, (void*)frame, 1, *seq - 1);
- break;
- case 'O': /* Old/late frame */
- pjmedia_jbuf_put_frame(jb, (void*)frame, 1, *seq - 10 - pj_rand()%40);
- break;
- case '.': /* End of test session. */
- data_eos = PJ_TRUE;
- break;
- default:
- print_state = PJ_FALSE;
- printf("Unknown test data '%c'\n", data);
- break;
- }
- if (data_eos)
- return PJ_FALSE;
- #ifdef REPORT
- if (print_state) {
- pjmedia_jb_state state;
- pjmedia_jbuf_get_state(jb, &state);
- printf("seq=%d\t%c\tsize=%d\tprefetch=%d\n",
- *last_seq, toupper(data), state.size, state.prefetch);
- }
- #else
- PJ_UNUSED_ARG(print_state); /* Warning about variable set but unused */
- #endif
- return PJ_TRUE;
- }
- int jbuf_main(void)
- {
- FILE *input;
- pj_bool_t data_eof = PJ_FALSE;
- int old_log_level;
- int rc = 0;
- const char* input_filename = "Jbtest.dat";
- const char* input_search_path[] = {
- "../build",
- "pjmedia/build",
- "build"
- };
- /* Try to open test data file in the working directory */
- input = fopen(input_filename, "rt");
- /* If that fails, try to open test data file in specified search paths */
- if (input == NULL) {
- char input_path[PJ_MAXPATH];
- unsigned i;
- for (i = 0; !input && i < PJ_ARRAY_SIZE(input_search_path); ++i) {
- pj_ansi_snprintf(input_path, PJ_MAXPATH, "%s/%s",
- input_search_path[i],
- input_filename);
- input = fopen(input_path, "rt");
- }
- }
- /* Failed to open test data file. */
- if (input == NULL) {
- printf("Failed to open test data file, Jbtest.dat\n");
- return -1;
- }
- old_log_level = pj_log_get_level();
- pj_log_set_level(5);
- while (rc == 0 && !data_eof) {
- pj_str_t jb_name = {"JBTEST", 6};
- pjmedia_jbuf *jb;
- pj_pool_t *pool;
- pjmedia_jb_state state;
- pj_uint16_t last_seq = 0;
- pj_uint16_t seq = 1;
- char line[1024], *p = NULL;
- test_param_t param;
- test_cond_t cond;
- param.adaptive = PJ_TRUE;
- param.init_prefetch = JB_INIT_PREFETCH;
- param.min_prefetch = JB_MIN_PREFETCH;
- param.max_prefetch = JB_MAX_PREFETCH;
- cond.burst = -1;
- cond.delay = -1;
- cond.delay_min = -1;
- cond.discard = -1;
- cond.empty = -1;
- cond.lost = -1;
- printf("\n\n");
- /* Parse test session title, param, and conditions */
- do {
- p = fgets(line, sizeof(line), input);
- } while (p && parse_test_headers(line, ¶m, &cond));
- /* EOF test data */
- if (p == NULL)
- break;
- //printf("======================================================\n");
- /* Initialize test session */
- pool = pj_pool_create(mem, "JBPOOL", 256*16, 256*16, NULL);
- pjmedia_jbuf_create(pool, &jb_name, 1, JB_PTIME, JB_BUF_SIZE, &jb);
- pjmedia_jbuf_reset(jb);
- if (param.adaptive) {
- pjmedia_jbuf_set_adaptive(jb,
- param.init_prefetch,
- param.min_prefetch,
- param.max_prefetch);
- } else {
- pjmedia_jbuf_set_fixed(jb, param.init_prefetch);
- }
- #ifdef REPORT
- pjmedia_jbuf_get_state(jb, &state);
- printf("Initial\tsize=%d\tprefetch=%d\tmin.pftch=%d\tmax.pftch=%d\n",
- state.size, state.prefetch, state.min_prefetch,
- state.max_prefetch);
- #endif
- /* Test session start */
- while (1) {
- char c;
- /* Get next line of test data */
- if (!p || *p == 0) {
- p = fgets(line, sizeof(line), input);
- if (p == NULL) {
- data_eof = PJ_TRUE;
- break;
- }
- }
- /* Get next char of test data */
- c = *p++;
- /* Skip spaces */
- if (isspace(c))
- continue;
- /* Print comment line */
- if (c == '#') {
- #ifdef PRINT_COMMENT
- while (*p && isspace(*p)) ++p;
- if (*p) printf("..%s", p);
- #endif
- *p = 0;
- continue;
- }
- /* Process test data */
- if (!process_test_data(c, jb, &seq, &last_seq))
- break;
- }
- /* Print JB states */
- pjmedia_jbuf_get_state(jb, &state);
- printf("------------------------------------------------------\n");
- printf("Summary:\n");
- printf(" size=%d prefetch=%d\n", state.size, state.prefetch);
- printf(" delay (min/max/avg/dev)=%d/%d/%d/%d ms\n",
- state.min_delay, state.max_delay, state.avg_delay,
- state.dev_delay);
- printf(" lost=%d discard=%d empty=%d burst(avg)=%d\n",
- state.lost, state.discard, state.empty, state.avg_burst);
- /* Evaluate test session */
- if (cond.burst >= 0 && (int)state.avg_burst > cond.burst) {
- printf("! 'Burst' should be %d, it is %d\n",
- cond.burst, state.avg_burst);
- rc |= 1;
- }
- if (cond.delay >= 0 && (int)state.avg_delay/JB_PTIME > cond.delay) {
- printf("! 'Delay' should be %d, it is %d\n",
- cond.delay, state.avg_delay/JB_PTIME);
- rc |= 2;
- }
- if (cond.delay_min >= 0 && (int)state.min_delay/JB_PTIME > cond.delay_min) {
- printf("! 'Minimum delay' should be %d, it is %d\n",
- cond.delay_min, state.min_delay/JB_PTIME);
- rc |= 32;
- }
- if (cond.discard >= 0 && (int)state.discard > cond.discard) {
- printf("! 'Discard' should be %d, it is %d\n",
- cond.discard, state.discard);
- rc |= 4;
- }
- if (cond.empty >= 0 && (int)state.empty > cond.empty) {
- printf("! 'Empty' should be %d, it is %d\n",
- cond.empty, state.empty);
- rc |= 8;
- }
- if (cond.lost >= 0 && (int)state.lost > cond.lost) {
- printf("! 'Lost' should be %d, it is %d\n",
- cond.lost, state.lost);
- rc |= 16;
- }
- pjmedia_jbuf_destroy(jb);
- pj_pool_release(pool);
- }
- fclose(input);
- pj_log_set_level(old_log_level);
- return rc;
- }
|