Commit 54f3cd52 authored by Ghislain MARY's avatar Ghislain MARY
Browse files

Add video tester that creates its own GTK windows for video display.

parent c7437e6f
......@@ -20,6 +20,8 @@
#
############################################################################
find_package(GTK2 2.18 COMPONENTS gtk)
set(SOURCE_FILES
accountmanager.c
call_tester.c
......@@ -40,8 +42,14 @@ set(SOURCE_FILES
tester.c
transport_tester.c
upnp_tester.c
video_tester.c
)
add_executable(liblinphone_tester ${SOURCE_FILES})
target_include_directories(liblinphone_tester PUBLIC ${CUNIT_INCLUDE_DIRS})
target_link_libraries(liblinphone_tester linphone ${CUNIT_LIBRARIES})
if (GTK2_FOUND)
target_compile_definitions(liblinphone_tester PRIVATE HAVE_GTK)
target_include_directories(liblinphone_tester PUBLIC ${GTK2_INCLUDE_DIRS})
target_link_libraries(liblinphone_tester linphone ${GTK2_LIBRARIES})
endif()
......@@ -27,7 +27,8 @@ liblinphonetester_la_SOURCES = tester.c \
player_tester.c \
dtmf_tester.c \
accountmanager.c \
offeranswer_tester.c
offeranswer_tester.c \
video_tester.c
liblinphonetester_la_LDFLAGS= -no-undefined
liblinphonetester_la_LIBADD= ../coreapi/liblinphone.la $(CUNIT_LIBS)
......@@ -35,6 +36,13 @@ liblinphonetester_la_LIBADD= ../coreapi/liblinphone.la $(CUNIT_LIBS)
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/coreapi
AM_CFLAGS = $(STRICT_OPTIONS) $(STRICT_OPTIONS_CC) -DIN_LINPHONE $(ORTP_CFLAGS) $(MEDIASTREAMER_CFLAGS) $(CUNIT_CFLAGS) $(BELLESIP_CFLAGS) $(LIBXML2_CFLAGS) $(SQLITE3_CFLAGS)
if BUILD_GTK_UI
liblinphone_tester_la_LIBADD += $(LIBGTK_LIBS) $(LIBGTKMAC_LIBS)
AM_CFLAGS += $(LIBGTK_CFLAGS) $(LIBGTKMAC_CFLAGS) -DHAVE_GTK
endif
if !BUILD_IOS
noinst_PROGRAMS = liblinphone_tester
......
......@@ -740,7 +740,7 @@ void disable_all_audio_codecs_except_one(LinphoneCore *lc, const char *mime, int
}
#ifdef VIDEO_ENABLED
static void disable_all_video_codecs_except_one(LinphoneCore *lc, const char *mime) {
void disable_all_video_codecs_except_one(LinphoneCore *lc, const char *mime) {
const MSList *codecs = linphone_core_get_video_codecs(lc);
const MSList *it = NULL;
PayloadType *pt = NULL;
......
......@@ -24,6 +24,9 @@
#if HAVE_CU_CURSES
#include "CUnit/CUCurses.h"
#endif
#ifdef HAVE_GTK
#include <gtk/gtk.h>
#endif
extern int liblinphone_tester_use_log_file;
......@@ -167,6 +170,12 @@ int main (int argc, char *argv[])
char *xml_tmp_file=NULL;
int xml = 0;
FILE* log_file=NULL;
#ifdef HAVE_GTK
gdk_threads_init();
gtk_init(&argc, &argv);
#endif
#if defined(ANDROID)
linphone_core_set_log_handler(linphone_android_ortp_log_handler);
#elif defined(__QNX__)
......@@ -246,7 +255,6 @@ int main (int argc, char *argv[])
}
liblinphone_tester_enable_xml(xml);
ret = liblinphone_tester_run_tests(suite_name, test_name);
liblinphone_tester_uninit();
......
......@@ -63,6 +63,7 @@ extern test_suite_t transport_test_suite;
extern test_suite_t player_test_suite;
extern test_suite_t dtmf_test_suite;
extern test_suite_t offeranswer_test_suite;
extern test_suite_t video_test_suite;
extern int liblinphone_tester_nb_test_suites(void);
......@@ -295,6 +296,7 @@ bool_t call_with_test_params(LinphoneCoreManager* caller_mgr
bool_t call(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr);
void end_call(LinphoneCoreManager *m1, LinphoneCoreManager *m2);
void disable_all_audio_codecs_except_one(LinphoneCore *lc, const char *mime, int rate);
void disable_all_video_codecs_except_one(LinphoneCore *lc, const char *mime);
stats * get_stats(LinphoneCore *lc);
LinphoneCoreManager *get_manager(LinphoneCore *lc);
const char *liblinphone_tester_get_subscribe_content(void);
......
......@@ -25,6 +25,9 @@
#if HAVE_CU_CURSES
#include "CUnit/CUCurses.h"
#endif
#ifdef HAVE_GTK
#include <gtk/gtk.h>
#endif
static test_suite_t **test_suite = NULL;
static int nb_test_suites = 0;
......@@ -201,6 +204,11 @@ bool_t wait_for_list(MSList* lcs,int* counter,int value,int timeout_ms) {
liblinphone_tester_clock_start(&start);
while ((counter==NULL || *counter<value) && !liblinphone_tester_clock_elapsed(&start,timeout_ms)) {
for (iterator=lcs;iterator!=NULL;iterator=iterator->next) {
#ifdef HAVE_GTK
gdk_threads_enter();
gtk_main_iteration_do(FALSE);
gdk_threads_leave();
#endif
linphone_core_iterate((LinphoneCore*)(iterator->data));
}
ms_usleep(20000);
......@@ -442,6 +450,9 @@ void liblinphone_tester_init(void) {
add_test_suite(&transport_test_suite);
add_test_suite(&player_test_suite);
add_test_suite(&dtmf_test_suite);
#if defined(VIDEO_ENABLED) && defined(HAVE_GTK)
add_test_suite(&video_test_suite);
#endif
}
void liblinphone_tester_uninit(void) {
......
/*
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/>.
*/
#if defined(VIDEO_ENABLED) && defined(HAVE_GTK)
#include <stdio.h>
#include "CUnit/Basic.h"
#include "linphonecore.h"
#include "liblinphone_tester.h"
#include "lpconfig.h"
#include "private.h"
#include <gtk/gtk.h>
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
#elif defined(WIN32)
#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>
static unsigned long get_native_handle(GdkWindow *gdkw) {
#ifdef GDK_WINDOWING_X11
return (unsigned long)GDK_WINDOW_XID(gdkw);
#elif defined(WIN32)
return (unsigned long)GDK_WINDOW_HWND(gdkw);
#elif defined(__APPLE__)
return (unsigned long)gdk_quartz_window_get_nsview(gdkw);
#endif
g_warning("No way to get the native handle from gdk window");
return 0;
}
static GtkWidget *create_video_window(LinphoneCall *call) {
GtkWidget *video_window;
GdkColor color;
MSVideoSize vsize = MS_VIDEO_SIZE_CIF;
video_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
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);
gdk_display_flush(gdk_window_get_display(gtk_widget_get_window(video_window)));
return video_window;
}
static void show_video_window(LinphoneCall *call) {
GtkWidget *video_window = (GtkWidget *)linphone_call_get_user_data(call);
if (video_window == NULL) {
video_window = create_video_window(call);
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) {
case LinphoneCallConnected:
show_video_window(call);
break;
case LinphoneCallEnd:
hide_video_video(call);
break;
default:
break;
}
}
static bool_t video_call_with_params(LinphoneCoreManager* caller_mgr, LinphoneCoreManager* callee_mgr, const LinphoneCallParams *caller_params, const LinphoneCallParams *callee_params) {
int retry = 0;
stats initial_caller = caller_mgr->stat;
stats initial_callee = callee_mgr->stat;
bool_t result = FALSE;
bool_t did_received_call;
CU_ASSERT_PTR_NOT_NULL(linphone_core_invite_address_with_params(caller_mgr->lc, callee_mgr->identity, caller_params));
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;
CU_ASSERT_TRUE(linphone_core_inc_invite_pending(callee_mgr->lc));
CU_ASSERT_EQUAL(caller_mgr->stat.number_of_LinphoneCallOutgoingProgress, initial_caller.number_of_LinphoneCallOutgoingProgress + 1);
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)
&& retry++ < 20) {
linphone_core_iterate(caller_mgr->lc);
linphone_core_iterate(callee_mgr->lc);
ms_usleep(100000);
}
CU_ASSERT_TRUE((caller_mgr->stat.number_of_LinphoneCallOutgoingRinging == initial_caller.number_of_LinphoneCallOutgoingRinging + 1)
|| (caller_mgr->stat.number_of_LinphoneCallOutgoingEarlyMedia == initial_caller.number_of_LinphoneCallOutgoingEarlyMedia + 1));
CU_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call_remote_address(callee_mgr->lc));
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;
}
linphone_core_accept_call_with_params(callee_mgr->lc, linphone_core_get_current_call(callee_mgr->lc), callee_params);
CU_ASSERT_TRUE(wait_for(callee_mgr->lc, caller_mgr->lc, &callee_mgr->stat.number_of_LinphoneCallConnected, initial_callee.number_of_LinphoneCallConnected + 1));
CU_ASSERT_TRUE(wait_for(callee_mgr->lc, caller_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallConnected, initial_callee.number_of_LinphoneCallConnected + 1));
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);
return result;
}
static void early_media_video_during_video_call_test(void) {
LinphoneCoreManager *marie;
LinphoneCoreManager *pauline;
LinphoneCallParams *marie_params;
LinphoneCallParams *pauline_params;
LinphoneCoreVTable *marie_vtable;
LinphoneCoreVTable *pauline_vtable;
int dummy = 0;
marie = linphone_core_manager_new( "marie_rc");
pauline = linphone_core_manager_new( "pauline_rc");
marie_vtable = linphone_core_v_table_new();
marie_vtable->call_state_changed = video_call_state_changed;
linphone_core_add_listener(marie->lc, marie_vtable);
linphone_core_set_video_device(marie->lc, "StaticImage: Static picture");
//linphone_core_set_video_device(marie->lc, "V4L2: /dev/video0");
linphone_core_enable_video_capture(marie->lc, TRUE);
linphone_core_enable_video_display(marie->lc, TRUE);
linphone_core_set_avpf_mode(marie->lc, LinphoneAVPFEnabled);
marie_params = linphone_core_create_default_call_parameters(marie->lc);
linphone_call_params_enable_video(marie_params, TRUE);
disable_all_video_codecs_except_one(marie->lc, "VP8");
pauline_vtable = linphone_core_v_table_new();
pauline_vtable->call_state_changed = video_call_state_changed;
linphone_core_add_listener(pauline->lc, pauline_vtable);
linphone_core_set_video_device(pauline->lc, "StaticImage: Static picture");
linphone_core_enable_video_capture(pauline->lc, TRUE);
linphone_core_enable_video_display(pauline->lc, TRUE);
pauline_params = linphone_core_create_default_call_parameters(pauline->lc);
linphone_call_params_enable_video(pauline_params, TRUE);
disable_all_video_codecs_except_one(pauline->lc, "VP8");
CU_ASSERT_TRUE(video_call_with_params(marie, pauline, marie_params, pauline_params));
/* Wait for 3s. */
wait_for_until(marie->lc, pauline->lc, &dummy, 1, 3000);
linphone_core_terminate_all_calls(marie->lc);
CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1));
CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1));
CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallReleased, 1));
CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallReleased, 1));
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
test_t video_tests[] = {
{ "Early-media video during video call", early_media_video_during_video_call_test }
};
test_suite_t video_test_suite = {
"Video",
NULL,
NULL,
sizeof(video_tests) / sizeof(video_tests[0]),
video_tests
};
#endif /* VIDEO_ENABLED */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment