blob: c2a3b1d4d90daa67e73ace74f8656579db93f7b2 [file] [log] [blame]
Benny Prijono5dcb38d2005-11-21 01:55:47 +00001/* $Id$ */
2/*
Benny Prijono844653c2008-12-23 17:27:53 +00003 * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
Benny Prijono32177c02008-06-20 22:44:47 +00004 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
Benny Prijono5dcb38d2005-11-21 01:55:47 +00005 *
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.
10 *
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.
15 *
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
19 */
20#include <stdio.h>
21#include <ctype.h>
Benny Prijono5dcb38d2005-11-21 01:55:47 +000022#include <pj/pool.h>
Benny Prijonocf5c06d2008-03-26 16:18:17 +000023#include "test.h"
Benny Prijono5dcb38d2005-11-21 01:55:47 +000024
Benny Prijonocf5c06d2008-03-26 16:18:17 +000025#define JB_INIT_PREFETCH 0
26#define JB_MIN_PREFETCH 0
27#define JB_MAX_PREFETCH 10
28#define JB_PTIME 20
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +000029#define JB_BUF_SIZE 50
Benny Prijono5dcb38d2005-11-21 01:55:47 +000030
Benny Prijono1dc0da72009-04-18 00:12:13 +000031//#define REPORT
Benny Prijono5dcb38d2005-11-21 01:55:47 +000032//#define PRINT_COMMENT
33
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +000034typedef struct test_param_t {
35 pj_bool_t adaptive;
36 unsigned init_prefetch;
37 unsigned min_prefetch;
38 unsigned max_prefetch;
39} test_param_t;
40
41typedef struct test_cond_t {
42 int burst;
43 int discard;
44 int lost;
45 int empty;
46 int delay; /**< Maximum delay, in frames. */
47} test_cond_t;
48
49static pj_bool_t parse_test_headers(char *line, test_param_t *param,
50 test_cond_t *cond)
51{
52 char *p = line;
53
54 if (*p == '%') {
55 /* Test params. */
56 char mode_st[16];
57
58 sscanf(p+1, "%s %u %u %u", mode_st, &param->init_prefetch,
59 &param->min_prefetch, &param->max_prefetch);
Nanang Izzuddin55496672009-04-08 18:41:32 +000060 param->adaptive = (pj_ansi_stricmp(mode_st, "adaptive") == 0);
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +000061
62 } else if (*p == '!') {
63 /* Success condition. */
64 char cond_st[16];
65 unsigned cond_val;
66
67 sscanf(p+1, "%s %u", cond_st, &cond_val);
Nanang Izzuddin55496672009-04-08 18:41:32 +000068 if (pj_ansi_stricmp(cond_st, "burst") == 0)
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +000069 cond->burst = cond_val;
Nanang Izzuddin55496672009-04-08 18:41:32 +000070 else if (pj_ansi_stricmp(cond_st, "delay") == 0)
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +000071 cond->delay = cond_val;
Nanang Izzuddin55496672009-04-08 18:41:32 +000072 else if (pj_ansi_stricmp(cond_st, "discard") == 0)
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +000073 cond->discard = cond_val;
Nanang Izzuddin55496672009-04-08 18:41:32 +000074 else if (pj_ansi_stricmp(cond_st, "empty") == 0)
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +000075 cond->empty = cond_val;
Nanang Izzuddin55496672009-04-08 18:41:32 +000076 else if (pj_ansi_stricmp(cond_st, "lost") == 0)
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +000077 cond->lost = cond_val;
78
79 } else if (*p == '=') {
80 /* Test title. */
81 ++p;
82 while (*p && isspace(*p)) ++p;
83 printf("%s", p);
Nanang Izzuddinb6f66bc2010-01-20 01:02:37 +000084
85 } else if (*p == '#') {
86 /* Ignore comment line. */
87
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +000088 } else {
89 /* Unknown header, perhaps this is the test data */
90
91 /* Skip spaces */
92 while (*p && isspace(*p)) ++p;
93
94 /* Test data started.*/
95 if (*p != 0)
96 return PJ_FALSE;
97 }
98
99 return PJ_TRUE;
100}
101
102static pj_bool_t process_test_data(char data, pjmedia_jbuf *jb,
103 pj_uint16_t *seq, pj_uint16_t *last_seq)
104{
105 char frame[1];
106 char f_type;
107 pj_bool_t print_state = PJ_TRUE;
108 pj_bool_t data_eos = PJ_FALSE;
109
110 switch (toupper(data)) {
111 case 'G': /* Get */
112 pjmedia_jbuf_get_frame(jb, frame, &f_type);
113 break;
114 case 'P': /* Put */
115 pjmedia_jbuf_put_frame(jb, (void*)frame, 1, *seq);
116 *last_seq = *seq;
117 ++*seq;
118 break;
119 case 'L': /* Lost */
120 *last_seq = *seq;
121 ++*seq;
122 printf("Lost\n");
123 break;
124 case 'R': /* Sequence restarts */
125 *seq = 1;
126 printf("Sequence restarting, from %u to %u\n", *last_seq, *seq);
127 break;
128 case 'J': /* Sequence jumps */
Nanang Izzuddinb6f66bc2010-01-20 01:02:37 +0000129 (*seq) += 20;
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +0000130 printf("Sequence jumping, from %u to %u\n", *last_seq, *seq);
131 break;
132 case 'D': /* Frame duplicated */
133 pjmedia_jbuf_put_frame(jb, (void*)frame, 1, *seq - 1);
134 break;
135 case 'O': /* Old/late frame */
136 pjmedia_jbuf_put_frame(jb, (void*)frame, 1, *seq - 10 - pj_rand()%40);
137 break;
138 case '.': /* End of test session. */
139 data_eos = PJ_TRUE;
140 break;
141 default:
142 print_state = PJ_FALSE;
143 printf("Unknown test data '%c'\n", data);
144 break;
145 }
146
147 if (data_eos)
148 return PJ_FALSE;
149
150#ifdef REPORT
151 if (print_state) {
152 pjmedia_jb_state state;
153
154 pjmedia_jbuf_get_state(jb, &state);
155 printf("seq=%d\t%c\tsize=%d\tprefetch=%d\n",
156 *last_seq, toupper(data), state.size, state.prefetch);
157 }
158#endif
159
160 return PJ_TRUE;
161}
162
Benny Prijonocf5c06d2008-03-26 16:18:17 +0000163int jbuf_main(void)
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000164{
Nanang Izzuddind3708c32009-06-18 15:49:06 +0000165 FILE *input;
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +0000166 pj_bool_t data_eof = PJ_FALSE;
167 int old_log_level;
168 int rc = 0;
Nanang Izzuddind3708c32009-06-18 15:49:06 +0000169 const char* input_filename = "Jbtest.dat";
170 const char* input_search_path[] = {
Benny Prijono681a8bf2009-08-15 09:08:11 +0000171 "../build",
172 "pjmedia/build",
173 "build"
Nanang Izzuddind3708c32009-06-18 15:49:06 +0000174 };
175
176 /* Try to open test data file in the working directory */
177 input = fopen(input_filename, "rt");
178
179 /* If that fails, try to open test data file in specified search paths */
180 if (input == NULL) {
181 char input_path[PJ_MAXPATH];
182 int i;
183
184 for (i = 0; !input && i < PJ_ARRAY_SIZE(input_search_path); ++i) {
185 pj_ansi_snprintf(input_path, PJ_MAXPATH, "%s/%s",
186 input_search_path[i],
187 input_filename);
188 input = fopen(input_path, "rt");
189 }
190 }
191
192 /* Failed to open test data file. */
193 if (input == NULL) {
194 printf("Failed to open test data file, Jbtest.dat\n");
195 return -1;
196 }
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000197
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +0000198 old_log_level = pj_log_get_level();
199 pj_log_set_level(5);
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000200
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +0000201 while (rc == 0 && !data_eof) {
202 pj_str_t jb_name = {"JBTEST", 6};
203 pjmedia_jbuf *jb;
204 pj_pool_t *pool;
205 pjmedia_jb_state state;
206 pj_uint16_t last_seq = 0;
207 pj_uint16_t seq = 1;
208 char line[1024], *p = NULL;
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000209
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +0000210 test_param_t param;
211 test_cond_t cond;
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000212
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +0000213 param.adaptive = PJ_TRUE;
214 param.init_prefetch = JB_INIT_PREFETCH;
215 param.min_prefetch = JB_MIN_PREFETCH;
216 param.max_prefetch = JB_MAX_PREFETCH;
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000217
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +0000218 cond.burst = -1;
219 cond.delay = -1;
220 cond.discard = -1;
221 cond.empty = -1;
222 cond.lost = -1;
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000223
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +0000224 printf("\n\n");
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000225
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +0000226 /* Parse test session title, param, and conditions */
227 do {
228 p = fgets(line, sizeof(line), input);
229 } while (p && parse_test_headers(line, &param, &cond));
230
231 /* EOF test data */
232 if (p == NULL)
233 break;
234
235 //printf("======================================================\n");
236
237 /* Initialize test session */
238 pool = pj_pool_create(mem, "JBPOOL", 256*16, 256*16, NULL);
239 pjmedia_jbuf_create(pool, &jb_name, 1, JB_PTIME, JB_BUF_SIZE, &jb);
Benny Prijonocf5c06d2008-03-26 16:18:17 +0000240 pjmedia_jbuf_reset(jb);
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +0000241
242 if (param.adaptive) {
243 pjmedia_jbuf_set_adaptive(jb,
244 param.init_prefetch,
245 param.min_prefetch,
246 param.max_prefetch);
247 } else {
248 pjmedia_jbuf_set_fixed(jb, param.init_prefetch);
249 }
Benny Prijonocf5c06d2008-03-26 16:18:17 +0000250
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000251#ifdef REPORT
Benny Prijonocf5c06d2008-03-26 16:18:17 +0000252 pjmedia_jbuf_get_state(jb, &state);
253 printf("Initial\tsize=%d\tprefetch=%d\tmin.pftch=%d\tmax.pftch=%d\n",
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +0000254 state.size, state.prefetch, state.min_prefetch,
255 state.max_prefetch);
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000256#endif
257
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +0000258
259 /* Test session start */
260 while (1) {
Nanang Izzuddin2e4f03f2009-04-27 19:18:38 +0000261 char c;
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000262
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +0000263 /* Get next line of test data */
264 if (!p || *p == 0) {
265 p = fgets(line, sizeof(line), input);
266 if (p == NULL) {
267 data_eof = PJ_TRUE;
268 break;
269 }
270 }
271
272 /* Get next char of test data */
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000273 c = *p++;
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +0000274
275 /* Skip spaces */
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000276 if (isspace(c))
277 continue;
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000278
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +0000279 /* Print comment line */
280 if (c == '#') {
281#ifdef PRINT_COMMENT
282 while (*p && isspace(*p)) ++p;
283 if (*p) printf("..%s", p);
284#endif
285 *p = 0;
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000286 continue;
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000287 }
288
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +0000289 /* Process test data */
290 if (!process_test_data(c, jb, &seq, &last_seq))
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000291 break;
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000292 }
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +0000293
294 /* Print JB states */
295 pjmedia_jbuf_get_state(jb, &state);
296 printf("------------------------------------------------------\n");
297 printf("Summary:\n");
298 printf(" size=%d prefetch=%d\n", state.size, state.prefetch);
299 printf(" delay (min/max/avg/dev)=%d/%d/%d/%d ms\n",
300 state.min_delay, state.max_delay, state.avg_delay,
301 state.dev_delay);
302 printf(" lost=%d discard=%d empty=%d burst(avg)=%d\n",
303 state.lost, state.discard, state.empty, state.avg_burst);
304
305 /* Evaluate test session */
306 if (cond.burst >= 0 && (int)state.avg_burst > cond.burst) {
307 printf("! 'Burst' should be %d, it is %d\n",
308 cond.burst, state.avg_burst);
309 rc |= 1;
310 }
311 if (cond.delay >= 0 && (int)state.avg_delay/JB_PTIME > cond.delay) {
312 printf("! 'Delay' should be %d, it is %d\n",
313 cond.delay, state.avg_delay/JB_PTIME);
314 rc |= 2;
315 }
316 if (cond.discard >= 0 && (int)state.discard > cond.discard) {
317 printf("! 'Discard' should be %d, it is %d\n",
318 cond.discard, state.discard);
319 rc |= 4;
320 }
321 if (cond.empty >= 0 && (int)state.empty > cond.empty) {
322 printf("! 'Empty' should be %d, it is %d\n",
323 cond.empty, state.empty);
324 rc |= 8;
325 }
326 if (cond.lost >= 0 && (int)state.lost > cond.lost) {
327 printf("! 'Lost' should be %d, it is %d\n",
328 cond.lost, state.lost);
329 rc |= 16;
330 }
331
332 pjmedia_jbuf_destroy(jb);
333 pj_pool_release(pool);
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000334 }
335
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +0000336 fclose(input);
337 pj_log_set_level(old_log_level);
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000338
Nanang Izzuddinad4bb0a2009-04-06 17:13:33 +0000339 return rc;
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000340}