diff --git a/src/common/jingle_rtp.py b/src/common/jingle_rtp.py index a1a906e3e..e64c175c0 100644 --- a/src/common/jingle_rtp.py +++ b/src/common/jingle_rtp.py @@ -20,19 +20,11 @@ import gobject import xmpp import farsight, gst +import gajim + from jingle_transport import JingleTransportICEUDP from jingle_content import contents, JingleContent -# TODO: Will that be even used? -def get_first_gst_element(elements): - """ - Return, if it exists, the first available element of the list - """ - for name in elements: - factory = gst.element_factory_find(name) - if factory: - return factory.create() - class JingleRTPContent(JingleContent): def __init__(self, session, media, transport=None): @@ -260,25 +252,25 @@ class JingleAudio(JingleRTPContent): self.p2psession.set_codec_preferences(codecs) # the local parts - # TODO: use gconfaudiosink? - # sink = get_first_gst_element(['alsasink', 'osssink', 'autoaudiosink']) - self.sink = gst.element_factory_make('alsasink') - self.sink.set_property('sync', False) - #sink.set_property('latency-time', 20000) - #sink.set_property('buffer-time', 80000) + try: + self.sink = gst.parse_bin_from_description(gajim.config.get('audio_output_device'), True) + except: + self.session.connection.dispatch('ERROR', (_("Audio configuration error"), + _("Couldn't setup audio output. Check your audio configuration."))) - # TODO: use gconfaudiosrc? - src_mic = gst.element_factory_make('alsasrc') - src_mic.set_property('blocksize', 320) + try: + src_bin = gst.parse_bin_from_description(gajim.config.get('audio_input_device'), True) + except: + self.session.connection.dispatch('ERROR', (_("Audio configuration error"), + _("Couldn't setup audio input. Check your audio configuration."))) - self.mic_volume = gst.element_factory_make('volume') + self.mic_volume = src_bin.get_by_name('gajim_vol') self.mic_volume.set_property('volume', 1) # link gst elements - self.pipeline.add(self.sink, src_mic, self.mic_volume) - src_mic.link(self.mic_volume) + self.pipeline.add(self.sink, src_bin) - self.mic_volume.get_pad('src').link(self.p2psession.get_property( + src_bin.get_pad('src').link(self.p2psession.get_property( 'sink-pad')) self.p2pstream.connect('src-pad-added', self._on_src_pad_added) @@ -296,21 +288,27 @@ class JingleVideo(JingleRTPContent): # sometimes, one window won't show up, # sometimes it'll freeze... JingleRTPContent.setup_stream(self) + # the local parts - src_vid = gst.element_factory_make('videotestsrc') - src_vid.set_property('is-live', True) - videoscale = gst.element_factory_make('videoscale') + try: + src_bin = gst.parse_bin_from_description(gajim.config.get('video_input_device'), True) + except: + self.session.connection.dispatch('ERROR', (_("Video configuration error"), + _("Couldn't setup video input. Check your video configuration."))) caps = gst.element_factory_make('capsfilter') caps.set_property('caps', gst.caps_from_string('video/x-raw-yuv, width=320, height=240')) - colorspace = gst.element_factory_make('ffmpegcolorspace') - self.pipeline.add(src_vid, videoscale, caps, colorspace) - gst.element_link_many(src_vid, videoscale, caps, colorspace) + self.pipeline.add(src_bin, caps) + src_bin.link(caps) - self.sink = gst.element_factory_make('xvimagesink') + try: + self.sink = gst.parse_bin_from_description(gajim.config.get('video_output_device'), True) + except: + self.session.connection.dispatch('ERROR', (_("Video configuration error"), + _("Couldn't setup video output. Check your video configuration."))) self.pipeline.add(self.sink) - colorspace.get_pad('src').link(self.p2psession.get_property('sink-pad')) + caps.get_pad('src').link(self.p2psession.get_property('sink-pad')) self.p2pstream.connect('src-pad-added', self._on_src_pad_added) # The following is needed for farsight to process ICE requests: diff --git a/src/common/multimedia_helpers.py b/src/common/multimedia_helpers.py new file mode 100644 index 000000000..59d8b635f --- /dev/null +++ b/src/common/multimedia_helpers.py @@ -0,0 +1,103 @@ +## +## Copyright (C) 2009 Thibaut GIRKA +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published +## by the Free Software Foundation; version 2 only. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +import gst + + +class DeviceManager(object): + def __init__(self): + self.devices = {} + + def detect(self): + self.devices = {} + + def get_devices(self): + if not self.devices: + self.detect() + return self.devices + + def detect_element(self, name, text, pipe='%s'): + try: + element = gst.element_factory_make(name, '%spresencetest' % name) + if isinstance(element, gst.interfaces.PropertyProbe): + element.set_state(gst.STATE_READY) + devices = element.probe_get_values_name('device') + if devices: + self.devices[text % _(' Default device')] = pipe % name + for device in devices: + element.set_property('device', device) + device_name = element.get_property('device-name') + self.devices[text % device_name] = pipe % '%s device=%s' % (name, device) + element.set_state(gst.STATE_NULL) + else: + self.devices[text] = pipe % name + except gst.ElementNotFoundError: + print 'element \'%s\' not found' % name + + +class AudioInputManager(DeviceManager): + def detect(self): + self.devices = {} + # Test src + self.detect_element('audiotestsrc', _('Audio test'), + '%s is-live=true name=gajim_vol') + # Auto src + self.detect_element('autoaudiosrc', _('Autodetect'), + '%s ! volume name=gajim_vol') + # Alsa src + self.detect_element('alsasrc', _('ALSA: %s'), + '%s ! volume name=gajim_vol') + + +class AudioOutputManager(DeviceManager): + def detect(self): + self.devices = {} + # Fake sink + self.detect_element('fakesink', _('Fake audio output')) + # Auto sink + self.detect_element('autoaudiosink', _('Autodetect')) + # Alsa sink + self.detect_element('alsasink', _('ALSA: %s'), + '%s sync=false') + + +class VideoInputManager(DeviceManager): + def detect(self): + self.devices = {} + # Test src + self.detect_element('videotestsrc', _('Video test'), + '%s is-live=true') + # Auto src + self.detect_element('autovideosrc', _('Autodetect'), + '%s ! videoscale ! ffmpegcolorspace') + # V4L2 src ; TODO: Figure out why it doesn't work + self.detect_element('v4l2src', _('V4L2: %s'), + '%s ! videoscale ! ffmpegcolorspace') + # Funny things, just to test... + # self.devices['GOOM'] = 'audiotestsrc ! goom' + # self.devices['screen'] = 'ximagesrc' + + +class VideoOutputManager(DeviceManager): + def detect(self): + self.devices = {} + # Fake video output + self.detect_element('fakesink', _('Fake audio output')) + # Auto sink + self.detect_element('autovideosink', _('Autodetect')) + # xvimage sink + self.detect_element('xvimagesink', _('X Window System (X11/XShm/Xv): %s')) + # ximagesink + self.detect_element('ximagesink', _('X Window System (without Xv)')) + + diff --git a/src/config.py b/src/config.py index 841273204..2ff9ff73b 100644 --- a/src/config.py +++ b/src/config.py @@ -59,6 +59,8 @@ from common.zeroconf import connection_zeroconf from common import dataforms from common import GnuPG +from common.multimedia_helpers import AudioInputManager, AudioOutputManager, VideoInputManager, VideoOutputManager + from common.exceptions import GajimGeneralException #---------- PreferencesWindow class -------------# @@ -429,10 +431,10 @@ class PreferencesWindow: if gajim.config.get(opt_name + '_device') == value: combobox.set_active(index) - create_av_combobox('audio_input', {'test': 'test'}) - create_av_combobox('audio_output', {'test': 'test'}) - create_av_combobox('video_input', {'test': 'test'}) - create_av_combobox('video_output', {'test': 'test'}) + 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_output', VideoOutputManager().get_devices()) ### Advanced tab ### # open links with if os.name == 'nt':