1
/* $Id: jbuf_test.c 3841 2011-10-24 09:28:13Z ming $ */
3
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
#define JB_INIT_PREFETCH 0
26
#define JB_MIN_PREFETCH 0
27
#define JB_MAX_PREFETCH 10
29
#define JB_BUF_SIZE 50
32
//#define PRINT_COMMENT
34
typedef struct test_param_t {
36
unsigned init_prefetch;
37
unsigned min_prefetch;
38
unsigned max_prefetch;
41
typedef struct test_cond_t {
46
int delay; /**< Average delay, in frames. */
47
int delay_min; /**< Minimum delay, in frames. */
50
static pj_bool_t parse_test_headers(char *line, test_param_t *param,
59
sscanf(p+1, "%s %u %u %u", mode_st, ¶m->init_prefetch,
60
¶m->min_prefetch, ¶m->max_prefetch);
61
param->adaptive = (pj_ansi_stricmp(mode_st, "adaptive") == 0);
63
} else if (*p == '!') {
64
/* Success condition. */
68
sscanf(p+1, "%s %u", cond_st, &cond_val);
69
if (pj_ansi_stricmp(cond_st, "burst") == 0)
70
cond->burst = cond_val;
71
else if (pj_ansi_stricmp(cond_st, "delay") == 0)
72
cond->delay = cond_val;
73
else if (pj_ansi_stricmp(cond_st, "delay_min") == 0)
74
cond->delay_min = cond_val;
75
else if (pj_ansi_stricmp(cond_st, "discard") == 0)
76
cond->discard = cond_val;
77
else if (pj_ansi_stricmp(cond_st, "empty") == 0)
78
cond->empty = cond_val;
79
else if (pj_ansi_stricmp(cond_st, "lost") == 0)
80
cond->lost = cond_val;
82
} else if (*p == '=') {
85
while (*p && isspace(*p)) ++p;
88
} else if (*p == '#') {
89
/* Ignore comment line. */
92
/* Unknown header, perhaps this is the test data */
95
while (*p && isspace(*p)) ++p;
97
/* Test data started.*/
105
static pj_bool_t process_test_data(char data, pjmedia_jbuf *jb,
106
pj_uint16_t *seq, pj_uint16_t *last_seq)
110
pj_bool_t print_state = PJ_TRUE;
111
pj_bool_t data_eos = PJ_FALSE;
113
switch (toupper(data)) {
115
pjmedia_jbuf_get_frame(jb, frame, &f_type);
118
pjmedia_jbuf_put_frame(jb, (void*)frame, 1, *seq);
127
case 'R': /* Sequence restarts */
129
printf("Sequence restarting, from %u to %u\n", *last_seq, *seq);
131
case 'J': /* Sequence jumps */
133
printf("Sequence jumping, from %u to %u\n", *last_seq, *seq);
135
case 'D': /* Frame duplicated */
136
pjmedia_jbuf_put_frame(jb, (void*)frame, 1, *seq - 1);
138
case 'O': /* Old/late frame */
139
pjmedia_jbuf_put_frame(jb, (void*)frame, 1, *seq - 10 - pj_rand()%40);
141
case '.': /* End of test session. */
145
print_state = PJ_FALSE;
146
printf("Unknown test data '%c'\n", data);
155
pjmedia_jb_state state;
157
pjmedia_jbuf_get_state(jb, &state);
158
printf("seq=%d\t%c\tsize=%d\tprefetch=%d\n",
159
*last_seq, toupper(data), state.size, state.prefetch);
169
pj_bool_t data_eof = PJ_FALSE;
172
const char* input_filename = "Jbtest.dat";
173
const char* input_search_path[] = {
179
/* Try to open test data file in the working directory */
180
input = fopen(input_filename, "rt");
182
/* If that fails, try to open test data file in specified search paths */
184
char input_path[PJ_MAXPATH];
187
for (i = 0; !input && i < PJ_ARRAY_SIZE(input_search_path); ++i) {
188
pj_ansi_snprintf(input_path, PJ_MAXPATH, "%s/%s",
189
input_search_path[i],
191
input = fopen(input_path, "rt");
195
/* Failed to open test data file. */
197
printf("Failed to open test data file, Jbtest.dat\n");
201
old_log_level = pj_log_get_level();
204
while (rc == 0 && !data_eof) {
205
pj_str_t jb_name = {"JBTEST", 6};
208
pjmedia_jb_state state;
209
pj_uint16_t last_seq = 0;
211
char line[1024], *p = NULL;
216
param.adaptive = PJ_TRUE;
217
param.init_prefetch = JB_INIT_PREFETCH;
218
param.min_prefetch = JB_MIN_PREFETCH;
219
param.max_prefetch = JB_MAX_PREFETCH;
230
/* Parse test session title, param, and conditions */
232
p = fgets(line, sizeof(line), input);
233
} while (p && parse_test_headers(line, ¶m, &cond));
239
//printf("======================================================\n");
241
/* Initialize test session */
242
pool = pj_pool_create(mem, "JBPOOL", 256*16, 256*16, NULL);
243
pjmedia_jbuf_create(pool, &jb_name, 1, JB_PTIME, JB_BUF_SIZE, &jb);
244
pjmedia_jbuf_reset(jb);
246
if (param.adaptive) {
247
pjmedia_jbuf_set_adaptive(jb,
252
pjmedia_jbuf_set_fixed(jb, param.init_prefetch);
256
pjmedia_jbuf_get_state(jb, &state);
257
printf("Initial\tsize=%d\tprefetch=%d\tmin.pftch=%d\tmax.pftch=%d\n",
258
state.size, state.prefetch, state.min_prefetch,
263
/* Test session start */
267
/* Get next line of test data */
269
p = fgets(line, sizeof(line), input);
276
/* Get next char of test data */
283
/* Print comment line */
286
while (*p && isspace(*p)) ++p;
287
if (*p) printf("..%s", p);
293
/* Process test data */
294
if (!process_test_data(c, jb, &seq, &last_seq))
298
/* Print JB states */
299
pjmedia_jbuf_get_state(jb, &state);
300
printf("------------------------------------------------------\n");
301
printf("Summary:\n");
302
printf(" size=%d prefetch=%d\n", state.size, state.prefetch);
303
printf(" delay (min/max/avg/dev)=%d/%d/%d/%d ms\n",
304
state.min_delay, state.max_delay, state.avg_delay,
306
printf(" lost=%d discard=%d empty=%d burst(avg)=%d\n",
307
state.lost, state.discard, state.empty, state.avg_burst);
309
/* Evaluate test session */
310
if (cond.burst >= 0 && (int)state.avg_burst > cond.burst) {
311
printf("! 'Burst' should be %d, it is %d\n",
312
cond.burst, state.avg_burst);
315
if (cond.delay >= 0 && (int)state.avg_delay/JB_PTIME > cond.delay) {
316
printf("! 'Delay' should be %d, it is %d\n",
317
cond.delay, state.avg_delay/JB_PTIME);
320
if (cond.delay_min >= 0 && (int)state.min_delay/JB_PTIME > cond.delay_min) {
321
printf("! 'Minimum delay' should be %d, it is %d\n",
322
cond.delay_min, state.min_delay/JB_PTIME);
325
if (cond.discard >= 0 && (int)state.discard > cond.discard) {
326
printf("! 'Discard' should be %d, it is %d\n",
327
cond.discard, state.discard);
330
if (cond.empty >= 0 && (int)state.empty > cond.empty) {
331
printf("! 'Empty' should be %d, it is %d\n",
332
cond.empty, state.empty);
335
if (cond.lost >= 0 && (int)state.lost > cond.lost) {
336
printf("! 'Lost' should be %d, it is %d\n",
337
cond.lost, state.lost);
341
pjmedia_jbuf_destroy(jb);
342
pj_pool_release(pool);
346
pj_log_set_level(old_log_level);