|
HOME
SIP/media Features
High Performance SIP
Small Footprint SIP
Symbian Port
FAQ
Documentation
Licensing
Download
Development (Trac)
Projects using pjsip
Mailing List
Open Source Links
About: PJLIB, PJLIB-UTIL, PJSIP, and PJMEDIA are created by: Benny Prijono <bennylp pjsip.org>
|
|
Home --> Documentations --> PJMEDIA Reference
Benchmarking pjmedia (conference bridge+resample). For my use only, and it only works in Win32.
This file is pjsip-apps/src/samples/confbench.c
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00033 #include <pjmedia.h>
00034 #include <pjlib-util.h>
00035 #include <pjlib.h>
00036 #include <stdlib.h>
00037 #include <stdio.h>
00038 #include <windows.h>
00039
00040
00041 #define THIS_FILE "confsample.c"
00042
00043
00044
00045
00046
00047
00048
00049 #define TEST_SET LARGE_SET
00050 #define HAS_RESAMPLE 0
00051
00052
00053 #define SMALL_SET 16
00054 #define LARGE_SET 100
00055
00056
00057 #define PORT_COUNT 254
00058 #define CLOCK_RATE 16000
00059 #define SAMPLES_PER_FRAME (CLOCK_RATE/100)
00060 #if HAS_RESAMPLE
00061 # define SINE_CLOCK 32000
00062 #else
00063 # define SINE_CLOCK CLOCK_RATE
00064 #endif
00065 #define SINE_PTIME 20
00066 #define DURATION 10
00067
00068 #define SINE_COUNT TEST_SET
00069 #define NULL_COUNT TEST_SET
00070 #define IDLE_COUNT 32
00071
00072
00073 static void app_perror(const char *sender, const char *title, pj_status_t status)
00074 {
00075 char errmsg[PJ_ERR_MSG_SIZE];
00076
00077 pj_strerror(status, errmsg, sizeof(errmsg));
00078 PJ_LOG(1,(sender, "%s: %s", title, errmsg));
00079 }
00080
00081
00082 struct Times
00083 {
00084 FILETIME kernel_time;
00085 ULARGE_INTEGER u_kernel_time;
00086 FILETIME user_time;
00087 ULARGE_INTEGER u_user_time;
00088 ULARGE_INTEGER u_total;
00089 };
00090
00091 static void process(struct Times *t)
00092 {
00093 pj_memcpy(&t->u_kernel_time, &t->kernel_time, sizeof(FILETIME));
00094 pj_memcpy(&t->u_user_time, &t->user_time, sizeof(FILETIME));
00095 t->u_total.QuadPart = t->u_kernel_time.QuadPart + t->u_user_time.QuadPart;
00096 }
00097
00098 static void benchmark(void)
00099 {
00100 FILETIME creation_time, exit_time;
00101 struct Times start, end;
00102 DWORD ts, te;
00103 LARGE_INTEGER elapsed;
00104 BOOL rc;
00105 int i;
00106 double pct;
00107
00108 puts("Test started!"); fflush(stdout);
00109
00110 ts = GetTickCount();
00111 rc = GetProcessTimes(GetCurrentProcess(), &creation_time, &exit_time,
00112 &start.kernel_time, &start.user_time);
00113 for (i=DURATION; i>0; --i) {
00114 printf("\r%d ", i); fflush(stdout);
00115 pj_thread_sleep(1000);
00116 }
00117 rc = GetProcessTimes(GetCurrentProcess(), &creation_time, &exit_time,
00118 &end.kernel_time, &end.user_time);
00119 te = GetTickCount();
00120
00121 process(&start);
00122 process(&end);
00123
00124 elapsed.QuadPart = end.u_total.QuadPart - start.u_total.QuadPart;
00125
00126 pct = elapsed.QuadPart * 100.0 / ((te-ts)*10000.0);
00127
00128 printf("CPU usage=%6.4f%%\n", pct); fflush(stdout);
00129 }
00130
00131
00132
00133
00134 typedef struct
00135 {
00136 pj_int16_t *samples;
00137 } port_data;
00138
00139
00140
00141 static pj_status_t sine_get_frame( pjmedia_port *port,
00142 pjmedia_frame *frame)
00143 {
00144 port_data *sine = port->port_data.pdata;
00145 pj_int16_t *samples = frame->buf;
00146 unsigned i, count, left, right;
00147
00148
00149 count = frame->size / 2 / port->info.channel_count;
00150
00151 left = 0;
00152 right = 0;
00153
00154 for (i=0; i<count; ++i) {
00155 *samples++ = sine->samples[left];
00156 ++left;
00157
00158 if (port->info.channel_count == 2) {
00159 *samples++ = sine->samples[right];
00160 right += 2;
00161 if (right >= count)
00162 right = 0;
00163 }
00164 }
00165
00166
00167
00168
00169 frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
00170
00171 return PJ_SUCCESS;
00172 }
00173
00174 #ifndef M_PI
00175 #define M_PI (3.14159265)
00176 #endif
00177
00178
00179
00180
00181 static pj_status_t create_sine_port(pj_pool_t *pool,
00182 unsigned sampling_rate,
00183 unsigned channel_count,
00184 pjmedia_port **p_port)
00185 {
00186 pjmedia_port *port;
00187 unsigned i;
00188 unsigned count;
00189 port_data *sine;
00190
00191 PJ_ASSERT_RETURN(pool && channel_count > 0 && channel_count <= 2,
00192 PJ_EINVAL);
00193
00194 port = pj_pool_zalloc(pool, sizeof(pjmedia_port));
00195 PJ_ASSERT_RETURN(port != NULL, PJ_ENOMEM);
00196
00197
00198 port->info.bits_per_sample = 16;
00199 port->info.channel_count = channel_count;
00200 port->info.encoding_name = pj_str("pcm");
00201 port->info.has_info = 1;
00202 port->info.name = pj_str("sine generator");
00203 port->info.need_info = 0;
00204 port->info.pt = 0xFF;
00205 port->info.clock_rate = sampling_rate;
00206 port->info.samples_per_frame = sampling_rate * SINE_PTIME / 1000 * channel_count;
00207 port->info.bytes_per_frame = port->info.samples_per_frame * 2;
00208 port->info.type = PJMEDIA_TYPE_AUDIO;
00209
00210
00211 port->get_frame = &sine_get_frame;
00212
00213
00214 port->port_data.pdata = sine = pj_pool_zalloc(pool, sizeof(port_data));
00215
00216
00217 count = port->info.samples_per_frame / channel_count;
00218 sine->samples = pj_pool_alloc(pool, count * sizeof(pj_int16_t));
00219 PJ_ASSERT_RETURN(sine->samples != NULL, PJ_ENOMEM);
00220
00221
00222 for( i=0; i<count; i++ )
00223 {
00224 sine->samples[i] = (pj_int16_t) (10000.0 *
00225 sin(((double)i/(double)count) * M_PI * 8.) );
00226 }
00227
00228 *p_port = port;
00229
00230 return PJ_SUCCESS;
00231 }
00232
00233 int main()
00234 {
00235 pj_caching_pool cp;
00236 pjmedia_endpt *med_endpt;
00237 pj_pool_t *pool;
00238 pjmedia_conf *conf;
00239 int i;
00240 pjmedia_port *sine_port[SINE_COUNT], *null_port, *conf_port;
00241 pjmedia_port *nulls[NULL_COUNT];
00242 unsigned null_slots[NULL_COUNT];
00243 pjmedia_master_port *master_port;
00244 pj_status_t status;
00245
00246
00247 pj_log_set_level(3);
00248
00249 status = pj_init();
00250 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00251
00252 pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
00253 pool = pj_pool_create( &cp.factory,
00254 "wav",
00255 4000,
00256 4000,
00257 NULL
00258 );
00259
00260 status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
00261 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00262
00263
00264
00265 status = pjmedia_conf_create( pool,
00266 PORT_COUNT,
00267 CLOCK_RATE,
00268 1, SAMPLES_PER_FRAME, 16,
00269 PJMEDIA_CONF_NO_DEVICE,
00270 &conf);
00271 if (status != PJ_SUCCESS) {
00272 app_perror(THIS_FILE, "Unable to create conference bridge", status);
00273 return 1;
00274 }
00275
00276 printf("Resampling is %s\n", (HAS_RESAMPLE?"active":"disabled"));
00277
00278
00279 printf("Creating %d null ports..\n", NULL_COUNT);
00280 for (i=0; i<NULL_COUNT; ++i) {
00281 status = pjmedia_null_port_create(pool, CLOCK_RATE, 1, SAMPLES_PER_FRAME*2, 16, &nulls[i]);
00282 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00283
00284 status = pjmedia_conf_add_port(conf, pool, nulls[i], NULL, &null_slots[i]);
00285 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00286 }
00287
00288
00289 printf("Creating %d sine generator ports..\n", SINE_COUNT);
00290 for (i=0; i<SINE_COUNT; ++i) {
00291 unsigned j, slot;
00292
00293
00294 status = create_sine_port(pool, SINE_CLOCK, 1, &sine_port[i]);
00295 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00296
00297
00298 status = pjmedia_conf_add_port( conf,
00299 pool,
00300 sine_port[i],
00301 NULL,
00302 &slot
00303 );
00304 if (status != PJ_SUCCESS) {
00305 app_perror(THIS_FILE, "Unable to add conference port", status);
00306 return 1;
00307 }
00308
00309 status = pjmedia_conf_connect_port(conf, slot, 0, 0);
00310 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00311
00312 for (j=0; j<NULL_COUNT; ++j) {
00313 status = pjmedia_conf_connect_port(conf, slot, null_slots[j], 0);
00314 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00315 }
00316 }
00317
00318
00319 printf("Creating %d idle ports..\n", IDLE_COUNT);
00320 for (i=0; i<IDLE_COUNT; ++i) {
00321 pjmedia_port *dummy;
00322 status = pjmedia_null_port_create(pool, CLOCK_RATE, 1, SAMPLES_PER_FRAME, 16, &dummy);
00323 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00324 status = pjmedia_conf_add_port(conf, pool, dummy, NULL, NULL);
00325 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00326 }
00327
00328
00329 status = pjmedia_null_port_create(pool, CLOCK_RATE, 1, SAMPLES_PER_FRAME, 16,
00330 &null_port);
00331 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00332
00333 conf_port = pjmedia_conf_get_master_port(conf);
00334
00335
00336 status = pjmedia_master_port_create(pool, null_port, conf_port, 0, &master_port);
00337
00338
00339 pjmedia_master_port_start(master_port);
00340
00341 puts("Waiting to settle.."); fflush(stdout);
00342 pj_thread_sleep(5000);
00343
00344
00345 benchmark();
00346
00347
00348
00349 return 0;
00350 }
00351
00352
PJMEDIA small footprint Open Source media stack
(C)2003-2008 Benny Prijono
|
|