video_tester.c 24.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
	liblinphone_tester - liblinphone test suite
	Copyright (C) 2013  Belledonne Communications SARL

	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, see <http://www.gnu.org/licenses/>.
*/
Simon Morlat's avatar
Simon Morlat committed
18
#include "private.h"
19

20
#if defined(VIDEO_ENABLED)
21

22

23 24 25
#include "linphonecore.h"
#include "liblinphone_tester.h"
#include "lpconfig.h"
Simon Morlat's avatar
Simon Morlat committed
26

27
#if HAVE_GTK
28 29 30
#include <gtk/gtk.h>
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
Ghislain MARY's avatar
Ghislain MARY committed
31
#elif defined(_WIN32)
32 33 34 35 36 37 38 39 40
#include <gdk/gdkwin32.h>
#elif defined(__APPLE__)
extern void *gdk_quartz_window_get_nswindow(GdkWindow      *window);
extern void *gdk_quartz_window_get_nsview(GdkWindow      *window);
#endif

#include <gdk/gdkkeysyms.h>


41
static void *get_native_handle(GdkWindow *gdkw) {
42
#ifdef GDK_WINDOWING_X11
43
	return (void *)GDK_WINDOW_XID(gdkw);
Ghislain MARY's avatar
Ghislain MARY committed
44
#elif defined(_WIN32)
45
	return (void *)GDK_WINDOW_HWND(gdkw);
46
#elif defined(__APPLE__)
47
	return (void *)gdk_quartz_window_get_nsview(gdkw);
48 49 50 51 52
#endif
	g_warning("No way to get the native handle from gdk window");
	return 0;
}

53
static GtkWidget *create_video_window(LinphoneCall *call, LinphoneCallState cstate) {
54
	GtkWidget *video_window;
55
	GdkDisplay *display;
56
	GdkColor color;
57
	MSVideoSize vsize = { MS_VIDEO_SIZE_CIF_W, MS_VIDEO_SIZE_CIF_H };
58 59 60 61 62 63
	const char *cstate_str;
	char *title;
	stats* counters = get_stats(call->core);

	cstate_str = linphone_call_state_to_string(cstate);
	title = g_strdup_printf("%s", cstate_str);
64
	video_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
65 66
	gtk_window_set_title(GTK_WINDOW(video_window), title);
	g_free(title);
67 68 69 70 71
	gtk_window_resize(GTK_WINDOW(video_window), vsize.width, vsize.height);
	gdk_color_parse("black", &color);
	gtk_widget_modify_bg(video_window, GTK_STATE_NORMAL, &color);
	gtk_widget_show(video_window);
	g_object_set_data(G_OBJECT(video_window), "call", call);
72 73 74 75 76 77
#if GTK_CHECK_VERSION(2,24,0)
	display = gdk_window_get_display(gtk_widget_get_window(video_window));
#else // backward compatibility with Debian 6 and Centos 6
	display = gdk_drawable_get_display(gtk_widget_get_window(video_window));
#endif
	gdk_display_flush(display);
78
	counters->number_of_video_windows_created++;
79 80 81
	return video_window;
}

82
static void show_video_window(LinphoneCall *call, LinphoneCallState cstate) {
83 84
	GtkWidget *video_window = (GtkWidget *)linphone_call_get_user_data(call);
	if (video_window == NULL) {
85
		video_window = create_video_window(call, cstate);
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
		linphone_call_set_user_data(call, video_window);
		linphone_call_set_native_video_window_id(call, get_native_handle(gtk_widget_get_window(video_window)));
	}
}

static void hide_video_video(LinphoneCall *call) {
	GtkWidget *video_window = (GtkWidget *)linphone_call_get_user_data(call);
	if (video_window != NULL) {
		gtk_widget_destroy(video_window);
		linphone_call_set_user_data(call, NULL);
		linphone_call_set_native_video_window_id(call, 0);
	}
}

static void video_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg) {
	switch (cstate) {
102 103
		case LinphoneCallIncomingEarlyMedia:
		case LinphoneCallOutgoingEarlyMedia:
104
		case LinphoneCallConnected:
105
			show_video_window(call, cstate);
106 107 108 109 110 111 112 113 114
			break;
		case LinphoneCallEnd:
			hide_video_video(call);
			break;
		default:
			break;
	}
}

