Commit c88522e5 authored by Yann Leboulanger's avatar Yann Leboulanger

ability to see out own video in the same time we send it and show both outging...

ability to see out own video in the same time we send it and show both outging and incoming videos inside chat control
parent 68797305
This diff is collapsed.
......@@ -2174,7 +2174,7 @@ $T will be replaced by auto-not-available timeout</property>
<child>
<object class="GtkTable" id="table8">
<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="column_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>
</packing>
</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>
</child>
</object>
......
......@@ -2151,10 +2151,27 @@ class ChatControl(ChatControlBase):
if widget.get_active():
if getattr(self, jingle_type + '_state') == \
self.JINGLE_STATE_NULL:
sid = getattr(gajim.connections[self.account],
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],
'start_' + jingle_type)(self.contact.get_full_jid())
getattr(self, 'set_' + jingle_type + '_state')('connecting', sid)
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)
img = getattr(self, '_' + jingle_type + '_button').get_property('image')
......
......@@ -305,6 +305,7 @@ class Config:
'video_output_device': [opt_str, 'autovideosink'],
'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_see_self': [opt_bool, True, _('If True, You will also see your webcam')],
'audio_input_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.')],
......
......@@ -120,16 +120,18 @@ class ConnectionJingle(object):
jingle.start_session()
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'):
return self.get_jingle_session(jid, media='video').sid
jingle = self.get_jingle_session(jid, media='audio')
if jingle:
jingle.add_content('video', JingleVideo(jingle))
jingle.add_content('video', JingleVideo(jingle, in_xid=in_xid,
out_xid=out_xid))
else:
jingle = JingleSession(self, weinitiate=True, jid=jid)
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()
return jingle.sid
......
......@@ -22,6 +22,7 @@ import socket
import nbxmpp
import farstream, gst
import gst.interfaces
from glib import GError
import gajim
......@@ -63,6 +64,7 @@ class JingleRTPContent(JingleContent):
# pipeline and bus
self.pipeline = gst.Pipeline()
bus = self.pipeline.get_bus()
bus.enable_sync_message_emission()
bus.add_signal_watch()
bus.connect('message', self._on_gst_message)
......@@ -366,8 +368,11 @@ class JingleAudio(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)
self.in_xid = in_xid
self.out_xid = out_xid
self.out_xid_set = False
self.setup_stream()
def setup_stream(self):
......@@ -375,6 +380,8 @@ class JingleVideo(JingleRTPContent):
# sometimes, one window won't show up,
# sometimes it'll freeze...
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
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)
else:
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',
'%%s ! %svideoscale ! %sffmpegcolorspace' % (framerate, 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'))
'%%s %s! %svideoscale ! %sffmpegcolorspace' % (tee, framerate,
video_size), _("video input"))
self.pipeline.add(self.src_bin)#, caps)
self.pipeline.set_state(gst.STATE_PLAYING)
#src_bin.link(caps)
self.sink = self.make_bin_from_config('video_output_device',
'videoscale ! ffmpegcolorspace ! %s force-aspect-ratio=True',
'videoscale ! ffmpegcolorspace ! %s',
_("video output"))
self.pipeline.add(self.sink)
......@@ -410,11 +425,27 @@ class JingleVideo(JingleRTPContent):
# The following is needed for farstream to process ICE requests:
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):
# TODO: Use avatar?
pipeline = 'videotestsrc is-live=true ! video/x-raw-yuv,framerate=10/1 ! ffmpegcolorspace'
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):
if desc['media'] == 'audio':
return JingleAudio
......
......@@ -102,7 +102,7 @@ class VideoOutputManager(DeviceManager):
def detect(self):
self.devices = {}
# Fake video output
self.detect_element('fakesink', _('Fake audio output'))
self.detect_element('fakesink', _('Fake video output'))
# Auto sink
self.detect_element('xvimagesink',
_('X Window System (X11/XShm/Xv): %s'))
......
......@@ -478,6 +478,8 @@ class PreferencesWindow:
'800x600': '800x600', '640x480': '640x480',
'320x240': '320x240'}, 'video_size', key=lambda x: -1 if \
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:
for opt_name in ('audio_input', 'audio_output', 'video_input',
......@@ -1131,6 +1133,9 @@ class PreferencesWindow:
def on_video_size_combobox_changed(self, widget):
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):
self.on_checkbutton_toggled(widget, 'use_stun_server',
[self.xml.get_object('stun_server_entry')])
......
......@@ -73,7 +73,7 @@ demandimport.enable()
demandimport.ignore += ['gobject._gobject', 'libasyncns', 'i18n',
'logging.NullHandler', 'dbus.service', 'OpenSSL.SSL', 'OpenSSL.crypto',
'common.sleepy', 'DLFCN', 'dl', 'xml.sax', 'xml.sax.handler', 'ic',
'Crypto.PublicKey', 'IPython']
'Crypto.PublicKey', 'IPython', 'gst.interfaces']
if os.name == 'nt':
import locale
......
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