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