From 5863df792e94e9dc183fd7a138069867f2b61fb2 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 12 Dec 2014 16:42:27 +0100 Subject: [PATCH] Make the preview window a real gtk window. Move camera preview test within the settings. --- NEWS | 11 +++++++ coreapi/linphonecore.c | 16 ++++++++++ coreapi/linphonecore.h | 1 + gtk/linphone.h | 1 + gtk/main.c | 22 ++----------- gtk/parameters.ui | 30 +++++++++++++----- gtk/videowindow.c | 71 +++++++++++++++++++++++++++++++++++++----- 7 files changed, 118 insertions(+), 34 deletions(-) diff --git a/NEWS b/NEWS index 6fada612f..bb1d573a0 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,14 @@ +linphone-3.8.0 -- Date to be defined + Application level improvements: + * The video window has now controls in order to switch fullscreen mode and terminate call. + * The out of call video preview feature (to test camera) is moved into the settings and is no longer linked to the in-call video preview feature. + * Lots of updated translations. + + Liblinphone level improvements: + * Support for RTP/AVPF (RFCxxxx) for video streams, allowing fast transmission error recovery with VP8 codec only. + * API enhancements, most objects can be ref-counted. + * Call video recording feature, in mkv format (H264 streams only for the moment) + linphone-3.7.0 -- February 20th, 2014 Application level improvements: * It is now possible to configure multiple proxy accounts with different transports (UDP, TCP, TLS) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index c3a838aef..b0fa65e12 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -5640,6 +5640,22 @@ MSVideoSize linphone_core_get_preview_video_size(const LinphoneCore *lc){ return lc->video_conf.preview_vsize; } +/** + * Returns the effective video size for the captured video as provided by the camera. + * When preview is disabled or not yet started, this function returns a zeroed video size. + * @see linphone_core_set_preview_video_size() + * @ingroup media_parameters + * @param lc the core + * @return a MSVideoSize +**/ +MSVideoSize linphone_core_get_current_preview_video_size(const LinphoneCore *lc){ + MSVideoSize ret={0}; + if (lc->previewstream){ + ret=video_preview_get_current_size(lc->previewstream); + } + return ret; +} + /** * Sets the preview video size by its name. See linphone_core_set_preview_video_size() for more information about this feature. * diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 5c24d14a7..155170338 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -2811,6 +2811,7 @@ LINPHONE_PUBLIC void linphone_core_set_preferred_video_size(LinphoneCore *lc, MS LINPHONE_PUBLIC void linphone_core_set_preview_video_size(LinphoneCore *lc, MSVideoSize vsize); LINPHONE_PUBLIC void linphone_core_set_preview_video_size_by_name(LinphoneCore *lc, const char *name); LINPHONE_PUBLIC MSVideoSize linphone_core_get_preview_video_size(const LinphoneCore *lc); +LINPHONE_PUBLIC MSVideoSize linphone_core_get_current_preview_video_size(const LinphoneCore *lc); LINPHONE_PUBLIC MSVideoSize linphone_core_get_preferred_video_size(const LinphoneCore *lc); /** diff --git a/gtk/linphone.h b/gtk/linphone.h index 70f1c58e3..cfb52f5e7 100644 --- a/gtk/linphone.h +++ b/gtk/linphone.h @@ -199,4 +199,5 @@ void linphone_gtk_close_config_fetching(GtkWidget *w, LinphoneConfiguringState s const char *linphone_gtk_get_sound_path(const char *file); void linphone_gtk_in_call_show_video(LinphoneCall *call); char *linphone_gtk_address(const LinphoneAddress *addr);/*return human readable identifier for a LinphoneAddress */ +GtkWidget *linphone_gtk_get_camera_preview_window(void); diff --git a/gtk/main.c b/gtk/main.c index 2bb9d5446..4303a770c 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -827,9 +827,6 @@ bool_t linphone_gtk_video_enabled(void){ void linphone_gtk_show_main_window(){ GtkWidget *w=linphone_gtk_get_main_window(); - LinphoneCore *lc=linphone_gtk_get_core(); - linphone_core_enable_video_preview(lc,linphone_gtk_get_ui_config_int("videoselfview", - VIDEOSELFVIEW_DEFAULT)); gtk_widget_show(w); gtk_window_present(GTK_WINDOW(w)); } @@ -1023,13 +1020,6 @@ void _linphone_gtk_enable_video(gboolean val){ linphone_core_enable_video_capture(linphone_gtk_get_core(), TRUE); linphone_core_enable_video_display(linphone_gtk_get_core(), TRUE); linphone_core_set_video_policy(linphone_gtk_get_core(),&policy); - - if (val){ - linphone_core_enable_video_preview(linphone_gtk_get_core(), - linphone_gtk_get_ui_config_int("videoselfview",VIDEOSELFVIEW_DEFAULT)); - }else{ - linphone_core_enable_video_preview(linphone_gtk_get_core(),FALSE); - } } void linphone_gtk_enable_video(GtkWidget *w){ @@ -1041,7 +1031,6 @@ void linphone_gtk_enable_video(GtkWidget *w){ void linphone_gtk_enable_self_view(GtkWidget *w){ gboolean val=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w)); LinphoneCore *lc=linphone_gtk_get_core(); - linphone_core_enable_video_preview(lc,val); linphone_core_enable_self_view(lc,val); linphone_gtk_set_ui_config_int("videoselfview",val); } @@ -1838,10 +1827,11 @@ void linphone_gtk_manage_login(void){ gboolean linphone_gtk_close(GtkWidget *mw){ /*shutdown calls if any*/ LinphoneCore *lc=linphone_gtk_get_core(); + GtkWidget *camera_preview=linphone_gtk_get_camera_preview_window(); if (linphone_core_in_call(lc)){ linphone_core_terminate_all_calls(lc); } - linphone_core_enable_video_preview(lc,FALSE); + if (camera_preview) gtk_widget_destroy(camera_preview); #ifdef __APPLE__ /*until with have a better option*/ gtk_window_iconify(GTK_WINDOW(mw)); #else @@ -1852,13 +1842,6 @@ gboolean linphone_gtk_close(GtkWidget *mw){ #ifdef HAVE_GTK_OSX static gboolean on_window_state_event(GtkWidget *w, GdkEventWindowState *event){ - bool_t video_enabled=linphone_gtk_video_enabled(); - if ((event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) ||(event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN) ){ - linphone_core_enable_video_preview(linphone_gtk_get_core(),FALSE); - }else{ - linphone_core_enable_video_preview(linphone_gtk_get_core(), - linphone_gtk_get_ui_config_int("videoselfview",VIDEOSELFVIEW_DEFAULT) && video_enabled); - } return FALSE; } #endif @@ -1969,6 +1952,7 @@ static void linphone_gtk_init_main_window(){ g_signal_connect(G_OBJECT(main_window), "window-state-event",G_CALLBACK(on_window_state_event), NULL); #endif linphone_gtk_check_menu_items(); + linphone_core_enable_video_preview(linphone_gtk_get_core(),FALSE); } void linphone_gtk_log_handler(OrtpLogLevel lev, const char *fmt, va_list args){ diff --git a/gtk/parameters.ui b/gtk/parameters.ui index aa8480aa9..8c2483ef7 100644 --- a/gtk/parameters.ui +++ b/gtk/parameters.ui @@ -1233,7 +1233,7 @@ True False - 3 + 4 2 @@ -1330,6 +1330,22 @@ GTK_EXPAND + + + Show camera preview + True + True + True + False + + + + 2 + 3 + 4 + GTK_EXPAND + + @@ -2188,7 +2204,7 @@ 1 2 GTK_FILL - + @@ -2250,7 +2266,7 @@ 2 3 GTK_FILL - + @@ -2265,7 +2281,7 @@ 2 3 GTK_FILL - + @@ -2538,7 +2554,7 @@ True False - label + label 1 @@ -2550,7 +2566,7 @@ True False - label + label 1 @@ -2564,7 +2580,7 @@ True False - label + label 1 diff --git a/gtk/videowindow.c b/gtk/videowindow.c index f2247e573..220569077 100644 --- a/gtk/videowindow.c +++ b/gtk/videowindow.c @@ -94,7 +94,7 @@ static gboolean drag_drop(GtkWidget *widget, GdkDragContext *drag_context, gint return TRUE; } -unsigned long get_native_handle(GdkWindow *gdkw){ +static unsigned long get_native_handle(GdkWindow *gdkw){ #ifdef GDK_WINDOWING_X11 return (unsigned long)GDK_WINDOW_XID(gdkw); #elif defined(WIN32) @@ -106,6 +106,15 @@ unsigned long get_native_handle(GdkWindow *gdkw){ return 0; } +static void _resize_video_window(GtkWidget *video_window, MSVideoSize vsize){ + MSVideoSize cur; + gtk_window_get_size(GTK_WINDOW(video_window),&cur.width,&cur.height); + if (vsize.width*vsize.height > cur.width*cur.height || + ms_video_size_get_orientation(vsize)!=ms_video_size_get_orientation(cur) ){ + gtk_window_resize(GTK_WINDOW(video_window),vsize.width,vsize.height); + } +} + static gint resize_video_window(LinphoneCall *call){ const LinphoneCallParams *params=linphone_call_get_current_params(call); if (params){ @@ -114,13 +123,7 @@ static gint resize_video_window(LinphoneCall *call){ GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call); GtkWidget *video_window=(GtkWidget*)g_object_get_data(G_OBJECT(callview),"video_window"); if (video_window){ - MSVideoSize cur; - gtk_window_get_size(GTK_WINDOW(video_window),&cur.width,&cur.height); - if (vsize.width*vsize.height > cur.width*cur.height || - ms_video_size_get_orientation(vsize)!=ms_video_size_get_orientation(cur) ){ - g_message("Resized to %ix%i",vsize.width,vsize.height); - gtk_window_resize(GTK_WINDOW(video_window),vsize.width,vsize.height); - } + _resize_video_window(video_window,vsize); } } } @@ -308,3 +311,55 @@ void linphone_gtk_in_call_show_video(LinphoneCall *call){ } } } + +static void on_video_preview_destroyed(GtkWidget *video_preview, GtkWidget *mw){ + LinphoneCore *lc=linphone_gtk_get_core(); + guint timeout_id=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(video_preview),"timeout-id")); + g_object_set_data(G_OBJECT(mw),"video_preview",NULL); + linphone_core_enable_video_preview(lc,FALSE); + linphone_core_set_native_preview_window_id(lc,-1); + g_source_remove(timeout_id); +} + +GtkWidget *linphone_gtk_get_camera_preview_window(void){ + return (GtkWidget *)g_object_get_data(G_OBJECT(linphone_gtk_get_main_window()),"video_preview"); +} + +static gboolean check_preview_size(GtkWidget *video_preview){ + MSVideoSize vsize=linphone_core_get_current_preview_video_size(linphone_gtk_get_core()); + if (vsize.width && vsize.height){ + MSVideoSize cur; + gtk_window_get_size(GTK_WINDOW(video_preview),&cur.width,&cur.height); + if (cur.width!=vsize.width || cur.height!=vsize.height){ + gtk_window_resize(GTK_WINDOW(video_preview),vsize.width,vsize.height); + } + } + return TRUE; +} + +void linphone_gtk_show_camera_preview_clicked(GtkButton *button){ + GtkWidget *mw=linphone_gtk_get_main_window(); + GtkWidget *video_preview=(GtkWidget *)g_object_get_data(G_OBJECT(mw),"video_preview"); + + if (!video_preview){ + gchar *title; + LinphoneCore *lc=linphone_gtk_get_core(); + GdkColor color; + guint tid; + + video_preview=gtk_window_new(GTK_WINDOW_TOPLEVEL); + title=g_strdup_printf("%s - Video preview",linphone_gtk_get_ui_config("title","Linphone")); + gtk_window_set_title(GTK_WINDOW(video_preview),title); + gdk_color_parse("black",&color); + gtk_widget_modify_bg(video_preview,GTK_STATE_NORMAL,&color); + g_free(title); + g_object_set_data(G_OBJECT(mw),"video_preview",video_preview); + g_signal_connect(video_preview,"destroy",(GCallback)on_video_preview_destroyed,mw); + gtk_widget_show(video_preview); + linphone_core_set_native_preview_window_id(lc,get_native_handle(gtk_widget_get_window(video_preview))); + linphone_core_enable_video_preview(lc,TRUE); + tid=g_timeout_add(100,(GSourceFunc)check_preview_size,video_preview); + g_object_set_data(G_OBJECT(video_preview),"timeout-id",GINT_TO_POINTER(tid)); + } +} +