mediastreamer2_tester_private.c 10.1 KB
Newer Older
Ghislain MARY's avatar
Ghislain MARY committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
mediastreamer2 library - modular sound and video processing and streaming
Copyright (C) 2006-2013 Belledonne Communications, Grenoble

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#include "mediastreamer2_tester_private.h"
21
#include "bc_tester_utils.h"
Ghislain MARY's avatar
Ghislain MARY committed
22 23 24 25 26 27 28

#include "mediastreamer2/dtmfgen.h"
#include "mediastreamer2/msfileplayer.h"
#include "mediastreamer2/msfilerec.h"
#include "mediastreamer2/msrtp.h"
#include "mediastreamer2/mssndcard.h"
#include "mediastreamer2/mstonedetector.h"
29
#include "mediastreamer2/mswebcam.h"
Ghislain MARY's avatar
Ghislain MARY committed
30 31 32 33 34 35 36 37 38


typedef struct {
	MSDtmfGenCustomTone generated_tone;
	MSToneDetectorDef expected_tone;
} tone_test_def_t;


static tone_test_def_t tone_definition[] = {
Simon Morlat's avatar
Simon Morlat committed
39 40 41
	{ { "", 400, {2000,0}, 0.6f, 0 }, { "", 2000, 300, 0.5f } },
	{ { "", 600, {1500,0}, 1.0f, 0 }, { "", 1500, 500, 0.9f } },
	{ { "", 500,  {941,0}, 0.8f, 0 }, { "",  941, 400, 0.7f } }
Ghislain MARY's avatar
Ghislain MARY committed
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
};


MSTicker *ms_tester_ticker = NULL;
MSFilter *ms_tester_fileplay = NULL;
MSFilter *ms_tester_filerec = NULL;
MSFilter *ms_tester_dtmfgen = NULL;
MSFilter *ms_tester_tonedet = NULL;
MSFilter *ms_tester_voidsource = NULL;
MSFilter *ms_tester_voidsink = NULL;
MSFilter *ms_tester_encoder = NULL;
MSFilter *ms_tester_decoder = NULL;
MSFilter *ms_tester_rtprecv = NULL;
MSFilter *ms_tester_rtpsend = NULL;
MSFilter *ms_tester_resampler = NULL;
MSFilter *ms_tester_soundwrite = NULL;
58
MSFilter *ms_tester_soundread = NULL;
59
MSFilter *ms_tester_videocapture = NULL;
60
char *ms_tester_codec_mime = "pcmu";
Ghislain MARY's avatar
Ghislain MARY committed
61 62 63 64 65 66 67 68 69 70 71 72
unsigned char ms_tester_tone_detected;


static MSTicker * create_ticker(void) {
	MSTickerParams params;
	params.name = "Tester MSTicker";
	params.prio = MS_TICKER_PRIO_NORMAL;
	return ms_ticker_new_with_params(&params);
}


void ms_tester_create_ticker(void) {
73
	BC_ASSERT_PTR_NULL(ms_tester_ticker);
Ghislain MARY's avatar
Ghislain MARY committed
74
	ms_tester_ticker = create_ticker();
75
	BC_ASSERT_PTR_NOT_NULL_FATAL(ms_tester_ticker);
Ghislain MARY's avatar
Ghislain MARY committed
76 77 78 79 80 81 82 83 84 85 86
}

void ms_tester_destroy_ticker(void) {
	if (ms_tester_ticker) {
		ms_ticker_destroy(ms_tester_ticker);
		ms_tester_ticker = NULL;
	}
}

#define CREATE_FILTER(mask, filter, id) \
	if (filter_mask & mask) { \
87
		BC_ASSERT_PTR_NULL(filter); \
Ghislain MARY's avatar
Ghislain MARY committed
88
		filter = ms_filter_new(id); \
89
		BC_ASSERT_PTR_NOT_NULL_FATAL(filter); \
Ghislain MARY's avatar
Ghislain MARY committed
90 91
	}

92
void ms_tester_create_filter(MSFilter **filter, MSFilterId id) {
93 94
	BC_ASSERT_PTR_NOT_NULL(filter);
	BC_ASSERT_PTR_NULL(*filter);
95
	*filter = ms_filter_new(id);
96
	BC_ASSERT_PTR_NOT_NULL_FATAL(*filter);
97 98
}