115 116 117 118 119 120 121 122
static void early_media_video_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg) {
	LinphoneCallParams *params;

	video_call_state_changed(lc, call, cstate, msg);
	switch (cstate) {
		case LinphoneCallIncomingReceived:
			params = linphone_core_create_default_call_parameters(lc);
			linphone_call_params_enable_video(params, TRUE);
123 124
			linphone_call_params_set_audio_direction(params, LinphoneMediaDirectionSendOnly);
			linphone_call_params_set_video_direction(params, LinphoneMediaDirectionRecvOnly);
125 126 127 128 129 130 131 132
			linphone_core_accept_early_media_with_params(lc, call, params);
			linphone_call_params_unref(params);
			break;
		default:
			break;
	}
}

133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
static void early_media_video_call_state_changed_with_inactive_audio(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg) {
	LinphoneCallParams *params;

	video_call_state_changed(lc, call, cstate, msg);
	switch (cstate) {
		case LinphoneCallIncomingReceived:
			params = linphone_core_create_default_call_parameters(lc);
			linphone_call_params_enable_video(params, TRUE);
			linphone_call_params_set_audio_direction(params, LinphoneMediaDirectionInactive);
			linphone_call_params_set_video_direction(params, LinphoneMediaDirectionRecvOnly);
			linphone_core_accept_early_media_with_params(lc, call, params);
			linphone_call_params_unref(params);
			break;
		default:
			break;
	}
}

151 152 153 154 155 156 157 158 159 160 161 162 163
bool_t wait_for_three_cores(LinphoneCore *lc1, LinphoneCore *lc2, LinphoneCore *lc3, int timeout) {
	MSList *lcs = NULL;
	bool_t result;
	int dummy = 0;
	if (lc1) lcs = ms_list_append(lcs, lc1);
	if (lc2) lcs = ms_list_append(lcs, lc2);
	if (lc3) lcs = ms_list_append(lcs, lc3);
	result = wait_for_list(lcs, &dummy, 1, timeout);
	ms_list_free(lcs);
	return result;
}

static bool_t video_call_with_params(LinphoneCoreManager* caller_mgr, LinphoneCoreManager* callee_mgr, const LinphoneCallParams *caller_params, const LinphoneCallParams *callee_params, bool_t automatically_accept) {
164 165 166
	int retry = 0;
	stats initial_caller = caller_mgr->stat;
	stats initial_callee = callee_mgr->stat;
167
	bool_t result = TRUE;
168 169
	bool_t did_received_call;

170
	BC_ASSERT_PTR_NOT_NULL(linphone_core_invite_address_with_params(caller_mgr->lc, callee_mgr->identity, caller_params));
171 172 173
	did_received_call = wait_for(callee_mgr->lc, caller_mgr->lc, &callee_mgr->stat.number_of_LinphoneCallIncomingReceived, initial_callee.number_of_LinphoneCallIncomingReceived + 1);
	if (!did_received_call) return 0;

174
	BC_ASSERT_EQUAL(caller_mgr->stat.number_of_LinphoneCallOutgoingProgress, initial_caller.number_of_LinphoneCallOutgoingProgress + 1, int, "%d");
175 176 177

	while (caller_mgr->stat.number_of_LinphoneCallOutgoingRinging != (initial_caller.number_of_LinphoneCallOutgoingRinging + 1)
		&& caller_mgr->stat.number_of_LinphoneCallOutgoingEarlyMedia != (initial_caller.number_of_LinphoneCallOutgoingEarlyMedia + 1)
178
		&& retry++ < 200) {
179 180
		linphone_core_iterate(caller_mgr->lc);
		linphone_core_iterate(callee_mgr->lc);
181
		ms_usleep(10000);
182 183
	}

184
	BC_ASSERT_TRUE((caller_mgr->stat.number_of_LinphoneCallOutgoingRinging == initial_caller.number_of_LinphoneCallOutgoingRinging + 1)
185 186
		|| (caller_mgr->stat.number_of_LinphoneCallOutgoingEarlyMedia == initial_caller.number_of_LinphoneCallOutgoingEarlyMedia + 1));

187
	BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call_remote_address(callee_mgr->lc));
188 189 190 191
	if(!linphone_core_get_current_call(caller_mgr->lc) || !linphone_core_get_current_call(callee_mgr->lc) || !linphone_core_get_current_call_remote_address(callee_mgr->lc)) {
		return 0;
	}

