ability to see out own video in the same time we send it and show both outging and incoming videos inside chat control

This commit is contained in:
Yann Leboulanger 2012-12-30 18:59:48 +01:00
parent 6879730568
commit c88522e5de
9 changed files with 694 additions and 567 deletions

View file

@ -11,6 +11,10 @@
<property name="border_width">3</property> <property name="border_width">3</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<property name="spacing">1</property> <property name="spacing">1</property>
<child>
<object class="GtkHPaned" id="hpaned1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child> <child>
<object class="GtkVBox" id="vbox2"> <object class="GtkVBox" id="vbox2">
<property name="visible">True</property> <property name="visible">True</property>
@ -274,8 +278,6 @@
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="has_tooltip">True</property>
<property name="tooltip_text" translatable="yes">Show a list of emoticons (Alt+M)</property>
<property name="relief">none</property> <property name="relief">none</property>
<property name="focus_on_click">False</property> <property name="focus_on_click">False</property>
<child> <child>
@ -298,8 +300,6 @@
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="has_tooltip">True</property>
<property name="tooltip_text" translatable="yes">Show a list of formattings</property>
<property name="relief">none</property> <property name="relief">none</property>
<property name="focus_on_click">False</property> <property name="focus_on_click">False</property>
<child> <child>
@ -332,8 +332,6 @@
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="no_show_all">True</property> <property name="no_show_all">True</property>
<property name="has_tooltip">True</property>
<property name="tooltip_text" translatable="yes">Add this contact to roster (Ctrl+D)</property>
<property name="relief">none</property> <property name="relief">none</property>
<child> <child>
<object class="GtkImage" id="image9"> <object class="GtkImage" id="image9">
@ -375,8 +373,6 @@
<object class="GtkToggleButton" id="audio_togglebutton"> <object class="GtkToggleButton" id="audio_togglebutton">
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="has_tooltip">True</property>
<property name="tooltip_text" translatable="yes">Toggle audio session</property>
<property name="relief">none</property> <property name="relief">none</property>
<child> <child>
<object class="GtkImage" id="audio_image"> <object class="GtkImage" id="audio_image">
@ -395,8 +391,6 @@
<object class="GtkToggleButton" id="video_togglebutton"> <object class="GtkToggleButton" id="video_togglebutton">
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="has_tooltip">True</property>
<property name="tooltip_text" translatable="yes">Toggle video session</property>
<property name="relief">none</property> <property name="relief">none</property>
<child> <child>
<object class="GtkImage" id="video_image"> <object class="GtkImage" id="video_image">
@ -417,8 +411,6 @@
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="has_tooltip">True</property>
<property name="tooltip_text" translatable="yes">Invite contacts to the conversation (Ctrl+G)</property>
<property name="relief">none</property> <property name="relief">none</property>
<property name="focus_on_click">False</property> <property name="focus_on_click">False</property>
<child> <child>
@ -441,8 +433,6 @@
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="has_tooltip">True</property>
<property name="tooltip_text" translatable="yes">Show the contact's profile (Ctrl+I)</property>
<property name="relief">none</property> <property name="relief">none</property>
<property name="focus_on_click">False</property> <property name="focus_on_click">False</property>
<child> <child>
@ -465,8 +455,6 @@
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="has_tooltip">True</property>
<property name="tooltip_text" translatable="yes">Browse the chat history (Ctrl+H)</property>
<property name="relief">none</property> <property name="relief">none</property>
<property name="focus_on_click">False</property> <property name="focus_on_click">False</property>
<child> <child>
@ -500,8 +488,6 @@
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="has_tooltip">True</property>
<property name="tooltip_text" translatable="yes">Show a menu of advanced functions (Alt+D)</property>
<property name="relief">none</property> <property name="relief">none</property>
<property name="focus_on_click">False</property> <property name="focus_on_click">False</property>
<child> <child>
@ -666,6 +652,76 @@ audio-mic-volume-low</property>
</packing> </packing>
</child> </child>
</object> </object>
<packing>
<property name="resize">False</property>
<property name="shrink">True</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="video_hbox">
<property name="no_show_all">True</property>
<property name="spacing">6</property>
<child>
<object class="GtkFixed" id="outgoing_fixed">
<property name="no_show_all">True</property>
<child>
<object class="GtkViewport" id="viewport1">
<property name="width_request">160</property>
<property name="height_request">120</property>
<property name="visible">True</property>
<property name="resize_mode">queue</property>
<child>
<object class="GtkDrawingArea" id="outgoing_drawingarea">
<property name="width_request">160</property>
<property name="height_request">120</property>
<property name="visible">True</property>
<property name="double_buffered">False</property>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkViewport" id="viewport2">
<property name="visible">True</property>
<property name="resize_mode">queue</property>
<child>
<object class="GtkDrawingArea" id="incoming_drawingarea">
<property name="width_request">320</property>
<property name="height_request">240</property>
<property name="visible">True</property>
<property name="double_buffered">False</property>
</object>
</child>
</object>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="resize">True</property>
<property name="shrink">True</property>
</packing>
</child>
</object>
<packing> <packing>
<property name="position">0</property> <property name="position">0</property>
</packing> </packing>
@ -712,8 +768,8 @@ audio-mic-volume-low</property>
<property name="relief">none</property> <property name="relief">none</property>
</object> </object>
<packing> <packing>
<property name="x_options"></property> <property name="x_options"/>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -727,8 +783,8 @@ audio-mic-volume-low</property>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="right_attach">2</property> <property name="right_attach">2</property>
<property name="x_options"></property> <property name="x_options"/>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -742,8 +798,8 @@ audio-mic-volume-low</property>
<packing> <packing>
<property name="left_attach">2</property> <property name="left_attach">2</property>
<property name="right_attach">3</property> <property name="right_attach">3</property>
<property name="x_options"></property> <property name="x_options"/>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -757,8 +813,8 @@ audio-mic-volume-low</property>
<packing> <packing>
<property name="top_attach">1</property> <property name="top_attach">1</property>
<property name="bottom_attach">2</property> <property name="bottom_attach">2</property>
<property name="x_options"></property> <property name="x_options"/>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -774,8 +830,8 @@ audio-mic-volume-low</property>
<property name="right_attach">2</property> <property name="right_attach">2</property>
<property name="top_attach">1</property> <property name="top_attach">1</property>
<property name="bottom_attach">2</property> <property name="bottom_attach">2</property>
<property name="x_options"></property> <property name="x_options"/>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -791,8 +847,8 @@ audio-mic-volume-low</property>
<property name="right_attach">3</property> <property name="right_attach">3</property>
<property name="top_attach">1</property> <property name="top_attach">1</property>
<property name="bottom_attach">2</property> <property name="bottom_attach">2</property>
<property name="x_options"></property> <property name="x_options"/>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -806,8 +862,8 @@ audio-mic-volume-low</property>
<packing> <packing>
<property name="top_attach">2</property> <property name="top_attach">2</property>
<property name="bottom_attach">3</property> <property name="bottom_attach">3</property>
<property name="x_options"></property> <property name="x_options"/>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -823,8 +879,8 @@ audio-mic-volume-low</property>
<property name="right_attach">2</property> <property name="right_attach">2</property>
<property name="top_attach">2</property> <property name="top_attach">2</property>
<property name="bottom_attach">3</property> <property name="bottom_attach">3</property>
<property name="x_options"></property> <property name="x_options"/>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -840,8 +896,8 @@ audio-mic-volume-low</property>
<property name="right_attach">3</property> <property name="right_attach">3</property>
<property name="top_attach">2</property> <property name="top_attach">2</property>
<property name="bottom_attach">3</property> <property name="bottom_attach">3</property>
<property name="x_options"></property> <property name="x_options"/>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -855,8 +911,8 @@ audio-mic-volume-low</property>
<packing> <packing>
<property name="top_attach">3</property> <property name="top_attach">3</property>
<property name="bottom_attach">4</property> <property name="bottom_attach">4</property>
<property name="x_options"></property> <property name="x_options"/>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -872,8 +928,8 @@ audio-mic-volume-low</property>
<property name="right_attach">2</property> <property name="right_attach">2</property>
<property name="top_attach">3</property> <property name="top_attach">3</property>
<property name="bottom_attach">4</property> <property name="bottom_attach">4</property>
<property name="x_options"></property> <property name="x_options"/>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -889,8 +945,8 @@ audio-mic-volume-low</property>
<property name="right_attach">3</property> <property name="right_attach">3</property>
<property name="top_attach">3</property> <property name="top_attach">3</property>
<property name="bottom_attach">4</property> <property name="bottom_attach">4</property>
<property name="x_options"></property> <property name="x_options"/>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
</object> </object>