Ghislain MARY's avatar
Ghislain MARY committed
99
void ms_tester_create_filters(unsigned int filter_mask) {
100 101
	MSSndCardManager *snd_manager;
	MSWebCamManager *cam_manager;
Ghislain MARY's avatar
Ghislain MARY committed
102
	MSSndCard *playcard;
103
	MSSndCard *captcard;
104
	MSWebCam *camera;
Ghislain MARY's avatar
Ghislain MARY committed
105 106 107 108 109 110 111

	CREATE_FILTER(FILTER_MASK_FILEPLAY, ms_tester_fileplay, MS_FILE_PLAYER_ID);
	CREATE_FILTER(FILTER_MASK_FILEREC, ms_tester_filerec, MS_FILE_REC_ID);
	CREATE_FILTER(FILTER_MASK_DTMFGEN, ms_tester_dtmfgen, MS_DTMF_GEN_ID);
	CREATE_FILTER(FILTER_MASK_TONEDET, ms_tester_tonedet, MS_TONE_DETECTOR_ID);
	CREATE_FILTER(FILTER_MASK_VOIDSOURCE, ms_tester_voidsource, MS_VOID_SOURCE_ID);
	CREATE_FILTER(FILTER_MASK_VOIDSINK, ms_tester_voidsink, MS_VOID_SINK_ID);
112
	if (filter_mask & FILTER_MASK_ENCODER) {
113
		BC_ASSERT_PTR_NULL(ms_tester_encoder);
114
		ms_tester_encoder = ms_filter_create_encoder(ms_tester_codec_mime);
115
		BC_ASSERT_PTR_NOT_NULL_FATAL(ms_tester_encoder);
116 117
	}
	if (filter_mask & FILTER_MASK_DECODER) {
118
		BC_ASSERT_PTR_NULL(ms_tester_decoder);
119
		ms_tester_decoder = ms_filter_create_decoder(ms_tester_codec_mime);
120
		BC_ASSERT_PTR_NOT_NULL_FATAL(ms_tester_decoder);
121
	}
Ghislain MARY's avatar
Ghislain MARY committed
122 123 124 125
	CREATE_FILTER(FILTER_MASK_RTPRECV, ms_tester_rtprecv, MS_RTP_RECV_ID);
	CREATE_FILTER(FILTER_MASK_RTPSEND, ms_tester_rtpsend, MS_RTP_SEND_ID);
	CREATE_FILTER(FILTER_MASK_RESAMPLER, ms_tester_resampler, MS_RESAMPLE_ID);
	if (filter_mask & FILTER_MASK_SOUNDWRITE) {
126
		BC_ASSERT_PTR_NULL(ms_tester_soundwrite);
127 128
		snd_manager = ms_snd_card_manager_get();
		playcard = ms_snd_card_manager_get_default_playback_card(snd_manager);
129
		BC_ASSERT_PTR_NOT_NULL_FATAL(playcard);
Ghislain MARY's avatar
Ghislain MARY committed
130
		ms_tester_soundwrite = ms_snd_card_create_writer(playcard);
131
		BC_ASSERT_PTR_NOT_NULL_FATAL(ms_tester_soundwrite);
Ghislain MARY's avatar
Ghislain MARY committed
132
	}
133
	if (filter_mask & FILTER_MASK_SOUNDREAD) {
134
		BC_ASSERT_PTR_NULL(ms_tester_soundread);
135 136
		snd_manager = ms_snd_card_manager_get();
		captcard = ms_snd_card_manager_get_default_capture_card(snd_manager);
137
		BC_ASSERT_PTR_NOT_NULL_FATAL(captcard);
138
		ms_tester_soundread = ms_snd_card_create_reader(captcard);
139
		BC_ASSERT_PTR_NOT_NULL_FATAL(ms_tester_soundread);
140
	}
141
	if (filter_mask & FILTER_MASK_VIDEOCAPTURE) {
142
		BC_ASSERT_PTR_NULL(ms_tester_videocapture);
143 144
		cam_manager = ms_web_cam_manager_get();
		camera = ms_web_cam_manager_get_default_cam(cam_manager);
145
		BC_ASSERT_PTR_NOT_NULL_FATAL(camera);
146
		ms_tester_videocapture = ms_web_cam_create_reader(camera);
147
		BC_ASSERT_PTR_NOT_NULL_FATAL(ms_tester_videocapture);
148
	}
Ghislain MARY's avatar
Ghislain MARY committed
149 150 151
}