192 193
	if (automatically_accept == TRUE) {
		linphone_core_accept_call_with_params(callee_mgr->lc, linphone_core_get_current_call(callee_mgr->lc), callee_params);
194

195 196
		BC_ASSERT_TRUE(wait_for(callee_mgr->lc, caller_mgr->lc, &callee_mgr->stat.number_of_LinphoneCallConnected, initial_callee.number_of_LinphoneCallConnected + 1));
		BC_ASSERT_TRUE(wait_for(callee_mgr->lc, caller_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallConnected, initial_callee.number_of_LinphoneCallConnected + 1));
197 198 199
		result = wait_for(callee_mgr->lc, caller_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallStreamsRunning, initial_caller.number_of_LinphoneCallStreamsRunning + 1)
			&& wait_for(callee_mgr->lc, caller_mgr->lc, &callee_mgr->stat.number_of_LinphoneCallStreamsRunning, initial_callee.number_of_LinphoneCallStreamsRunning + 1);
	}
200 201 202
	return result;
}

203 204 205 206 207 208 209 210 211 212
static LinphoneCallParams * _configure_for_video(LinphoneCoreManager *manager, LinphoneCoreCallStateChangedCb cb) {
	LinphoneCallParams *params;
	LinphoneCoreVTable *vtable = linphone_core_v_table_new();
	vtable->call_state_changed = cb;
	linphone_core_add_listener(manager->lc, vtable);
	linphone_core_set_video_device(manager->lc, "StaticImage: Static picture");
	linphone_core_enable_video_capture(manager->lc, TRUE);
	linphone_core_enable_video_display(manager->lc, TRUE);
	params = linphone_core_create_default_call_parameters(manager->lc);
	linphone_call_params_enable_video(params, TRUE);
Simon Morlat's avatar
Simon Morlat committed
213 214 215 216 217 218
	if (linphone_core_find_payload_type(manager->lc,"VP8", 90000, -1)!=NULL){
		disable_all_video_codecs_except_one(manager->lc, "VP8");
	}else{
		ms_warning("VP8 codec not available, will use MP4V-ES instead");
		disable_all_video_codecs_except_one(manager->lc, "MP4V-ES");
	}
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
	return params;
}

static LinphoneCallParams * configure_for_video(LinphoneCoreManager *manager) {
	return _configure_for_video(manager, video_call_state_changed);
}

static LinphoneCallParams * configure_for_early_media_video_sending(LinphoneCoreManager *manager) {
	LinphoneCallParams *params = _configure_for_video(manager, video_call_state_changed);
	linphone_call_params_enable_early_media_sending(params, TRUE);
	return params;
}

static LinphoneCallParams * configure_for_early_media_video_receiving(LinphoneCoreManager *manager) {
	return _configure_for_video(manager, early_media_video_call_state_changed);
}

236 237 238 239
static LinphoneCallParams * configure_for_early_media_video_receiving_with_inactive_audio(LinphoneCoreManager *manager) {
	return _configure_for_video(manager, early_media_video_call_state_changed_with_inactive_audio);
}

240 241 242 243

static void early_media_video_during_video_call_test(void) {
	LinphoneCoreManager *marie;
	LinphoneCoreManager *pauline;
244
	LinphoneCoreManager *laure;
245 246
	LinphoneCallParams *marie_params;
	LinphoneCallParams *pauline_params;
247 248 249
	LinphoneCallParams *laure_params;

	marie = linphone_core_manager_new("marie_rc");
250
	pauline = linphone_core_manager_new("pauline_tcp_rc");
251 252 253 254 255 256
	laure = linphone_core_manager_new("laure_rc");
	marie_params = configure_for_early_media_video_receiving(marie);
	pauline_params = configure_for_video(pauline);
	laure_params = configure_for_early_media_video_sending(laure);

	/* Normal automatically accepted video call from marie to pauline. */
257
	BC_ASSERT_TRUE(video_call_with_params(marie, pauline, marie_params, pauline_params, TRUE));
258

259 260 261 262
	/* Wait for 2s. */
	wait_for_three_cores(marie->lc, pauline->lc, NULL, 2000);

	/* Early media video call from laure to marie. */
263
	BC_ASSERT_TRUE(video_call_with_params(laure, marie, laure_params, NULL, FALSE));
264 265 266

	/* Wait for 2s. */
	wait_for_three_cores(marie->lc, pauline->lc, laure->lc, 2000);
267 268

	linphone_core_terminate_all_calls(marie->lc);
269 270 271 272 273 274
	BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1));
	BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1));
	BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallReleased, 1));
	BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallReleased, 1));
	BC_ASSERT_TRUE(wait_for(marie->lc, laure->lc, &marie->stat.number_of_LinphoneCallEnd, 1));
	BC_ASSERT_TRUE(wait_for(marie->lc, laure->lc, &laure->stat.number_of_LinphoneCallEnd, 1));
