1
2 /*
3 mediastreamer2 library - modular sound and video processing and streaming
4 Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org)
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21
22 #include "mediastreamer2/msticker.h"
23
24 #include "mediastreamer2/msrtp.h"
25 #include "mediastreamer2/msfileplayer.h"
26 #include "mediastreamer2/msfilerec.h"
27
28 #include <signal.h>
29
30 #define MAX_RTP_SIZE 1500
31
32 static int run=1;
33
stop(int signum)34 static void stop(int signum){
35 run=0;
36 }
37
38 struct test_session {
39 RtpSession *rtps;
40
41 MSFilter *fplayer;
42 MSFilter *encoder;
43 MSFilter *rtpsend;
44
45 MSFilter *rtprecv;
46 MSFilter *decoder;
47 MSFilter *frecorder;
48 };
49
50 struct bench_config {
51 int num_session;
52 int num_session_record;
53
54 int port_origin;
55 char *ip_destination;
56 int port_destination;
57
58 int payload;
59 int rate;
60 int ptime;
61 char *wavfile;
62
63 MSFactory *factory;
64 MSTicker *ticker;
65 bctbx_list_t *tsessions; /* list of struct test_session */
66 };
67
68 #define NUM_SESSION 50 /* num of session to start per block */
69 #define NUM_SESSION_RECORD 1
70
71 struct bench_config cfg[] = {
72 { NUM_SESSION,NUM_SESSION_RECORD,
73 8000,"127.0.0.1",9000,
74 8,8000,20,"test1.wav",
75 NULL,NULL,NULL },
76
77 { NUM_SESSION,NUM_SESSION_RECORD,
78 9000,"127.0.0.1",8000,
79 8,8000,20,"test1.wav",
80 NULL,NULL,NULL },
81
82 { NUM_SESSION,NUM_SESSION_RECORD,
83 10000,"127.0.0.1",11000,
84 8,8000,20,"test1.wav",
85 NULL,NULL,NULL },
86
87 { NUM_SESSION,NUM_SESSION_RECORD,
88 11000,"127.0.0.1",10000,
89 8,8000,20,"test1.wav",
90 NULL,NULL,NULL },
91
92 { 0,0,0,"",0,0,0,0,NULL,NULL,NULL,NULL },
93 };
94
create_duplex_rtpsession(int locport)95 static RtpSession *create_duplex_rtpsession(int locport){
96 RtpSession *rtpr;
97 rtpr=rtp_session_new(RTP_SESSION_SENDRECV);
98 rtp_session_set_recv_buf_size(rtpr,MAX_RTP_SIZE);
99 rtp_session_set_scheduling_mode(rtpr,0);
100 rtp_session_set_blocking_mode(rtpr,0);
101 rtp_session_enable_adaptive_jitter_compensation(rtpr,FALSE);
102 rtp_session_set_symmetric_rtp(rtpr,TRUE);
103 rtp_session_set_local_addr(rtpr,"0.0.0.0",locport,locport+1);
104 rtp_session_signal_connect(rtpr,"timestamp_jump",(RtpCallback)rtp_session_resync,NULL);
105 rtp_session_signal_connect(rtpr,"ssrc_changed",(RtpCallback)rtp_session_resync,NULL);
106 return rtpr;
107 }
108
init_bench(struct bench_config * bench)109 static int init_bench(struct bench_config *bench)
110 {
111 PayloadType *pt;
112 int pos;
113 int val;
114 int count;
115
116 bench->factory = ms_factory_new_with_voip();
117 bench->ticker=ms_ticker_new();
118
119 count = 0;
120 /* creates the couple of encoder/decoder */
121 pt=rtp_profile_get_payload(&av_profile,bench->payload);
122 if (pt==NULL){
123 ms_error("audiostream.c: undefined payload type.");
124 return count;
125 }
126 if (pt->clock_rate!=8000 && pt->clock_rate!=16000 && pt->clock_rate!=32000){
127 ms_error("audiostream.c: wrong rate.");
128 return count;
129 }
130 for (pos=0;pos<bench->num_session;pos++)
131 {
132 struct test_session *ts = (struct test_session *)ortp_malloc(sizeof(struct test_session));
133 memset(ts, 0, sizeof(struct test_session));
134
135 ts->rtps = create_duplex_rtpsession(bench->port_origin+pos*2);
136 if (ts->rtps==NULL)
137 {
138 ms_error("bench.c: cannot create rtp_session!");
139 ortp_free(ts);
140 return count;
141 }
142
143 rtp_session_set_payload_type(ts->rtps,bench->payload);
144 rtp_session_set_remote_addr_full(ts->rtps,
145 bench->ip_destination,
146 bench->port_destination+pos*2,
147 bench->ip_destination,
148 bench->port_destination+1+pos*2);
149
150 ts->fplayer = ms_factory_create_filter(bench->factory, MS_FILE_PLAYER_ID);
151 if (strstr(bench->wavfile, ".au")==NULL)
152 ts->encoder = ms_factory_create_encoder(bench->factory, pt->mime_type);
153 ts->rtpsend = ms_factory_create_filter(bench->factory, MS_RTP_SEND_ID);
154
155 ts->rtprecv = ms_factory_create_filter(bench->factory, MS_RTP_RECV_ID);
156 ts->decoder = ms_factory_create_decoder(bench->factory, pt->mime_type);
157 ts->frecorder = ms_factory_create_filter(bench->factory, MS_FILE_REC_ID);
158
159 if ((ts->encoder==NULL && strstr(bench->wavfile, ".au")==NULL)
160 || (ts->decoder==NULL )){
161 ms_error("bench.c: No decoder available for payload %i.",bench->payload);
162 if (ts->fplayer) ms_filter_destroy(ts->fplayer);
163 if (ts->encoder) ms_filter_destroy(ts->encoder);
164 if (ts->rtpsend) ms_filter_destroy(ts->rtpsend);
165 if (ts->rtprecv) ms_filter_destroy(ts->rtprecv);
166 if (ts->decoder) ms_filter_destroy(ts->decoder);
167 if (ts->frecorder) ms_filter_destroy(ts->frecorder);
168 ortp_free(ts);
169 return count;
170 }
171 if (ts->fplayer==NULL){
172 ms_error("bench.c: missing player filter.");
173 if (ts->fplayer) ms_filter_destroy(ts->fplayer);
174 if (ts->encoder) ms_filter_destroy(ts->encoder);
175 if (ts->rtpsend) ms_filter_destroy(ts->rtpsend);
176 if (ts->rtprecv) ms_filter_destroy(ts->rtprecv);
177 if (ts->decoder) ms_filter_destroy(ts->decoder);
178 if (ts->frecorder) ms_filter_destroy(ts->frecorder);
179 ortp_free(ts);
180 return count;
181 }
182 if (ts->frecorder==NULL){
183 ms_error("bench.c: missing recorder filter.");
184 if (ts->fplayer) ms_filter_destroy(ts->fplayer);
185 if (ts->encoder) ms_filter_destroy(ts->encoder);
186 if (ts->rtpsend) ms_filter_destroy(ts->rtpsend);
187 if (ts->rtprecv) ms_filter_destroy(ts->rtprecv);
188 if (ts->decoder) ms_filter_destroy(ts->decoder);
189 if (ts->frecorder) ms_filter_destroy(ts->frecorder);
190 ortp_free(ts);
191 return count;
192 }
193 if (ts->rtpsend==NULL){
194 ms_error("bench.c: missing rtpsend filter.");
195 if (ts->fplayer) ms_filter_destroy(ts->fplayer);
196 if (ts->encoder) ms_filter_destroy(ts->encoder);
197 if (ts->rtpsend) ms_filter_destroy(ts->rtpsend);
198 if (ts->rtprecv) ms_filter_destroy(ts->rtprecv);
199 if (ts->decoder) ms_filter_destroy(ts->decoder);
200 if (ts->frecorder) ms_filter_destroy(ts->frecorder);
201 ortp_free(ts);
202 return count;
203 }
204 if (ts->rtprecv==NULL){
205 ms_error("bench.c: missing rtprecv filter.");
206 if (ts->fplayer) ms_filter_destroy(ts->fplayer);
207 if (ts->encoder) ms_filter_destroy(ts->encoder);
208 if (ts->rtpsend) ms_filter_destroy(ts->rtpsend);
209 if (ts->rtprecv) ms_filter_destroy(ts->rtprecv);
210 if (ts->decoder) ms_filter_destroy(ts->decoder);
211 if (ts->frecorder) ms_filter_destroy(ts->frecorder);
212 ortp_free(ts);
213 return count;
214 }
215
216 ms_filter_call_method(ts->rtpsend,MS_RTP_SEND_SET_SESSION,ts->rtps);
217 ms_filter_call_method(ts->rtprecv,MS_RTP_RECV_SET_SESSION,ts->rtps);
218
219 ms_filter_call_method (ts->rtprecv, MS_FILTER_SET_SAMPLE_RATE,
220 &pt->clock_rate);
221
222 ms_filter_call_method (ts->frecorder, MS_FILTER_SET_SAMPLE_RATE,
223 &pt->clock_rate);
224
225 val = ms_filter_call_method(ts->fplayer,MS_FILE_PLAYER_OPEN,(void*)bench->wavfile);
226 if (val!=0)
227 {
228 ms_error("bench.c: Cannot open wav file (%s)", bench->wavfile);
229 if (ts->fplayer) ms_filter_destroy(ts->fplayer);
230 if (ts->encoder) ms_filter_destroy(ts->encoder);
231 if (ts->rtpsend) ms_filter_destroy(ts->rtpsend);
232 if (ts->rtprecv) ms_filter_destroy(ts->rtprecv);
233 if (ts->decoder) ms_filter_destroy(ts->decoder);
234 if (ts->frecorder) ms_filter_destroy(ts->frecorder);
235 ortp_free(ts);
236 return count;
237 }
238
239 val=0;
240 ms_filter_call_method (ts->fplayer, MS_FILTER_GET_SAMPLE_RATE,
241 &val);
242 if (val!=pt->clock_rate)
243 {
244 ms_error("bench.c: unsupported rate for wav file: codec=%i / file=%i",
245 pt->clock_rate, val);
246 if (ts->fplayer) ms_filter_destroy(ts->fplayer);
247 if (ts->encoder) ms_filter_destroy(ts->encoder);
248 if (ts->rtpsend) ms_filter_destroy(ts->rtpsend);
249 if (ts->rtprecv) ms_filter_destroy(ts->rtprecv);
250 if (ts->decoder) ms_filter_destroy(ts->decoder);
251 if (ts->frecorder) ms_filter_destroy(ts->frecorder);
252 ortp_free(ts);
253 return count;
254 }
255 ms_filter_call_method (ts->fplayer, MS_FILTER_GET_NCHANNELS,
256 &val);
257
258 if (val!=1)
259 {
260 ms_error("bench.c: unsupported number of channel for wav file: codec=1 / file=%i",
261 val);
262 if (ts->fplayer) ms_filter_destroy(ts->fplayer);
263 if (ts->encoder) ms_filter_destroy(ts->encoder);
264 if (ts->rtpsend) ms_filter_destroy(ts->rtpsend);
265 if (ts->rtprecv) ms_filter_destroy(ts->rtprecv);
266 if (ts->decoder) ms_filter_destroy(ts->decoder);
267 if (ts->frecorder) ms_filter_destroy(ts->frecorder);
268 ortp_free(ts);
269 return count;
270 }
271 ms_filter_call_method_noarg(ts->fplayer,MS_FILE_PLAYER_START);
272
273 if (strstr(bench->wavfile, ".au")==NULL)
274 {
275 ms_filter_link(ts->fplayer,0,ts->encoder,0);
276 ms_filter_link(ts->encoder,0,ts->rtpsend,0);
277 }
278 else
279 {
280 ms_filter_link(ts->fplayer,0,ts->rtpsend,0);
281 }
282
283 ms_filter_link(ts->rtprecv,0,ts->decoder,0);
284 ms_filter_link(ts->decoder,0,ts->frecorder,0);
285
286 ms_ticker_attach(bench->ticker,ts->fplayer);
287 ms_ticker_attach(bench->ticker,ts->rtprecv);
288
289 if (pos < bench->num_session_record)
290 {
291 char rec_file[128];
292 snprintf(rec_file, sizeof(rec_file), "rec_%s_%i.wav",
293 bench->ip_destination,
294 bench->port_destination+pos*2);
295 ms_filter_call_method(ts->frecorder,MS_FILE_REC_OPEN,(void*)rec_file);
296 ms_filter_call_method_noarg(ts->frecorder,MS_FILE_REC_START);
297 }
298
299 bench->tsessions = bctbx_list_append(bench->tsessions, (void*)ts);
300 count++;
301 }
302
303 return count;
304 }
305
uninit_bench(struct bench_config * bench)306 static int uninit_bench(struct bench_config *bench)
307 {
308 bctbx_list_t *it;
309 for(it=bench->tsessions;it!=NULL;it=bench->tsessions){
310 struct test_session *ts = (struct test_session *)it->data;
311 bench->tsessions = bctbx_list_erase_link(bench->tsessions, it);
312
313 ms_ticker_detach(bench->ticker,ts->fplayer);
314 ms_ticker_detach(bench->ticker,ts->rtprecv);
315
316 ms_filter_call_method_noarg(ts->frecorder,MS_FILE_REC_CLOSE);
317
318 if (strstr(bench->wavfile, ".au")==NULL)
319 {
320 ms_filter_unlink(ts->fplayer,0,ts->encoder,0);
321 ms_filter_unlink(ts->encoder,0,ts->rtpsend,0);
322 }
323 else
324 {
325 ms_filter_unlink(ts->fplayer,0,ts->rtpsend,0);
326 }
327
328 ms_filter_unlink(ts->rtprecv,0,ts->decoder,0);
329 ms_filter_unlink(ts->decoder,0,ts->frecorder,0);
330
331 if (ts->fplayer) ms_filter_destroy(ts->fplayer);
332 if (ts->encoder) ms_filter_destroy(ts->encoder);
333 if (ts->rtpsend) ms_filter_destroy(ts->rtpsend);
334
335 if (ts->rtprecv) ms_filter_destroy(ts->rtprecv);
336 if (ts->decoder) ms_filter_destroy(ts->decoder);
337 if (ts->frecorder) ms_filter_destroy(ts->frecorder);
338
339 ortp_free(ts);
340 }
341
342 ms_ticker_destroy(bench->ticker);
343 ms_factory_destroy(bench->factory);
344 return 0;
345 }
346
347
main(int argc,char * argv[])348 int main(int argc, char *argv[]){
349 int pos;
350 int count;
351 ortp_init();
352 ortp_set_log_level_mask(ORTP_LOG_DOMAIN, ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL);
353
354
355
356 rtp_profile_set_payload(&av_profile,115,&payload_type_lpc1015);
357 rtp_profile_set_payload(&av_profile,110,&payload_type_speex_nb);
358 rtp_profile_set_payload(&av_profile,111,&payload_type_speex_wb);
359 rtp_profile_set_payload(&av_profile,112,&payload_type_ilbc);
360
361 signal(SIGINT,stop);
362
363 count=0;
364 for (pos=0;cfg[pos].num_session!=0;pos++)
365 {
366 count = count + init_bench( &cfg[pos]);
367 ms_sleep(10);
368 }
369
370 ms_message("Number of session started: %i.", count);
371
372 while(run)
373 ms_sleep(1);
374
375 for (pos=0;cfg[pos].num_session!=0;pos++)
376 {
377 uninit_bench(&cfg[pos]);
378 }
379
380
381
382 return 0;
383 }
384
385