#define DESTROY_FILTER(mask, filter) \
152
	if ((filter_mask & mask) && (filter != NULL)) { \
Ghislain MARY's avatar
Ghislain MARY committed
153
		ms_filter_destroy(filter); \
154
		filter = NULL; \
Ghislain MARY's avatar
Ghislain MARY committed
155 156
	} \

157
void ms_tester_destroy_filter(MSFilter **filter) {
158
	BC_ASSERT_PTR_NOT_NULL(filter);
159 160 161 162 163 164
	if (*filter != NULL) {
		ms_filter_destroy(*filter);
		*filter = NULL;
	}
}

Ghislain MARY's avatar
Ghislain MARY committed
165
void ms_tester_destroy_filters(unsigned int filter_mask) {
166 167 168 169 170 171 172 173 174 175 176 177 178 179
	DESTROY_FILTER(FILTER_MASK_FILEPLAY, ms_tester_fileplay)
	DESTROY_FILTER(FILTER_MASK_FILEREC, ms_tester_filerec)
	DESTROY_FILTER(FILTER_MASK_DTMFGEN, ms_tester_dtmfgen)
	DESTROY_FILTER(FILTER_MASK_TONEDET, ms_tester_tonedet)
	DESTROY_FILTER(FILTER_MASK_VOIDSOURCE, ms_tester_voidsource)
	DESTROY_FILTER(FILTER_MASK_VOIDSINK, ms_tester_voidsink)
	DESTROY_FILTER(FILTER_MASK_ENCODER, ms_tester_encoder)
	DESTROY_FILTER(FILTER_MASK_DECODER, ms_tester_decoder)
	DESTROY_FILTER(FILTER_MASK_RTPRECV, ms_tester_rtprecv)
	DESTROY_FILTER(FILTER_MASK_RTPSEND, ms_tester_rtpsend)
	DESTROY_FILTER(FILTER_MASK_RESAMPLER, ms_tester_resampler)
	DESTROY_FILTER(FILTER_MASK_SOUNDWRITE, ms_tester_soundwrite)
	DESTROY_FILTER(FILTER_MASK_SOUNDREAD, ms_tester_soundread)
	DESTROY_FILTER(FILTER_MASK_VIDEOCAPTURE, ms_tester_videocapture)
Ghislain MARY's avatar
Ghislain MARY committed
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
}

void ms_tester_tone_generation_loop(void) {
	unsigned int i;

	for (i = 0; i < (sizeof(tone_definition) / sizeof(tone_definition[0])); i++) {
		ms_filter_call_method(ms_tester_dtmfgen, MS_DTMF_GEN_PLAY_CUSTOM, &tone_definition[i].generated_tone);
		ms_sleep(1);
	}
}

void ms_tester_tone_detection_loop(void) {
	unsigned int i;

	for (i = 0; i < (sizeof(tone_definition) / sizeof(tone_definition[0])); i++) {
		ms_tester_tone_detected = FALSE;
		ms_filter_call_method(ms_tester_tonedet, MS_TONE_DETECTOR_CLEAR_SCANS, NULL);
		ms_filter_call_method(ms_tester_tonedet, MS_TONE_DETECTOR_ADD_SCAN, &tone_definition[i].expected_tone);
		ms_sleep(1);
199
		BC_ASSERT_EQUAL(ms_tester_tone_detected, TRUE, int, "%d");
Ghislain MARY's avatar
Ghislain MARY committed
200 201 202 203 204 205 206 207
	}
}

