Jingle: farsight testing program
This commit is contained in:
		
							parent
							
								
									0a9c7f67ec
								
							
						
					
					
						commit
						c2c8efe2cc
					
				
					 1 changed files with 281 additions and 0 deletions
				
			
		
							
								
								
									
										281
									
								
								src/common/farsight/test-jingle.py
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										281
									
								
								src/common/farsight/test-jingle.py
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,281 @@
 | 
			
		|||
#!/usr/bin/python
 | 
			
		||||
 | 
			
		||||
import sys, dl, gst, gobject
 | 
			
		||||
sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_GLOBAL)
 | 
			
		||||
import farsight
 | 
			
		||||
from socket import *
 | 
			
		||||
 | 
			
		||||
TYPE_CANDIDATE=0
 | 
			
		||||
TYPE_CODEC=1
 | 
			
		||||
TYPE_READY_BYTE=2
 | 
			
		||||
 | 
			
		||||
MODE_DUPLEX=0
 | 
			
		||||
MODE_AUDIO=1
 | 
			
		||||
MODE_VIDEO=2
 | 
			
		||||
 | 
			
		||||
send_sock = 0
 | 
			
		||||
recv_sock = 0
 | 
			
		||||
serv_addr = None
 | 
			
		||||
audio_stream = None
 | 
			
		||||
video_stream = None
 | 
			
		||||
 | 
			
		||||
def stream_error(stream, error, debug):
 | 
			
		||||
	print "stream_error: stream=%r error=%s" % (stream, error)
 | 
			
		||||
 | 
			
		||||
def session_error(session, error, debug):
 | 
			
		||||
	print "session_error: session=%r error=%s" % (session, error)
 | 
			
		||||
 | 
			
		||||
def new_active_candidate_pair(stream, native, remote):
 | 
			
		||||
	print "new_active_candidate_pair: native %s, remote %s" % (native, remote)
 | 
			
		||||
	send_codecs(stream.get_local_codecs())
 | 
			
		||||
 | 
			
		||||
def codec_changed(stream, codec_id):
 | 
			
		||||
	print "codec_changed: codec_id=%d, stream=%r" % (codec_id, stream)
 | 
			
		||||
 | 
			
		||||
def native_candidates_prepared(stream):
 | 
			
		||||
	print "native_candidates_prepared: stream=%r" % stream
 | 
			
		||||
	for info in stream.get_native_candidate_list():
 | 
			
		||||
		print "Local transport candidate: %s %d %s %s %s %d pref %f" % (
 | 
			
		||||
			info['candidate_id'], info['component'],
 | 
			
		||||
			(info['proto']==farsight.NETWORK_PROTOCOL_TCP) and "TCP" or "UDP",
 | 
			
		||||
			info['proto_subtype'], info['ip'], info['port'], info['preference']);
 | 
			
		||||
 | 
			
		||||
def show_element(e):
 | 
			
		||||
	print 'element: ...'
 | 
			
		||||
 | 
			
		||||
def state_changed(stream, state, dir):
 | 
			
		||||
	if state==farsight.STREAM_STATE_DISCONNECTED:
 | 
			
		||||
		print "state_changed: disconnected"
 | 
			
		||||
	elif state==farsight.STREAM_STATE_CONNECTING:
 | 
			
		||||
		print "state_changed: connecting"
 | 
			
		||||
	elif state==farsight.STREAM_STATE_CONNECTED:
 | 
			
		||||
		print "state_changed: connectied"
 | 
			
		||||
		print "WW: stream.signal_native_candidates_prepared()"
 | 
			
		||||
		print "WW: stream.start()"
 | 
			
		||||
		exit()
 | 
			
		||||
		stream.signal_native_candidates_prepared()
 | 
			
		||||
		stream.start()
 | 
			
		||||
 | 
			
		||||
def setup_send(host, port):
 | 
			
		||||
	global send_sock, serv_addr
 | 
			
		||||
	send_sock = socket(AF_INET, SOCK_DGRAM)
 | 
			
		||||
	rx_addr = gethostbyname(host)
 | 
			
		||||
	serv_addr=(rx_addr, port)
 | 
			
		||||
 | 
			
		||||
def setup_recv(port):
 | 
			
		||||
	global recv_sock
 | 
			
		||||
	sock = socket(AF_INET, SOCK_DGRAM);
 | 
			
		||||
	sock.bind(('0.0.0.0', port))
 | 
			
		||||
	print "setup_recv: %r(%d)" % (sock, sock.fileno())
 | 
			
		||||
	recv_sock = sock
 | 
			
		||||
	return sock
 | 
			
		||||
 | 
			
		||||
