Moved things to JingleRTPContent, start pipeline earlier

Some methods of JingleVoIPContent have been moved to JingleRTPContent, in prevision of a video content class.

The pipeline now starts in setupStream, and the stream's direction is changed when the stream is ready.
This commit is contained in:
Thibaut GIRKA 2009-09-16 13:55:54 +02:00
parent 32ad59aa42
commit af44ee0840
1 changed files with 33 additions and 28 deletions

View File

@ -13,7 +13,7 @@
''' Handles the jingle signalling protocol. '''
#TODO:
# * things in XEP 0166, includign:
# * things in XEP 0166, including:
# - 'senders' attribute of 'content' element
# - security preconditions
# * actions:
@ -24,13 +24,19 @@
# * sid/content related:
# - tiebreaking
# - if there already is a session, use it
# * things in XEP 0176, including:
# - http://xmpp.org/extensions/xep-0176.html#protocol-restarts
# - http://xmpp.org/extensions/xep-0176.html#fallback
# * XEP 0177 (raw udp)
# * UI:
# - hang up button!
# - make state and codec informations available to the user
# * config:
# - codecs
# - STUN
# * figure out why it doesn't work with pidgin, and why it doesn't work well with psi
# * DONE: figure out why it doesn't work with pidgin:
# That's a bug in pidgin: http://xmpp.org/extensions/xep-0176.html#protocol-checks
# * destroy sessions when user is unavailable, see handle_event_notify?
# * timeout
# * video
@ -460,6 +466,7 @@ class JingleContent(object):
self.negotiated = False # is this content already negotiated?
self.candidates = [] # Local transport candidates
self.senders = 'both' #FIXME
self.allow_sending = True # Used for stream direction, attribute 'senders'
self.callbacks = {
@ -581,13 +588,16 @@ class JingleContent(object):
class JingleRTPContent(JingleContent):
def __init__(self, session, node=None):
def __init__(self, session, media, node=None):
JingleContent.__init__(self, session, node)
self.media = media
self.got_codecs = False
self.callbacks['content-accept'] += [self.__getRemoteCodecsCB]
self.callbacks['session-accept'] += [self.__getRemoteCodecsCB]
self.callbacks['session-initiate'] += [self.__getRemoteCodecsCB]
self.callbacks['session-terminate'] += [self.__stop]
self.callbacks['session-terminate-sent'] += [self.__stop]
def setupStream(self):
# pipeline and bus
@ -602,6 +612,10 @@ class JingleRTPContent(JingleContent):
self.pipeline.add(self.conference)
self.funnel = None
def _fillContent(self, content):
content.addChild(xmpp.NS_JINGLE_RTP+' description', attrs={'media': self.media},
payload=self.iterCodecs())
def _on_gst_message(self, bus, message):
if message.type == gst.MESSAGE_ELEMENT:
name = message.structure.get_name()
@ -622,15 +636,18 @@ class JingleRTPContent(JingleContent):
elif name == 'farsight-component-state-changed':
state = message.structure['state']
print message.structure['component'], state
if state==farsight.STREAM_STATE_READY:
if state==farsight.STREAM_STATE_CONNECTED:
self.negotiated = True
self.pipeline.set_state(gst.STATE_PLAYING)
#TODO: farsight.DIRECTION_BOTH only if senders='both'
self.p2pstream.set_property('direction', farsight.DIRECTION_BOTH)
#if not self.session.weinitiate: #FIXME: one more FIXME...
# self.session.sendContentAccept(self.__content((xmpp.Node('description', payload=self.iterCodecs()),)))
elif name == 'farsight-error':
print 'Farsight error #%d!' % message.structure['error-no']
print 'Message: %s' % message.structure['error-msg']
print 'Debug: %s' % message.structure['debug-msg']
else:
print name
def __getRemoteCodecsCB(self, stanza, content, error, action):
''' Get peer codecs from what we get from peer. '''
@ -666,24 +683,23 @@ class JingleRTPContent(JingleContent):
else: p = ()
yield xmpp.Node('payload-type', a, p)
def __stop(self, *things):
self.pipeline.set_state(gst.STATE_NULL)
def __del__(self):
self.__stop()
class JingleVoIP(JingleRTPContent):
''' Jingle VoIP sessions consist of audio content transported
over an ICE UDP protocol. '''
def __init__(self, session, node=None):
JingleRTPContent.__init__(self, session, node)
self.got_codecs = False
JingleRTPContent.__init__(self, session, 'audio', node)
self.callbacks['session-accept'] += [self.__startMic]
self.callbacks['session-terminate'] += [self.__stop]
self.callbacks['session-accept-sent'] += [self.__startMic]
self.callbacks['session-terminate-sent'] += [self.__stop]
self.got_codecs = False
self.setupStream()
def _fillContent(self, content):
content.addChild(xmpp.NS_JINGLE_RTP+' description', attrs={'media': 'audio'},
payload=self.iterCodecs())
''' Things to control the gstreamer's pipeline '''
def setupStream(self):
@ -705,8 +721,7 @@ class JingleVoIP(JingleRTPContent):
farsight.MEDIA_TYPE_AUDIO, 16000)]
self.p2psession.set_codec_preferences(codecs)
#TODO: farsight.DIRECTION_BOTH only if senders='both'
self.p2pstream = self.p2psession.new_stream(participant, farsight.DIRECTION_BOTH,
self.p2pstream = self.p2psession.new_stream(participant, farsight.DIRECTION_NONE,
'nice', params)
# the local parts
@ -724,7 +739,7 @@ class JingleVoIP(JingleRTPContent):
self.pipeline.add(self.src_mic)
self.mic_volume = gst.element_factory_make('volume')
self.mic_volume.set_property('volume', 0)
self.mic_volume.set_property('volume', 1)
self.pipeline.add(self.mic_volume)
# link gst elements
@ -743,17 +758,7 @@ class JingleVoIP(JingleRTPContent):
self.p2pstream.connect('src-pad-added', src_pad_added)
# The following is needed for farsight to process ICE requests:
self.conference.set_state(gst.STATE_PLAYING)
def __startMic(self, *things):
self.mic_volume.set_property('volume', 1)
def __stop(self, *things):
self.conference.set_state(gst.STATE_NULL)
self.pipeline.set_state(gst.STATE_NULL)
def __del__(self):
self.__stop()
self.pipeline.set_state(gst.STATE_PLAYING)
class ConnectionJingle(object):