diff --git a/gajim/data/gui/preferences_window.ui b/gajim/data/gui/preferences_window.ui index ec91d31002e7949e9b7c24e24e9180e0f01ca886..f9e027d95707c3f7f4036cb202a06f44e95f1295 100644 --- a/gajim/data/gui/preferences_window.ui +++ b/gajim/data/gui/preferences_window.ui @@ -2181,312 +2181,422 @@ $T will be replaced by auto-not-available timeout.</property> </packing> </child> <child> - <object class="GtkBox" id="audio_video_tab"> + <object class="GtkScrolledWindow"> <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="border_width">18</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> + <property name="can_focus">True</property> <child> - <object class="GtkGrid"> + <object class="GtkViewport"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="halign">start</property> - <property name="row_spacing">6</property> - <property name="column_spacing">12</property> - <child> - <object class="GtkLabel"> - <property name="width_request">-1</property> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">end</property> - <property name="label" translatable="yes">A_udio output device</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">audio_output_combobox</property> - <style> - <class name="dim-label"/> - </style> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">2</property> - </packing> - </child> - <child> - <object class="GtkComboBox" id="audio_output_combobox"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <signal name="changed" handler="on_audio_output_combobox_changed" swapped="no"/> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">2</property> - </packing> - </child> - <child> - <object class="GtkComboBox" id="audio_input_combobox"> - <property name="width_request">200</property> - <property name="visible">True</property> - <property name="can_focus">False</property> - <signal name="changed" handler="on_audio_input_combobox_changed" swapped="no"/> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkLabel"> - <property name="width_request">-1</property> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">end</property> - <property name="label" translatable="yes">_Audio input device</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">audio_input_combobox</property> - <style> - <class name="dim-label"/> - </style> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkLabel"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">start</property> - <property name="label" translatable="yes">Audio</property> - <property name="use_markup">True</property> - <style> - <class name="bold"/> - <class name="margin-top6"/> - </style> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> - </packing> - </child> - <child> - <object class="GtkLabel"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">start</property> - <property name="label" translatable="yes">Video</property> - <property name="use_markup">True</property> - <style> - <class name="bold"/> - <class name="margin-top6"/> - </style> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">3</property> - </packing> - </child> <child> - <object class="GtkLabel"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">end</property> - <property name="label" translatable="yes">_Video input device</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">video_input_combobox</property> - <style> - <class name="dim-label"/> - </style> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">4</property> - </packing> - </child> - <child> - <object class="GtkComboBox" id="video_input_combobox"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <signal name="changed" handler="on_video_input_combobox_changed" swapped="no"/> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">4</property> - </packing> - </child> - <child> - <object class="GtkLabel"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">end</property> - <property name="label" translatable="yes">Video output</property> - <property name="mnemonic_widget">selected_video_output</property> - <style> - <class name="dim-label"/> - </style> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">5</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="selected_video_output"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">start</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">5</property> - </packing> - </child> - <child> - <object class="GtkLabel"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">end</property> - <property name="margin_top">12</property> - <property name="label" translatable="yes">Video _framerate</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">video_framerate_combobox</property> - <style> - <class name="dim-label"/> - </style> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">6</property> - </packing> - </child> - <child> - <object class="GtkComboBox" id="video_framerate_combobox"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="margin_top">12</property> - <signal name="changed" handler="on_video_framerate_combobox_changed" swapped="no"/> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">6</property> - </packing> - </child> - <child> - <object class="GtkLabel"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">end</property> - <property name="label" translatable="yes">Video si_ze</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">video_size_combobox</property> - <style> - <class name="dim-label"/> - </style> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">7</property> - </packing> - </child> - <child> - <object class="GtkComboBox" id="video_size_combobox"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <signal name="changed" handler="on_video_size_combobox_changed" swapped="no"/> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">7</property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="video_see_self_checkbutton"> - <property name="label" translatable="yes">Vi_ew own video source</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="halign">start</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - <signal name="toggled" handler="on_video_see_self_checkbutton_toggled" swapped="no"/> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">8</property> - </packing> - </child> - <child> - <object class="GtkLabel"> + <object class="GtkBox"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="halign">start</property> - <property name="label" translatable="yes">Connection</property> - <property name="use_markup">True</property> - <style> - <class name="bold"/> - <class name="margin-top6"/> - </style> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">9</property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="stun_checkbutton"> - <property name="label" translatable="yes">STU_N server</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="halign">end</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - <signal name="toggled" handler="on_stun_checkbutton_toggled" swapped="no"/> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">10</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="stun_server_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip_text" translatable="yes">STUN server hostname. If no hostname was given, Gajim will try + <property name="orientation">vertical</property> + <child> + <object class="GtkGrid"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="hexpand">True</property> + <property name="border_width">18</property> + <property name="row_spacing">6</property> + <property name="column_spacing">12</property> + <child> + <object class="GtkLabel"> + <property name="width_request">-1</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + <property name="label" translatable="yes">A_udio output device</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">audio_output_combobox</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">2</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="audio_output_combobox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <signal name="changed" handler="on_audio_output_combobox_changed" swapped="no"/> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">2</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="audio_input_combobox"> + <property name="width_request">200</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <signal name="changed" handler="on_audio_input_combobox_changed" swapped="no"/> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="width_request">-1</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + <property name="label" translatable="yes">_Audio input device</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">audio_input_combobox</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">start</property> + <property name="label" translatable="yes">Audio</property> + <property name="use_markup">True</property> + <style> + <class name="bold"/> + <class name="margin-top6"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">start</property> + <property name="label" translatable="yes">Video</property> + <property name="use_markup">True</property> + <style> + <class name="bold"/> + <class name="margin-top6"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">3</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + <property name="label" translatable="yes">_Video input device</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">video_input_combobox</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">4</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="video_input_combobox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <signal name="changed" handler="on_video_input_combobox_changed" swapped="no"/> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">4</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="stun_checkbutton"> + <property name="label" translatable="yes">STU_N server</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="halign">end</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + <signal name="toggled" handler="on_stun_checkbutton_toggled" swapped="no"/> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">11</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="stun_server_entry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="tooltip_text" translatable="yes">STUN server hostname. If no hostname was given, Gajim will try to discover one from the server. (Example: stun.iptel.org)</property> - <property name="invisible_char">â—</property> - <signal name="changed" handler="stun_server_entry_changed" swapped="no"/> + <property name="invisible_char">â—</property> + <signal name="changed" handler="stun_server_entry_changed" swapped="no"/> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">11</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">start</property> + <property name="label" translatable="yes">Connection</property> + <property name="use_markup">True</property> + <style> + <class name="bold"/> + <class name="margin-top6"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">10</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="video_see_self_checkbutton"> + <property name="label" translatable="yes">Vi_ew own video source</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="halign">start</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + <signal name="toggled" handler="on_video_see_self_checkbutton_toggled" swapped="no"/> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">9</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="video_size_combobox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <signal name="changed" handler="on_video_size_combobox_changed" swapped="no"/> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">8</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + <property name="label" translatable="yes">Video si_ze</property> + <property name="use_underline">True</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">8</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + <property name="margin_top">12</property> + <property name="label" translatable="yes">Video _framerate</property> + <property name="use_underline">True</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">7</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="video_framerate_combobox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_top">12</property> + <signal name="changed" handler="on_video_framerate_combobox_changed" swapped="no"/> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">7</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + <property name="label" translatable="yes">Video output</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">6</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="selected_video_output"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">start</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">6</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="live_preview_checkbutton"> + <property name="label" translatable="yes">Show live _preview</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="halign">start</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + <signal name="toggled" handler="_on_live_preview_toggled" swapped="no"/> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">5</property> + </packing> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkSeparator"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_top">12</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox" id="av_preview_box"> + <property name="height_request">250</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkBox" id="av_preview_placeholder"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_top">12</property> + <property name="icon_name">camera-web-symbolic</property> + <property name="icon_size">6</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Live Preview</property> + <property name="justify">center</property> + <style> + <class name="bold"/> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">10</property> - </packing> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> </child> </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> </child> </object> <packing> - <property name="expand">False</property> + <property name="expand">True</property> <property name="fill">True</property> - <property name="position">1</property> + <property name="position">2</property> </packing> </child> </object> diff --git a/gajim/gtk/preferences.py b/gajim/gtk/preferences.py index 7c25983fcbd5c70e4a303d63e3a6677a3ef2e7c4..a7333bb2c5b275e0ba2fca1ad47ea83338325574 100644 --- a/gajim/gtk/preferences.py +++ b/gajim/gtk/preferences.py @@ -369,9 +369,12 @@ def create_av_combobox(opt_name, device_dict, config_name=None, self._ui.av_dependencies_infobar.set_no_show_all(True) self._ui.av_dependencies_infobar.hide() - create_av_combobox('audio_input', AudioInputManager().get_devices()) - create_av_combobox('audio_output', AudioOutputManager().get_devices()) - create_av_combobox('video_input', VideoInputManager().get_devices()) + create_av_combobox( + 'audio_input', AudioInputManager().get_devices()) + create_av_combobox( + 'audio_output', AudioOutputManager().get_devices()) + create_av_combobox( + 'video_input', VideoInputManager().get_devices()) create_av_combobox( 'video_framerate', @@ -393,99 +396,22 @@ def create_av_combobox(opt_name, device_dict, config_name=None, st = app.config.get('video_see_self') self._ui.video_see_self_checkbutton.set_active(st) - def on_av_map(tab): - label = self._ui.selected_video_output - sink, widget, name = gstreamer.create_gtk_widget() - if sink is None: - log.error('Failed to obtain a working Gstreamer GTK+ sink, ' - 'video support will be disabled') - self._ui.video_input_combobox.set_sensitive(False) - label.set_markup( - _('<span color="red" font-weight="bold">' - 'Unavailable</span>, video support will be disabled')) - return - - text = '' - if name == 'gtkglsink': - text = _('<span color="green" font-weight="bold">' - 'OpenGL</span> accelerated') - elif name == 'gtksink': - text = _('<span color="yellow" font-weight="bold">' - 'Unaccelerated</span>') - label.set_markup(text) - if self.av_pipeline is None: - self.av_pipeline = Gst.Pipeline.new('preferences-pipeline') - else: - self.av_pipeline.set_state(Gst.State.NULL) - self.av_pipeline.add(sink) - self.av_sink = sink - if self.av_widget is not None: - tab.remove(self.av_widget) - tab.add(widget) - self.av_widget = widget - - src_name = app.config.get('video_input_device') - try: - self.av_src = Gst.parse_bin_from_description(src_name, True) - except GLib.Error: - log.error('Failed to parse "%s" as Gstreamer element,' - ' falling back to autovideosrc', src_name) - self.av_src = None - if self.av_src is not None: - self.av_pipeline.add(self.av_src) - self.av_src.link(self.av_sink) - self.av_pipeline.set_state(Gst.State.PLAYING) - else: - # Parsing the pipeline stored in video_input_device failed, - # let’s try the default one. - self.av_src = Gst.ElementFactory.make('autovideosrc', None) - if self.av_src is None: - log.error('Failed to obtain a working Gstreamer source,' - ' video will be disabled.') - self._ui.video_input_combobox.set_sensitive(False) - return - # Great, this succeeded, let’s store it back into the - # config and use it. We’ve made autovideosrc the first - # element in the combobox so we can pick index 0 without - # worry. - combobox = self._ui.video_input_combobox - combobox.set_active(0) - - def on_av_unmap(tab): - if self.av_pipeline is not None: - self.av_pipeline.set_state(Gst.State.NULL) - if self.av_src is not None: - self.av_pipeline.remove(self.av_src) - self.av_src = None - if self.av_sink is not None: - self.av_pipeline.remove(self.av_sink) - self.av_sink = None - if self.av_widget is not None: - tab.remove(self.av_widget) - self.av_widget = None - self.av_pipeline = None - self.av_pipeline = None self.av_src = None self.av_sink = None self.av_widget = None - tab = self._ui.audio_video_tab - tab.connect('map', on_av_map) - tab.connect('unmap', on_av_unmap) - else: for opt_name in ('audio_input', 'audio_output', 'video_input', 'video_framerate', 'video_size'): combobox = self._ui.get_object(opt_name + '_combobox') combobox.set_sensitive(False) + self._ui.live_preview_checkbutton.set_sensitive(False) # STUN st = app.config.get('use_stun_server') self._ui.stun_checkbutton.set_active(st) - + self._ui.stun_server_entry.set_sensitive(st) self._ui.stun_server_entry.set_text(app.config.get('stun_server')) - if not st: - self._ui.stun_server_entry.set_sensitive(False) ### Advanced tab ### @@ -994,15 +920,89 @@ def on_video_input_combobox_changed(self, widget): widget.set_active(0) return - self.av_pipeline.set_state(Gst.State.NULL) - if self.av_src is not None: - self.av_pipeline.remove(self.av_src) - self.av_pipeline.add(src) - src.link(self.av_sink) - self.av_src = src - self.av_pipeline.set_state(Gst.State.PLAYING) + if self._ui.live_preview_checkbutton.get_active(): + self.av_pipeline.set_state(Gst.State.NULL) + if self.av_src is not None: + self.av_pipeline.remove(self.av_src) + self.av_pipeline.add(src) + src.link(self.av_sink) + self.av_src = src + self.av_pipeline.set_state(Gst.State.PLAYING) app.config.set('video_input_device', device) + def _on_live_preview_toggled(self, widget): + if widget.get_active(): + sink, widget, name = gstreamer.create_gtk_widget() + if sink is None: + log.error('Failed to obtain a working Gstreamer GTK+ sink, ' + 'video support will be disabled') + self._ui.video_input_combobox.set_sensitive(False) + self._ui.selected_video_output.set_markup( + _('<span color="red" font-weight="bold">' + 'Unavailable</span>, video support will be disabled')) + return + + text = '' + if name == 'gtkglsink': + text = _('<span color="green" font-weight="bold">' + 'OpenGL</span> accelerated') + elif name == 'gtksink': + text = _('<span color="yellow" font-weight="bold">' + 'Unaccelerated</span>') + self._ui.selected_video_output.set_markup(text) + if self.av_pipeline is None: + self.av_pipeline = Gst.Pipeline.new('preferences-pipeline') + else: + self.av_pipeline.set_state(Gst.State.NULL) + self.av_pipeline.add(sink) + self.av_sink = sink + + if self.av_widget is not None: + self._ui.av_preview_box.remove(self.av_widget) + self._ui.av_preview_placeholder.set_visible(False) + self._ui.av_preview_box.add(widget) + self.av_widget = widget + + src_name = app.config.get('video_input_device') + try: + self.av_src = Gst.parse_bin_from_description(src_name, True) + except GLib.Error: + log.error('Failed to parse "%s" as Gstreamer element, ' + 'falling back to autovideosrc', src_name) + self.av_src = None + if self.av_src is not None: + self.av_pipeline.add(self.av_src) + self.av_src.link(self.av_sink) + self.av_pipeline.set_state(Gst.State.PLAYING) + else: + # Parsing the pipeline stored in video_input_device failed, + # let’s try the default one. + self.av_src = Gst.ElementFactory.make('autovideosrc', None) + if self.av_src is None: + log.error('Failed to obtain a working Gstreamer source, ' + 'video will be disabled.') + self._ui.video_input_combobox.set_sensitive(False) + return + # Great, this succeeded, let’s store it back into the + # config and use it. We’ve made autovideosrc the first + # element in the combobox so we can pick index 0 without + # worry. + self._ui.video_input_combobox.set_active(0) + else: + if self.av_pipeline is not None: + self.av_pipeline.set_state(Gst.State.NULL) + if self.av_src is not None: + self.av_pipeline.remove(self.av_src) + self.av_src = None + if self.av_sink is not None: + self.av_pipeline.remove(self.av_sink) + self.av_sink = None + if self.av_widget is not None: + self._ui.av_preview_box.remove(self.av_widget) + self._ui.av_preview_placeholder.set_visible(True) + self.av_widget = None + self.av_pipeline = None + def on_video_framerate_combobox_changed(self, widget): self.on_av_combobox_changed(widget, 'video_framerate')