View file

@ -2174,7 +2174,7 @@ $T will be replaced by auto-not-available timeout</property>
<child> <child>
<object class="GtkTable" id="table8"> <object class="GtkTable" id="table8">
<property name="visible">True</property> <property name="visible">True</property>
<property name="n_rows">4</property> <property name="n_rows">5</property>
<property name="n_columns">2</property> <property name="n_columns">2</property>
<property name="column_spacing">6</property> <property name="column_spacing">6</property>
<property name="row_spacing">6</property> <property name="row_spacing">6</property>
@ -2270,6 +2270,21 @@ $T will be replaced by auto-not-available timeout</property>
<property name="bottom_attach">4</property> <property name="bottom_attach">4</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkCheckButton" id="video_see_self_checkbutton">
<property name="label" translatable="yes">View own video source</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_video_see_self_checkbutton_toggled"/>
</object>
<packing>
<property name="right_attach">2</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
</packing>
</child>
</object> </object>
</child> </child>
</object> </object>

View file

@ -2151,10 +2151,27 @@ class ChatControl(ChatControlBase):
if widget.get_active(): if widget.get_active():
if getattr(self, jingle_type + '_state') == \ if getattr(self, jingle_type + '_state') == \
self.JINGLE_STATE_NULL: self.JINGLE_STATE_NULL:
if jingle_type == 'video':
video_hbox = self.xml.get_object('video_hbox')
video_hbox.set_no_show_all(False)
if gajim.config.get('video_see_self'):
fixed = self.xml.get_object('outgoing_fixed')
fixed.set_no_show_all(False)
video_hbox.show_all()
in_xid = self.xml.get_object('incoming_drawingarea').window.xid
out_xid = self.xml.get_object('outgoing_drawingarea').window.xid
sid = gajim.connections[self.account].start_video(
self.contact.get_full_jid(), in_xid, out_xid)
else:
sid = getattr(gajim.connections[self.account], sid = getattr(gajim.connections[self.account],
'start_' + jingle_type)(self.contact.get_full_jid()) 'start_' + jingle_type)(self.contact.get_full_jid())
getattr(self, 'set_' + jingle_type + '_state')('connecting', sid) getattr(self, 'set_' + jingle_type + '_state')('connecting', sid)
else: else:
video_hbox = self.xml.get_object('video_hbox')
video_hbox.set_no_show_all(True)
video_hbox.hide()
fixed = self.xml.get_object('outgoing_fixed')
fixed.set_no_show_all(True)
self.close_jingle_content(jingle_type) self.close_jingle_content(jingle_type)
img = getattr(self, '_' + jingle_type + '_button').get_property('image') img = getattr(self, '_' + jingle_type + '_button').get_property('image')