void ms_tester_tone_generation_and_detection_loop(void) {
	unsigned int i;

	for (i = 0; i < (sizeof(tone_definition) / sizeof(tone_definition[0])); i++) {
		ms_tester_tone_detected = FALSE;
208 209 210
		BC_ASSERT_EQUAL(0,ms_filter_call_method(ms_tester_tonedet, MS_TONE_DETECTOR_CLEAR_SCANS, NULL), int, "%d");
		BC_ASSERT_EQUAL(0,ms_filter_call_method(ms_tester_tonedet, MS_TONE_DETECTOR_ADD_SCAN, &tone_definition[i].expected_tone), int, "%d");
		BC_ASSERT_EQUAL(0,ms_filter_call_method(ms_tester_dtmfgen, MS_DTMF_GEN_PLAY_CUSTOM, &tone_definition[i].generated_tone), int, "%d");
Ghislain MARY's avatar
Ghislain MARY committed
211
		ms_sleep(1);
212
		BC_ASSERT_EQUAL(ms_tester_tone_detected, TRUE, int, "%d");
Ghislain MARY's avatar
Ghislain MARY committed
213 214 215
	}
}

216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
bool_t wait_for_list(MSList *mss, int *counter, int value, int timeout_ms) {
	return wait_for_list_with_parse_events(mss, counter, value, timeout_ms, NULL, NULL);
}

bool_t wait_for_list_with_parse_events(MSList *mss, int *counter, int value, int timeout_ms, MSList *cbs, MSList *ptrs) {
	MSList *msi;
	MSList *cbi;
	MSList *ptri;
	int retry = 0;

	while ((*counter < value) && (retry++ < (timeout_ms / 100))) {
		for (msi = mss, cbi = cbs, ptri = ptrs; msi != NULL; msi = msi->next) {
			MediaStream *stream = (MediaStream *)msi->data;
			ms_tester_iterate_cb cb = NULL;
			media_stream_iterate(stream);
			if ((retry % 10) == 0) {
jehan's avatar
jehan committed
232 233 234 235 236 237 238 239
				ms_message("stream [%p] bandwidth usage: rtp [d=%.1f,u=%.1f] kbit/sec",
													stream,
													media_stream_get_down_bw(stream) / 1000,
													media_stream_get_up_bw(stream) / 1000);
				ms_message("stream [%p] bandwidth usage: rtcp[d=%.1f,u=%.1f] kbit/sec",
													stream,
													media_stream_get_rtcp_down_bw(stream) / 1000,
													media_stream_get_rtcp_up_bw(stream) / 1000);
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
			}
			if (cbi && ptri) {
				cb = (ms_tester_iterate_cb)cbi->data;
				cb(stream, ptri->data);
			}
			if (cbi) cbi = cbi->next;
			if (ptri) ptri = ptri->next;
		}
		ms_usleep(100000);
	}

	if (*counter < value)
		return FALSE;
	return TRUE;
}

bool_t wait_for_until(MediaStream *ms_1, MediaStream *ms_2, int *counter, int value, int timeout_ms) {
	return wait_for_until_with_parse_events(ms_1, ms_2, counter, value, timeout_ms, NULL, NULL, NULL, NULL);
}

bool_t wait_for_until_with_parse_events(MediaStream *ms1, MediaStream *ms2, int *counter, int value, int timeout_ms, ms_tester_iterate_cb cb1, void *ptr1, ms_tester_iterate_cb cb2, void *ptr2) {
	MSList *mss = NULL;
	MSList *cbs = NULL;
	MSList *ptrs = NULL;
	bool_t result;

	if (ms1) {
		mss = ms_list_append(mss, ms1);
		if (cb1 && ptr1) {
			cbs = ms_list_append(cbs, cb1);
			ptrs = ms_list_append(ptrs, ptr1);
		}
	}
	if (ms2) {
		mss = ms_list_append(mss, ms2);
		if (cb2 && ptr2) {
			cbs = ms_list_append(cbs, cb2);
			ptrs = ms_list_append(ptrs, ptr2);
		}
	}
	result = wait_for_list_with_parse_events(mss, counter, value, timeout_ms, cbs, ptrs);
	ms_list_free(mss);
282 283
	ms_list_free(cbs);
	ms_list_free(ptrs);
284 285 286 287 288 289
	return result;
}

bool_t wait_for(MediaStream* ms_1, MediaStream* ms_2, int *counter, int value) {
	return wait_for_until(ms_1, ms_2, counter, value, 2000);
}