def send_codecs(codecs):
 | 
			
		||||
	global send_sock, serv_addr
 | 
			
		||||
	for codec in codecs:
 | 
			
		||||
		print "Sending codec"
 | 
			
		||||
		print codec
 | 
			
		||||
		if 'channels' not in codec: codec['channels']=1
 | 
			
		||||
		s="%d %d %s %d %d %d " % (TYPE_CODEC, codec['media_type'],
 | 
			
		||||
			codec['encoding_name'], codec['id'], codec['clock_rate'],
 | 
			
		||||
			codec['channels'])
 | 
			
		||||
		send_sock.sendto(s, serv_addr)
 | 
			
		||||
	s="%d %d %s %d %d %d " % (TYPE_CODEC, codec['media_type'], 'LAST', 0, 0, 0)
 | 
			
		||||
	print "Sending end of list packet"
 | 
			
		||||
	send_sock.sendto(s, serv_addr)
 | 
			
		||||
 | 
			
		||||
def send_ready_byte():
 | 
			
		||||
	global send_sock, serv_addr
 | 
			
		||||
	send_sock.sendto('%d ' % TYPE_READY_BYTE, serv_addr)
 | 
			
		||||
	print "Sending ready byte"
 | 
			
		||||
 | 
			
		||||
def do_handshake(sockfd):
 | 
			
		||||
	global send_sock
 | 
			
		||||
	send_ready_byte()
 | 
			
		||||
	print "Waiting for ready byte"
 | 
			
		||||
	buf, recv_addr=recv_sock.recvfrom(1500)
 | 
			
		||||
	print "got message!"
 | 
			
		||||
	if int(buf.split(' ')[0]) == TYPE_READY_BYTE:
 | 
			
		||||
		send_ready_byte();
 | 
			
		||||
 | 
			
		||||
def send_candidate(type, trans):
 | 
			
		||||
	global send_sock, serv_addr
 | 
			
		||||
	s="%d %d %s %s %d %s %s" % (TYPE_CANDIDATE,
 | 
			
		||||
		type, trans['candidate_id'], trans['ip'], trans['port'],
 | 
			
		||||
		trans['username'], trans['password'])
 | 
			
		||||
	print "Sending..."
 | 
			
		||||
	send_sock.sendto(s, serv_addr)
 | 
			
		||||
 | 
			
		||||
def new_native_candidate(stream, candidate_id):
 | 
			
		||||
	candidate=stream.get_native_candidate(candidate_id)
 | 
			
		||||
	trans=candidate[0]
 | 
			
		||||
 | 
			
		||||
	print "New native candidate: <id: %s, component: %d, ip: %s port: %d proto: %d, proto_subtype: %s, proto_profile: %s, preference: %f, type: %d, username: %s, password: %s>" % (
 | 
			
		||||
		trans['candidate_id'], trans['component'], trans['ip'], trans['port'], trans['proto'],
 | 
			
		||||
		trans['proto_subtype'], trans['proto_profile'], trans['preference'], trans['type'],
 | 
			
		||||
		trans['username'], trans['password'])
 | 
			
		||||
 | 
			
		||||
	type=stream.get_property("media-type")
 | 
			
		||||
 | 
			
		||||
	send_candidate(type, trans)
 | 
			
		||||
 | 
			
		||||
remote_codecs_audio = []
 | 
			
		||||
remote_codecs_video = []
 | 
			
		||||
def add_remote_codec(stream, pt, encoding_name, media_type, clock_rate, channels):
 | 
			
		||||
	global remote_codecs_audio, remote_codecs_video
 | 
			
		||||
	if encoding_name=="LAST":
 | 
			
		||||
		if media_type==farsight.MEDIA_TYPE_AUDIO:
 | 
			
		||||
			print "WW: set_remote_codecs(remote_codecs_audio), %r" % (remote_codecs_audio,)
 | 
			
		||||
			stream.set_remote_codecs(remote_codecs_audio)
 | 
			
		||||
		else:
 | 
			
		||||
			stream.set_remote_codecs(remote_codecs_video)
 | 
			
		||||
	else:
 | 
			
		||||
		codec={'id': pt, 'encoding_name': encoding_name, 'media_type': media_type,
 | 
			
		||||
			'clock_rate': clock_rate, 'channels': channels}
 | 
			
		||||
		if media_type==farsight.MEDIA_TYPE_AUDIO:
 | 
			
		||||
			remote_codecs_audio.append(codec)
 | 
			
		||||
		elif media_type==farsight.MEDIA_TYPE_VIDEO:
 | 
			
		||||
			remote_codecs_video.append(codec)
 | 
			
		||||
 | 
			
		||||
		for codec in remote_codecs_audio:
 | 
			
		||||
			print "added audio codec: %d: %s/%d found" % (codec['id'], codec['encoding_name'], codec['clock_rate'])
 | 
			
		||||
		for codec in remote_codecs_video:
 | 
			
		||||
			print "added video codec: %d: %s/%d found" % (codec['id'], codec['encoding_name'], codec['clock_rate'])
 | 
			
		||||
 | 
			
		||||