View file

@ -305,6 +305,7 @@ class Config:
'video_output_device': [opt_str, 'autovideosink'], 'video_output_device': [opt_str, 'autovideosink'],
'video_framerate': [opt_str, '', _('Optionally fix jingle output video framerate. Example: 10/1 or 25/2')], 'video_framerate': [opt_str, '', _('Optionally fix jingle output video framerate. Example: 10/1 or 25/2')],
'video_size': [opt_str, '', _('Optionally resize jingle output video. Example: 320x240')], 'video_size': [opt_str, '', _('Optionally resize jingle output video. Example: 320x240')],
'video_see_self': [opt_bool, True, _('If True, You will also see your webcam')],
'audio_input_volume': [opt_int, 50], 'audio_input_volume': [opt_int, 50],
'audio_output_volume': [opt_int, 50], 'audio_output_volume': [opt_int, 50],
'use_stun_server': [opt_bool, False, _('If True, Gajim will try to use a STUN server when using jingle. The one in "stun_server" option, or the one given by the jabber server.')], 'use_stun_server': [opt_bool, False, _('If True, Gajim will try to use a STUN server when using jingle. The one in "stun_server" option, or the one given by the jabber server.')],

View file

@ -120,16 +120,18 @@ class ConnectionJingle(object):
jingle.start_session() jingle.start_session()
return jingle.sid return jingle.sid
def start_video(self, jid): def start_video(self, jid, in_xid, out_xid):
if self.get_jingle_session(jid, media='video'): if self.get_jingle_session(jid, media='video'):
return self.get_jingle_session(jid, media='video').sid return self.get_jingle_session(jid, media='video').sid
jingle = self.get_jingle_session(jid, media='audio') jingle = self.get_jingle_session(jid, media='audio')
if jingle: if jingle:
jingle.add_content('video', JingleVideo(jingle)) jingle.add_content('video', JingleVideo(jingle, in_xid=in_xid,
out_xid=out_xid))
else: else:
jingle = JingleSession(self, weinitiate=True, jid=jid) jingle = JingleSession(self, weinitiate=True, jid=jid)
self._sessions[jingle.sid] = jingle self._sessions[jingle.sid] = jingle
jingle.add_content('video', JingleVideo(jingle)) jingle.add_content('video', JingleVideo(jingle, in_xid=in_xid,
out_xid=out_xid))
jingle.start_session() jingle.start_session()
return jingle.sid return jingle.sid