275

276 277 278
	BC_ASSERT_EQUAL(marie->stat.number_of_video_windows_created, 2, int, "%d");
	BC_ASSERT_EQUAL(pauline->stat.number_of_video_windows_created, 1, int, "%d");
	BC_ASSERT_EQUAL(laure->stat.number_of_video_windows_created, 1, int, "%d");
279

280 281 282
	linphone_call_params_unref(marie_params);
	linphone_call_params_unref(pauline_params);
	linphone_call_params_unref(laure_params);
283 284
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
285
	linphone_core_manager_destroy(laure);
286 287
}

288
static void two_incoming_early_media_video_calls_test(void) {
289
	char *ringback_path;
290 291 292 293 294 295
	LinphoneCoreManager *marie;
	LinphoneCoreManager *pauline;
	LinphoneCoreManager *laure;
	LinphoneCallParams *marie_params;
	LinphoneCallParams *pauline_params;
	LinphoneCallParams *laure_params;
296 297
	LinphoneCall *call;
	const MSList *calls_list;
298 299

	marie = linphone_core_manager_new("marie_rc");
300
	pauline = linphone_core_manager_new("pauline_tcp_rc");
301 302 303 304 305
	laure = linphone_core_manager_new("laure_rc");
	marie_params = configure_for_early_media_video_receiving(marie);
	pauline_params = configure_for_early_media_video_sending(pauline);
	laure_params = configure_for_early_media_video_sending(laure);

306 307
	/* Configure early media audio to play ring during early-media and send remote ring back tone. */
	linphone_core_set_ring_during_incoming_early_media(marie->lc, TRUE);
308
	ringback_path = bc_tester_res("sounds/ringback.wav");
309 310 311
	linphone_core_set_remote_ringback_tone(marie->lc, ringback_path);
	ms_free(ringback_path);

312
	/* Early media video call from pauline to marie. */
313
	BC_ASSERT_TRUE(video_call_with_params(pauline, marie, pauline_params, NULL, FALSE));
314 315 316 317 318

	/* Wait for 2s. */
	wait_for_three_cores(marie->lc, pauline->lc, NULL, 2000);

	/* Early media video call from laure to marie. */
319
	BC_ASSERT_TRUE(video_call_with_params(laure, marie, laure_params, NULL, FALSE));
320 321 322 323

	/* Wait for 2s. */
	wait_for_three_cores(marie->lc, pauline->lc, laure->lc, 2000);

324
	BC_ASSERT_EQUAL(linphone_core_get_calls_nb(marie->lc), 2, int, "%d");
325 326 327
	if (linphone_core_get_calls_nb(marie->lc) == 2) {
		calls_list = linphone_core_get_calls(marie->lc);
		call = (LinphoneCall *)ms_list_nth_data(calls_list, 0);
328
		BC_ASSERT_PTR_NOT_NULL(call);
329 330
		if (call != NULL) {
			LinphoneCallParams *params = linphone_call_params_copy(linphone_call_get_current_params(call));
331 332
			linphone_call_params_set_audio_direction(params, LinphoneMediaDirectionSendRecv);
			linphone_call_params_set_video_direction(params, LinphoneMediaDirectionSendRecv);
333 334 335 336 337 338 339
			linphone_core_accept_call_with_params(marie->lc, call, params);

			/* Wait for 5s. */
			wait_for_three_cores(marie->lc, pauline->lc, laure->lc, 5000);
		}
	}

340
	linphone_core_terminate_all_calls(marie->lc);
341 342 343 344 345 346
	BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1));
	BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1));
	BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallReleased, 1));
	BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallReleased, 1));
	BC_ASSERT_TRUE(wait_for(marie->lc, laure->lc, &marie->stat.number_of_LinphoneCallEnd, 1));
	BC_ASSERT_TRUE(wait_for(marie->lc, laure->lc, &laure->stat.number_of_LinphoneCallEnd, 1));