def add_remote_candidate(stream, id, ip, port, username, password):
 | 
			
		||||
	if not stream: return
 | 
			
		||||
 | 
			
		||||
	trans={'candidate_id': id, 'component': 1, 'ip': ip, 'port': port, 'proto': farsight.NETWORK_PROTOCOL_UDP,
 | 
			
		||||
		'proto_subtype': 'RTP', 'proto_profile': 'AVP', 'preference': 1.0,
 | 
			
		||||
		'type': farsight.CANDIDATE_TYPE_LOCAL, 'username': username, 'password': password}
 | 
			
		||||
 | 
			
		||||
	print "WW: add_remote_candidate(%r)" % ([trans],)
 | 
			
		||||
	stream.add_remote_candidate([trans]);
 | 
			
		||||
 | 
			
		||||
def receive_loop(ch, cond, *data):
 | 
			
		||||
	print 'receive_loop called!'
 | 
			
		||||
	global recv_sock, serv_addr, audio_stream, remote_stream
 | 
			
		||||
	print "waiting for msg from %r" % (serv_addr,)
 | 
			
		||||
	buf,a = recv_sock.recvfrom(1500)
 | 
			
		||||
	print "got message! ",buf
 | 
			
		||||
	msg = buf.split(' ')
 | 
			
		||||
	type = int(msg.pop(0))
 | 
			
		||||
	print msg
 | 
			
		||||
	if type==TYPE_CANDIDATE:
 | 
			
		||||
		media_type, id, ip, port, username, password = msg[:6]
 | 
			
		||||
		media_type=int(media_type)
 | 
			
		||||
		port=int(port)
 | 
			
		||||
		print "Received %d %s %s %d %s %s" % (media_type, id, ip, port, username, password)
 | 
			
		||||
		if media_type==farsight.MEDIA_TYPE_AUDIO:
 | 
			
		||||
			add_remote_candidate(audio_stream, id, ip, port, username, password)
 | 
			
		||||
		elif media_type==farsight.MEDIA_TYPE_VIDEO:
 | 
			
		||||
			add_remote_candidate(video_stream, id, ip, port, username, password)
 | 
			
		||||
	elif type==TYPE_CODEC:
 | 
			
		||||
		media_type, encoding_name, pt, clock_rate, channels=msg[:5]
 | 
			
		||||
		media_type=int(media_type)
 | 
			
		||||
		pt=int(pt)
 | 
			
		||||
		clock_rate=int(clock_rate)
 | 
			
		||||
		channels=int(channels)
 | 
			
		||||
 | 
			
		||||
		print "Received %d %s %d %d %d" % (media_type, encoding_name, pt, clock_rate, channels)
 | 
			
		||||
 | 
			
		||||
		if media_type==farsight.MEDIA_TYPE_AUDIO:
 | 
			
		||||
			add_remote_codec(audio_stream, pt, encoding_name, media_type, clock_rate, channels)
 | 
			
		||||
		elif media_type==farsight.MEDIA_TYPE_VIDEO:
 | 
			
		||||
			add_remote_codec(video_stream, pt, encoding_name, media_type, clock_rate, channels)
 | 
			
		||||
	elif type==TYPE_READY_BYTE:
 | 
			
		||||
		print "got ready byte"
 | 
			
		||||
	return True
 | 
			
		||||
 | 
			
		||||