View file

@ -22,6 +22,7 @@ import socket
import nbxmpp import nbxmpp
import farstream, gst import farstream, gst
import gst.interfaces
from glib import GError from glib import GError
import gajim import gajim
@ -63,6 +64,7 @@ class JingleRTPContent(JingleContent):
# pipeline and bus # pipeline and bus
self.pipeline = gst.Pipeline() self.pipeline = gst.Pipeline()
bus = self.pipeline.get_bus() bus = self.pipeline.get_bus()
bus.enable_sync_message_emission()
bus.add_signal_watch() bus.add_signal_watch()
bus.connect('message', self._on_gst_message) bus.connect('message', self._on_gst_message)
@ -366,8 +368,11 @@ class JingleAudio(JingleRTPContent):
class JingleVideo(JingleRTPContent): class JingleVideo(JingleRTPContent):
def __init__(self, session, transport=None): def __init__(self, session, transport=None, in_xid=0, out_xid=0):
JingleRTPContent.__init__(self, session, 'video', transport) JingleRTPContent.__init__(self, session, 'video', transport)
self.in_xid = in_xid
self.out_xid = out_xid
self.out_xid_set = False
self.setup_stream() self.setup_stream()
def setup_stream(self): def setup_stream(self):
@ -375,6 +380,8 @@ class JingleVideo(JingleRTPContent):
# sometimes, one window won't show up, # sometimes, one window won't show up,
# sometimes it'll freeze... # sometimes it'll freeze...
JingleRTPContent.setup_stream(self, self._on_src_pad_added) JingleRTPContent.setup_stream(self, self._on_src_pad_added)
bus = self.pipeline.get_bus()
bus.connect('sync-message::element', self._on_sync_message)
# the local parts # the local parts
if gajim.config.get('video_framerate'): if gajim.config.get('video_framerate'):
@ -390,17 +397,25 @@ class JingleVideo(JingleRTPContent):
video_size = 'video/x-raw-yuv,width=%s,height=%s ! ' % (w, h) video_size = 'video/x-raw-yuv,width=%s,height=%s ! ' % (w, h)
else: else:
video_size = '' video_size = ''
if gajim.config.get('video_see_self'):
tee = '! tee name=t ! queue ! videoscale ! ' + \
'video/x-raw-yuv,width=160,height=120 ! ffmpegcolorspace ! ' + \
'%s t. ! queue ' % gajim.config.get(
'video_output_device')
else:
tee = ''
self.src_bin = self.make_bin_from_config('video_input_device', self.src_bin = self.make_bin_from_config('video_input_device',
'%%s ! %svideoscale ! %sffmpegcolorspace' % (framerate, video_size), '%%s %s! %svideoscale ! %sffmpegcolorspace' % (tee, framerate,
_("video input")) video_size), _("video input"))
#caps = gst.element_factory_make('capsfilter')
#caps.set_property('caps', gst.caps_from_string('video/x-raw-yuv, width=320, height=240'))
self.pipeline.add(self.src_bin)#, caps) self.pipeline.add(self.src_bin)#, caps)
self.pipeline.set_state(gst.STATE_PLAYING)
#src_bin.link(caps) #src_bin.link(caps)
self.sink = self.make_bin_from_config('video_output_device', self.sink = self.make_bin_from_config('video_output_device',
'videoscale ! ffmpegcolorspace ! %s force-aspect-ratio=True', 'videoscale ! ffmpegcolorspace ! %s',
_("video output")) _("video output"))
self.pipeline.add(self.sink) self.pipeline.add(self.sink)
@ -410,11 +425,27 @@ class JingleVideo(JingleRTPContent):
# The following is needed for farstream to process ICE requests: # The following is needed for farstream to process ICE requests:
self.pipeline.set_state(gst.STATE_PLAYING) self.pipeline.set_state(gst.STATE_PLAYING)
def _on_sync_message(self, bus, message):
if message.structure is None:
return False
if message.structure.get_name() == 'prepare-xwindow-id':
message.src.set_property('force-aspect-ratio', True)
imagesink = message.src
if gajim.config.get('video_see_self') and not self.out_xid_set:
imagesink.set_xwindow_id(self.out_xid)
self.out_xid_set = True
else:
imagesink.set_xwindow_id(self.in_xid)
def get_fallback_src(self): def get_fallback_src(self):
# TODO: Use avatar? # TODO: Use avatar?
pipeline = 'videotestsrc is-live=true ! video/x-raw-yuv,framerate=10/1 ! ffmpegcolorspace' pipeline = 'videotestsrc is-live=true ! video/x-raw-yuv,framerate=10/1 ! ffmpegcolorspace'
return gst.parse_bin_from_description(pipeline, True) return gst.parse_bin_from_description(pipeline, True)
def destroy(self):
JingleRTPContent.destroy(self)
self.pipeline.get_bus().disconnect_by_func(self._on_sync_message)
def get_content(desc): def get_content(desc):
if desc['media'] == 'audio': if desc['media'] == 'audio':
return JingleAudio return JingleAudio

