diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index f4f596807..3f2102445 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1372,6 +1372,7 @@ void linphone_call_init_video_stream(LinphoneCall *call){ if ((lc->video_conf.display || lc->video_conf.capture) && call->params.has_video){ int video_recv_buf_size=lp_config_get_int(lc->config,"video","recv_buf_size",0); int dscp=linphone_core_get_video_dscp(lc); + const char *display_filter=linphone_core_get_video_display_filter(lc); call->videostream=video_stream_new(call->video_port,call->video_port+1,linphone_core_ipv6_enabled(lc)); if (dscp!=-1) @@ -1379,8 +1380,8 @@ void linphone_call_init_video_stream(LinphoneCall *call){ video_stream_enable_display_filter_auto_rotate(call->videostream, lp_config_get_int(lc->config,"video","display_filter_auto_rotate",0)); if (video_recv_buf_size>0) rtp_session_set_recv_buf_size(call->videostream->ms.session,video_recv_buf_size); - if( lc->video_conf.displaytype != NULL) - video_stream_set_display_filter_name(call->videostream,lc->video_conf.displaytype); + if (display_filter != NULL) + video_stream_set_display_filter_name(call->videostream,display_filter); video_stream_set_event_callback(call->videostream,video_stream_event_cb, call); if (lc->rtptf){ RtpTransport *vrtp=lc->rtptf->video_rtp_func(lc->rtptf->video_rtp_func_data, call->video_port); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index b37e90936..0aad47e1c 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -956,10 +956,6 @@ static void video_config_read(LinphoneCore *lc){ self_view=lp_config_get_int(lc->config,"video","self_view",1); vpol.automatically_initiate=lp_config_get_int(lc->config,"video","automatically_initiate",1); vpol.automatically_accept=lp_config_get_int(lc->config,"video","automatically_accept",1); - lc->video_conf.displaytype=lp_config_get_string(lc->config,"video","displaytype",NULL); - if(lc->video_conf.displaytype) - ms_message("we are using a specific display:%s\n",lc->video_conf.displaytype); - linphone_core_enable_video(lc,capture,display); linphone_core_enable_video_preview(lc,lp_config_get_int(lc->config,"video","show_local",0)); linphone_core_enable_self_view(lc,self_view); @@ -4622,10 +4618,11 @@ static void toggle_video_preview(LinphoneCore *lc, bool_t val){ #ifdef VIDEO_ENABLED if (val){ if (lc->previewstream==NULL){ + const char *display_filter=linphone_core_get_video_display_filter(lc); lc->previewstream=video_preview_new(); video_preview_set_size(lc->previewstream,lc->video_conf.vsize); - if (lc->video_conf.displaytype) - video_preview_set_display_filter_name(lc->previewstream,lc->video_conf.displaytype); + if (display_filter) + video_preview_set_display_filter_name(lc->previewstream,display_filter); if (lc->preview_window_id!=0) video_preview_set_native_window_id(lc->previewstream,lc->preview_window_id); video_preview_start(lc->previewstream,lc->video_conf.device); diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 638f50a64..1705ad2af 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -1716,6 +1716,9 @@ LINPHONE_PUBLIC int linphone_core_get_audio_dscp(const LinphoneCore *lc); LINPHONE_PUBLIC void linphone_core_set_video_dscp(LinphoneCore *lc, int dscp); LINPHONE_PUBLIC int linphone_core_get_video_dscp(const LinphoneCore *lc); +LINPHONE_PUBLIC const char *linphone_core_get_video_display_filter(LinphoneCore *lc); +LINPHONE_PUBLIC void linphone_core_set_video_display_filter(LinphoneCore *lc, const char *filtername); + #ifdef __cplusplus } diff --git a/coreapi/misc.c b/coreapi/misc.c index b23a36b61..e88538fb3 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -1283,3 +1283,22 @@ LinphoneReason linphone_reason_from_sal(SalReason r){ return ret; } +/** + * Set the name of the mediastreamer2 filter to be used for rendering video. + * This is for advanced users of the library, mainly to workaround hardware/driver bugs. + * @ingroup media_parameters +**/ +void linphone_core_set_video_display_filter(LinphoneCore *lc, const char *filter_name){ + lp_config_set_string(lc->config,"video","displaytype",filter_name); +} + +/** + * Get the name of the mediastreamer2 filter used for rendering video. + * @ingroup media_parameters +**/ +const char *linphone_core_get_video_display_filter(LinphoneCore *lc){ + return lp_config_get_string(lc->config,"video","displaytype",NULL); +} + + + diff --git a/coreapi/private.h b/coreapi/private.h index 7c70a0df2..d8250df90 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -540,7 +540,6 @@ typedef struct video_config{ bool_t show_local; bool_t display; bool_t selfview; /*during calls*/ - const char *displaytype; }video_config_t; typedef struct ui_config diff --git a/gtk/parameters.ui b/gtk/parameters.ui index b8063792f..6624ec01c 100644 --- a/gtk/parameters.ui +++ b/gtk/parameters.ui @@ -1173,7 +1173,7 @@ True False - 2 + 3 2 @@ -1237,6 +1237,39 @@ 2 + + + True + False + Video output method: + right + + + 2 + 3 + GTK_EXPAND + + + + + True + False + + + + + 0 + + + + + 1 + 2 + 2 + 3 + GTK_EXPAND + + diff --git a/gtk/propertybox.c b/gtk/propertybox.c index b536edfd3..9467d109c 100644 --- a/gtk/propertybox.c +++ b/gtk/propertybox.c @@ -28,21 +28,35 @@ typedef enum { static void linphone_gtk_fill_combo_box(GtkWidget *combo, const char **devices, const char *selected, DeviceCap cap){ const char **p=devices; - int i=0,active=0; - /* glade creates a combo box without list model and text renderer, - unless we fill it with a dummy text. - This dummy text needs to be removed first*/ - gtk_combo_box_remove_text(GTK_COMBO_BOX(combo),0); + int i=0,active=-1; + GtkTreeModel *model; + + + if ((model=gtk_combo_box_get_model(GTK_COMBO_BOX(combo)))==NULL){ + /*case where combo box is created with no model*/ + GtkCellRenderer *renderer=gtk_cell_renderer_text_new(); + model=GTK_TREE_MODEL(gtk_list_store_new(1,G_TYPE_STRING)); + gtk_combo_box_set_model(GTK_COMBO_BOX(combo),model); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo),renderer,TRUE); + gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo),renderer,"text",0,NULL); + }else{ + gtk_list_store_clear(GTK_LIST_STORE(model)); + /* glade creates a combo box without list model and text renderer, + unless we fill it with a dummy text. + This dummy text needs to be removed first*/ + } + for(;*p!=NULL;++p){ if ( cap==CAP_IGNORE || (cap==CAP_CAPTURE && linphone_core_sound_device_can_capture(linphone_gtk_get_core(),*p)) || (cap==CAP_PLAYBACK && linphone_core_sound_device_can_playback(linphone_gtk_get_core(),*p)) ){ gtk_combo_box_append_text(GTK_COMBO_BOX(combo),*p); - if (strcmp(selected,*p)==0) active=i; + if (selected && strcmp(selected,*p)==0) active=i; i++; } } - gtk_combo_box_set_active(GTK_COMBO_BOX(combo),active); + if (active!=-1) + gtk_combo_box_set_active(GTK_COMBO_BOX(combo),active); } void linphone_gtk_fill_video_sizes(GtkWidget *combo){ @@ -317,6 +331,16 @@ void linphone_gtk_video_size_changed(GtkWidget *w){ defs[sel].vsize); } +void linphone_gtk_video_renderer_changed(GtkWidget *w){ + GtkTreeIter iter; + if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(w),&iter)){ + GtkTreeModel *model=gtk_combo_box_get_model(GTK_COMBO_BOX(w)); + gchar *name; + gtk_tree_model_get(model,&iter,0,&name,-1); + linphone_core_set_video_display_filter(linphone_gtk_get_core(),name); + } +} + void linphone_gtk_ring_file_set(GtkWidget *w){ gchar *file=gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(w)); linphone_core_set_ring(linphone_gtk_get_core(),file); @@ -1021,6 +1045,34 @@ void linphone_gtk_fill_webcams(GtkWidget *pb){ linphone_core_get_video_device(lc),CAP_IGNORE); } +void linphone_gtk_fill_video_renderers(GtkWidget *pb){ + LinphoneCore *lc=linphone_gtk_get_core(); + GtkWidget *combo=linphone_gtk_get_widget(pb,"renderers"); + MSList *l=ms_filter_lookup_by_interface(MSFilterVideoDisplayInterface); + MSList *elem; + int i; + const char *current_renderer=linphone_core_get_video_display_filter(lc); + GtkListStore *store; + GtkCellRenderer *renderer=gtk_cell_renderer_text_new(); + GtkTreeModel *model=GTK_TREE_MODEL(store=gtk_list_store_new(2,G_TYPE_STRING,G_TYPE_STRING)); + + gtk_combo_box_set_model(GTK_COMBO_BOX(combo),model); + gtk_cell_layout_clear(GTK_CELL_LAYOUT(combo)); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo),renderer,TRUE); + gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo),renderer,"text",1,NULL); + + for(i=0,elem=l;elem!=NULL && i<4 ;elem=elem->next,++i){ + MSFilterDesc *desc=(MSFilterDesc *)elem->data; + GtkTreeIter iter; + gtk_list_store_append(store,&iter); + gtk_list_store_set(store,&iter,0,desc->name,1,desc->text,-1); + if (current_renderer && strcmp(current_renderer,desc->name)==0) + gtk_combo_box_set_active(GTK_COMBO_BOX(combo),i); + } + ms_list_free(l); + +} + void linphone_gtk_show_parameters(void){ GtkWidget *mw=linphone_gtk_get_main_window(); GtkWidget *pb=(GtkWidget*)g_object_get_data(G_OBJECT(mw),"parameters"); @@ -1122,7 +1174,7 @@ void linphone_gtk_show_parameters(void){ /* MUTIMEDIA CONFIG */ linphone_gtk_fill_soundcards(pb); linphone_gtk_fill_webcams(pb); - + linphone_gtk_fill_video_renderers(pb); linphone_gtk_fill_video_sizes(linphone_gtk_get_widget(pb,"video_size")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"echo_cancelation")), linphone_core_echo_cancellation_enabled(lc)); diff --git a/mediastreamer2 b/mediastreamer2 index 67f1cce71..b25b9d8c6 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 67f1cce7101a43f31cc0b1f132b90b6111516bc8 +Subproject commit b25b9d8c6b48575761d2e37c4d0308bc6e93723c