def set_xoverlay(bus, message, xid):
 | 
			
		||||
	print "set_xoverlay: called"
 | 
			
		||||
	if message!=gst.MESSAGE_ELEMENT: return gst.BUS_PASS
 | 
			
		||||
 | 
			
		||||
	if not message.structure.has_name('prepare-xwindow-id'): return gst.BUS_PASS
 | 
			
		||||
 | 
			
		||||
	print "set_xoverlay: setting x overlay window id"
 | 
			
		||||
	message.set_xwindow_id(xid)
 | 
			
		||||
 | 
			
		||||
	return gst.BUS_DROP
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
	global audio_stream, remote_stream
 | 
			
		||||
	if len(sys.argv)<4 or len(sys.argv)>6:
 | 
			
		||||
		print 'usage: %s remoteip remoteport localport [mode] [xid]' % sys.argv[0]
 | 
			
		||||
		return -1
 | 
			
		||||
 | 
			
		||||
	if len(sys.argv)>=5:
 | 
			
		||||
		mode = int(sys.argv[4])
 | 
			
		||||
	else:
 | 
			
		||||
		mode = MODE_DUPLEX
 | 
			
		||||
 | 
			
		||||
	setup_send(sys.argv[1], int(sys.argv[2]))
 | 
			
		||||
	print "Sending to %s %d listening on port %d" % (sys.argv[1], int(sys.argv[2]), int(sys.argv[3]))
 | 
			
		||||
 | 
			
		||||
	recv_chan=setup_recv(int(sys.argv[3]))
 | 
			
		||||
 | 
			
		||||
	do_handshake(recv_chan)
 | 
			
		||||
 | 
			
		||||
	gobject.io_add_watch(recv_chan.fileno(), gobject.IO_IN, receive_loop)
 | 
			
		||||
 | 
			
		||||
	session = setup_rtp_session()
 | 
			
		||||
 | 
			
		||||
	if mode==MODE_AUDIO or mode==MODE_VIDEO:
 | 
			
		||||
		audio_stream = setup_rtp_stream(session, farsight.MEDIA_TYPE_AUDIO)
 | 
			
		||||
	if mode==MODE_VIDEO or mode==MODE_DUPLEX:
 | 
			
		||||
		video_stream = setup_rtp_stream(session, farsight.MEDIA_TYPE_VIDEO)
 | 
			
		||||
 | 
			
		||||
	if audio_stream:
 | 
			
		||||
		audio_stream.set_active_codec(8)
 | 
			
		||||
 | 
			
		||||
		alsasrc = gst.element_factory_make('audiotestsrc', 'src')
 | 
			
		||||
		alsasink= gst.element_factory_make('alsasink', 'alsasink')
 | 
			
		||||
 | 
			
		||||
		alsasink.set_property('sync', False)
 | 
			
		||||
		alsasink.set_property('latency-time', 20000)
 | 
			
		||||
		alsasink.set_property('buffer-time', 80000)
 | 
			
		||||
		alsasrc.set_property('blocksize', 320)
 | 
			
		||||
		#alsasrc.set_property('latency-time', 20000)
 | 
			
		||||
		alsasrc.set_property('is-live', True)
 | 
			
		||||
 | 
			
		||||
		print "WW: set_sink(%r)" % (alsasink,)
 | 
			
		||||
		audio_stream.set_sink(alsasink)
 | 
			
		||||
		print "WW: set_source(%r)" % (alsasrc,)
 | 
			
		||||
		audio_stream.set_source(alsasrc)
 | 
			
		||||
	
 | 
			
		||||
	#if video_stream: assert False
 | 
			
		||||
 | 
			
		||||
	gobject.MainLoop().run()
 | 
			
		||||
	print 'bu!'
 | 
			
		||||
 | 
			
		||||
def setup_rtp_session():
 | 
			
		||||
	session = farsight.farsight_session_factory_make('rtp')
 | 
			
		||||
 | 
			
		||||
	session.connect('error', session_error)
 | 
			
		||||
	return session
 | 
			
		||||
 | 
			
		||||
def setup_rtp_stream(session, type):
 | 
			
		||||
	stream = session.create_stream(type, farsight.STREAM_DIRECTION_BOTH)
 | 
			
		||||
 | 
			
		||||
	stream.set_property('transmitter', 'libjingle')
 | 
			
		||||
 | 
			
		||||
	stream.connect('error', stream_error)
 | 
			
		||||
	stream.connect('new-active-candidate-pair', new_active_candidate_pair)
 | 
			
		||||
	stream.connect('codec-changed', codec_changed)
 | 
			
		||||
	stream.connect('native-candidates-prepared', native_candidates_prepared)
 | 
			
		||||
	stream.connect('state-changed', state_changed)
 | 
			
		||||
	stream.connect('new-native-candidate', new_native_candidate)
 | 
			
		||||
 | 
			
		||||
	possible_codecs = stream.get_local_codecs()
 | 
			
		||||
 | 
			
		||||
	for codec in possible_codecs:
 | 
			
		||||
		print "codec: %d: %s/%d found" % (codec['id'], codec['encoding_name'], codec['clock_rate'])
 | 
			
		||||
	
 | 
			
		||||
	#send_codecs(possible_codecs)
 | 
			
		||||
 | 
			
		||||
	stream.prepare_transports()
 | 
			
		||||
 | 
			
		||||
	return stream
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
main()
 | 
			
		||||
		Loading…
	
	Add table
		
		Reference in a new issue