View file

@ -102,7 +102,7 @@ class VideoOutputManager(DeviceManager):
def detect(self): def detect(self):
self.devices = {} self.devices = {}
# Fake video output # Fake video output
self.detect_element('fakesink', _('Fake audio output')) self.detect_element('fakesink', _('Fake video output'))
# Auto sink # Auto sink
self.detect_element('xvimagesink', self.detect_element('xvimagesink',
_('X Window System (X11/XShm/Xv): %s')) _('X Window System (X11/XShm/Xv): %s'))

View file

@ -478,6 +478,8 @@ class PreferencesWindow:
'800x600': '800x600', '640x480': '640x480', '800x600': '800x600', '640x480': '640x480',
'320x240': '320x240'}, 'video_size', key=lambda x: -1 if \ '320x240': '320x240'}, 'video_size', key=lambda x: -1 if \
not x[1] else int(x[0][:3])) not x[1] else int(x[0][:3]))
st = gajim.config.get('video_see_self')
self.xml.get_object('video_see_self_checkbutton').set_active(st)
else: else:
for opt_name in ('audio_input', 'audio_output', 'video_input', for opt_name in ('audio_input', 'audio_output', 'video_input',
@ -1131,6 +1133,9 @@ class PreferencesWindow:
def on_video_size_combobox_changed(self, widget): def on_video_size_combobox_changed(self, widget):
self.on_av_combobox_changed(widget, 'video_size') self.on_av_combobox_changed(widget, 'video_size')
def on_video_see_self_checkbutton_toggled(self, widget):
self.on_checkbutton_toggled(widget, 'video_see_self')
def on_stun_checkbutton_toggled(self, widget): def on_stun_checkbutton_toggled(self, widget):
self.on_checkbutton_toggled(widget, 'use_stun_server', self.on_checkbutton_toggled(widget, 'use_stun_server',
[self.xml.get_object('stun_server_entry')]) [self.xml.get_object('stun_server_entry')])

View file

@ -73,7 +73,7 @@ demandimport.enable()
demandimport.ignore += ['gobject._gobject', 'libasyncns', 'i18n', demandimport.ignore += ['gobject._gobject', 'libasyncns', 'i18n',
'logging.NullHandler', 'dbus.service', 'OpenSSL.SSL', 'OpenSSL.crypto', 'logging.NullHandler', 'dbus.service', 'OpenSSL.SSL', 'OpenSSL.crypto',
'common.sleepy', 'DLFCN', 'dl', 'xml.sax', 'xml.sax.handler', 'ic', 'common.sleepy', 'DLFCN', 'dl', 'xml.sax', 'xml.sax.handler', 'ic',
'Crypto.PublicKey', 'IPython'] 'Crypto.PublicKey', 'IPython', 'gst.interfaces']
if os.name == 'nt': if os.name == 'nt':
import locale import locale