347

348 349 350
	BC_ASSERT_EQUAL(marie->stat.number_of_video_windows_created, 2, int, "%d");
	BC_ASSERT_EQUAL(pauline->stat.number_of_video_windows_created, 1, int, "%d");
	BC_ASSERT_EQUAL(laure->stat.number_of_video_windows_created, 1, int, "%d");
351 352 353 354 355 356 357 358 359

	linphone_call_params_unref(marie_params);
	linphone_call_params_unref(pauline_params);
	linphone_call_params_unref(laure_params);
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
	linphone_core_manager_destroy(laure);
}

360 361 362 363 364 365 366
static void early_media_video_with_inactive_audio(void) {
	LinphoneCoreManager *marie;
	LinphoneCoreManager *pauline;
	LinphoneCallParams *marie_params;
	LinphoneCallParams *pauline_params;

	marie = linphone_core_manager_new("marie_rc");
367
	pauline = linphone_core_manager_new("pauline_tcp_rc");
368 369 370 371
	marie_params = configure_for_early_media_video_receiving_with_inactive_audio(marie);
	pauline_params = configure_for_early_media_video_sending(pauline);

	/* Early media video call from pauline to marie. */
372
	BC_ASSERT_TRUE(video_call_with_params(pauline, marie, pauline_params, NULL, FALSE));
373 374 375 376 377

	/* Wait for 2s. */
	wait_for_three_cores(marie->lc, pauline->lc, NULL, 2000);

	/* Check that we are in LinphoneCallOutgoingEarlyMedia state and that the ringstream is present meaning we are playing the ringback tone. */
378 379
	BC_ASSERT_EQUAL(linphone_call_get_state(linphone_core_get_current_call(pauline->lc)), LinphoneCallOutgoingEarlyMedia, int, "%d");
	BC_ASSERT_PTR_NOT_NULL(pauline->lc->ringstream);
380 381

	linphone_core_terminate_all_calls(marie->lc);
382 383 384 385
	BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1));
	BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1));
	BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallReleased, 1));
	BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallReleased, 1));
386

387 388
	BC_ASSERT_EQUAL(marie->stat.number_of_video_windows_created, 1, int, "%d");
	BC_ASSERT_EQUAL(pauline->stat.number_of_video_windows_created, 1, int, "%d");
389 390 391 392 393 394 395

	linphone_call_params_unref(marie_params);
	linphone_call_params_unref(pauline_params);
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432
static void forked_outgoing_early_media_video_call_with_inactive_audio_test(void) {
	LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc");
	LinphoneCoreManager *marie1 = linphone_core_manager_new("marie_early_rc");
	LinphoneCoreManager *marie2 = linphone_core_manager_new("marie_early_rc");
	MSList *lcs = NULL;
	LinphoneCallParams *pauline_params;
	LinphoneCallParams *marie1_params;
	LinphoneCallParams *marie2_params;
	LinphoneVideoPolicy pol;
	LinphoneCall *marie1_call;
	LinphoneCall *marie2_call;
	LinphoneCall *pauline_call;
	LinphoneInfoMessage *info;
	int dummy = 0;
	pol.automatically_accept = 1;
	pol.automatically_initiate = 1;

	linphone_core_enable_video(pauline->lc, TRUE, TRUE);
	linphone_core_enable_video(marie1->lc, TRUE, TRUE);
	linphone_core_set_video_policy(marie1->lc, &pol);
	linphone_core_enable_video(marie2->lc, TRUE, TRUE);
	linphone_core_set_video_policy(marie2->lc, &pol);
	linphone_core_set_audio_port_range(marie2->lc, 40200, 40300);
	linphone_core_set_video_port_range(marie2->lc, 40400, 40500);

	lcs = ms_list_append(lcs,marie1->lc);
	lcs = ms_list_append(lcs,marie2->lc);
	lcs = ms_list_append(lcs,pauline->lc);

	pauline_params = linphone_core_create_default_call_parameters(pauline->lc);
	linphone_call_params_enable_early_media_sending(pauline_params, TRUE);
	linphone_call_params_enable_video(pauline_params, TRUE);
	marie1_params = configure_for_early_media_video_receiving_with_inactive_audio(marie1);
	marie2_params = configure_for_early_media_video_receiving_with_inactive_audio(marie2);

	linphone_core_invite_address_with_params(pauline->lc, marie1->identity, pauline_params);
	linphone_call_params_destroy(pauline_params);
433

Simon Morlat's avatar
Simon Morlat committed
434 435
	BC_ASSERT_TRUE(wait_for_list(lcs, &marie1->stat.number_of_LinphoneCallIncomingReceived, 1, 3000));
	BC_ASSERT_TRUE(wait_for_list(lcs, &marie2->stat.number_of_LinphoneCallIncomingReceived, 1, 3000));
436

Simon Morlat's avatar
Simon Morlat committed
437 438
	marie1_call = linphone_core_get_current_call(marie1->lc);
	marie2_call = linphone_core_get_current_call(marie2->lc);
439

Simon Morlat's avatar
Simon Morlat committed
440 441 442 443 444 445
	if (marie1_call){
		linphone_call_set_next_video_frame_decoded_callback(marie1_call, linphone_call_iframe_decoded_cb, marie1->lc);
	}
	if (marie2_call){
		linphone_call_set_next_video_frame_decoded_callback(marie2_call, linphone_call_iframe_decoded_cb, marie2->lc);
	}
446

447 448 449
	BC_ASSERT_TRUE(wait_for_list(lcs, &marie1->stat.number_of_LinphoneCallIncomingEarlyMedia, 1, 3000));
	BC_ASSERT_TRUE(wait_for_list(lcs, &marie2->stat.number_of_LinphoneCallIncomingEarlyMedia, 1, 3000));
	BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallOutgoingEarlyMedia, 1, 3000));
450 451 452

	pauline_call = linphone_core_get_current_call(pauline->lc);

453 454 455
	BC_ASSERT_PTR_NOT_NULL(pauline_call);
	BC_ASSERT_PTR_NOT_NULL(marie1_call);
	BC_ASSERT_PTR_NOT_NULL(marie2_call);
456 457

	if (pauline_call && marie1_call && marie2_call) {
Simon Morlat's avatar
Simon Morlat committed
458
		linphone_call_set_next_video_frame_decoded_callback(pauline_call, linphone_call_iframe_decoded_cb, pauline->lc);
459

460
		/* wait a bit that streams are established */
Simon Morlat's avatar
Simon Morlat committed
461
		wait_for_list(lcs, &dummy, 1, 3000);
462 463 464
		BC_ASSERT_EQUAL(linphone_call_get_audio_stats(pauline_call)->download_bandwidth, 0, float, "%f");
		BC_ASSERT_EQUAL(linphone_call_get_audio_stats(marie1_call)->download_bandwidth, 0, float, "%f");
		BC_ASSERT_EQUAL(linphone_call_get_audio_stats(marie2_call)->download_bandwidth, 0, float, "%f");
Simon Morlat's avatar
Simon Morlat committed
465
		BC_ASSERT_LOWER(linphone_call_get_video_stats(pauline_call)->download_bandwidth, 11, float, "%f"); /* because of stun packets*/
466 467
		BC_ASSERT_GREATER(linphone_call_get_video_stats(marie1_call)->download_bandwidth, 0, float, "%f");
		BC_ASSERT_GREATER(linphone_call_get_video_stats(marie2_call)->download_bandwidth, 0, float, "%f");
Simon Morlat's avatar
Simon Morlat committed
468 469
		BC_ASSERT_GREATER(marie1->stat.number_of_IframeDecoded, 1, int, "%i");
		BC_ASSERT_GREATER(marie2->stat.number_of_IframeDecoded, 1, int, "%i");
470 471 472

		linphone_call_params_set_audio_direction(marie1_params, LinphoneMediaDirectionSendRecv);
		linphone_core_accept_call_with_params(marie1->lc, linphone_core_get_current_call(marie1->lc), marie1_params);
473 474
		BC_ASSERT_TRUE(wait_for_list(lcs, &marie1->stat.number_of_LinphoneCallStreamsRunning, 1, 3000));
		BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1, 3000));
475 476

		/* marie2 should get her call terminated */
477
		BC_ASSERT_TRUE(wait_for_list(lcs, &marie2->stat.number_of_LinphoneCallEnd, 1, 1000));
478 479 480

		/*wait a bit that streams are established*/
		wait_for_list(lcs, &dummy, 1, 3000);
481 482
		BC_ASSERT_GREATER(linphone_call_get_audio_stats(pauline_call)->download_bandwidth, 71, float, "%f");
		BC_ASSERT_GREATER(linphone_call_get_audio_stats(marie1_call)->download_bandwidth, 71, float, "%f");
Simon Morlat's avatar
Simon Morlat committed
483 484 485
		BC_ASSERT_GREATER(linphone_call_get_video_stats(pauline_call)->download_bandwidth, 0, float, "%f");
		BC_ASSERT_GREATER(linphone_call_get_video_stats(marie1_call)->download_bandwidth, 0, float, "%f");
		BC_ASSERT_GREATER(pauline->stat.number_of_IframeDecoded, 1, int, "%i");
486 487 488 489

		/* send an INFO in reverse side to check that dialogs are properly established */
		info = linphone_core_create_info_message(marie1->lc);
		linphone_call_send_info_message(marie1_call, info);
490
		BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_inforeceived, 1, 3000));
491 492 493
	}

	linphone_core_terminate_all_calls(pauline->lc);
494 495
	BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallEnd, 1, 3000));
	BC_ASSERT_TRUE(wait_for_list(lcs, &marie1->stat.number_of_LinphoneCallEnd, 1, 3000));
496 497 498 499 500 501 502 503

	linphone_call_params_destroy(marie1_params);
	linphone_call_params_destroy(marie2_params);
	ms_list_free(lcs);
	linphone_core_manager_destroy(marie1);
	linphone_core_manager_destroy(marie2);
	linphone_core_manager_destroy(pauline);
}
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535
#endif /*HAVE_GTK*/

static void enable_disable_camera_after_camera_switches() {
	LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
	LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
	const char *currentCamId = (char*)linphone_core_get_video_device(marie->lc);
	const char **cameras=linphone_core_get_video_devices(marie->lc);
	const char *newCamId=NULL;
	int i;


	video_call_base_2(marie,pauline,FALSE,LinphoneMediaEncryptionNone,TRUE,TRUE);

	for (i=0;cameras[i]!=NULL;++i){
		if (strcmp(cameras[i],currentCamId)!=0){
			newCamId=cameras[i];
			break;
		}
	}
	if (newCamId){
		LinphoneCall *call = linphone_core_get_current_call(marie->lc);
		ms_message("Switching from [%s] to [%s]", currentCamId, newCamId);
		linphone_core_set_video_device(marie->lc, newCamId);
		if(call != NULL) {
			linphone_core_update_call(marie->lc, call, NULL);
		}
		BC_ASSERT_STRING_EQUAL(newCamId,ms_web_cam_get_string_id(linphone_call_get_video_device(call)));
		linphone_call_enable_camera(call,FALSE);
		linphone_core_iterate(marie->lc);
		linphone_call_enable_camera(call,TRUE);
		BC_ASSERT_STRING_EQUAL(newCamId,ms_web_cam_get_string_id(linphone_call_get_video_device(call)));
	}
536

537 538 539 540 541 542 543

	linphone_core_terminate_all_calls(pauline->lc);
	BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1));
	BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1));
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
544
test_t video_tests[] = {
545
#if HAVE_GTK
546
	{ "Early-media video during video call", early_media_video_during_video_call_test },
547
	{ "Two incoming early-media video calls", two_incoming_early_media_video_calls_test },
548
	{ "Early-media video with inactive audio", early_media_video_with_inactive_audio },
549 550 551 552
	{ "Forked outgoing early-media video call with inactive audio", forked_outgoing_early_media_video_call_with_inactive_audio_test },
#endif /*HAVE_GTK*/
	{ "Enable/disable camera after camera switches", enable_disable_camera_after_camera_switches}

553 554
};

555 556
test_suite_t video_test_suite = {"Video", NULL, NULL, liblinphone_tester_before_each, NULL,
								 sizeof(video_tests) / sizeof(video_tests[0]), video_tests};
557 558

#endif /* VIDEO_ENABLED */