import gst
import gobject
import glib
import sys
def on_message(bus,message):
    if message.type == gst.MESSAGE_EOS:
        print "EOS received"
        pipeline.set_state(gst.STATE_NULL)
        loop.quit()
    elif message.type == gst.MESSAGE_WARNING:
        print "warning"
	print message.parse_warning()[1]
    elif message.type == gst.MESSAGE_ERROR:
        print "error"
	print message.parse_error()[1]
    elif message.type == gst.MESSAGE_STATE_CHANGED:
        print "%s: %s ==> %s"  % (message.src.get_name() ,
                                  message.structure["old-state"].value_name ,
                                  message.structure["new-state"].value_name)
    elif message.type not in [gst.MESSAGE_STREAM_STATUS,
                              gst.MESSAGE_ELEMENT,gst.MESSAGE_TAG, 
                              gst.MESSAGE_NEW_CLOCK]:
        print message.type
        print message
    else:
        print message

def new_pad_removed(element,old_pad,data):
    data.signal_id = element.connect("pad-added",new_pad_added,data)
    element.disconnect(data.remove_signal_id)

    
                    
def new_pad_added(element,new_pad,data):
    try:
        element.link(data.link_element)
        data.remove_signal_id = element.connect("pad-removed",new_pad_removed,data)
        element.disconnect(data.signal_id)
#        print "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1"
#        print "===========Success!=======" ,data.link_element, new_pad,new_pad.get_caps()

    except gst.LinkError, e:
#        print "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1"
#        print "===========Link Error=======" ,e, new_pad,new_pad.get_caps()
        pass

class DelayLinkData:
    pass
def link_many(*args):
    length = len(args)
    try:
        for i in range(length):
            try:
                args[i].link(args[i+1])
            except gst.LinkError:
                data = DelayLinkData()
                data.link_element = args[i+1]
                data.signal_id = args[i].connect("pad-added",new_pad_added,data)
                
    except IndexError:
        pass
        


def make_element(class_name, **kws):
    element = gst.element_factory_make(class_name)
    for k in kws:
        if k=="pass1":
            element.set_property("pass",kws[k])
        else:
            element.set_property(k,kws[k])
    return element

def new_client(sink,fd,data=None):
    print "new client!"
    sink.client_count+=1
    if sink.client_count == 1:
        print "start playing !"
        sink.get_parent().get_by_name("source").set_state(gst.STATE_READY)
        sink.get_parent().get_by_name("source").set_state(gst.STATE_PAUSED)
        sink.get_parent().get_by_name("source").set_state(gst.STATE_PLAYING)

def client_closed(sink,fd,status,data=None):
    print "close client!"
    sink.client_count-=1
    if sink.client_count == 0:
        sink.get_parent().get_by_name("source").set_state(gst.STATE_PAUSED)
        sink.get_parent().get_by_name("source").set_state(gst.STATE_READY)
        sink.get_parent().get_by_name("source").set_state(gst.STATE_NULL)
location = sys.argv[1]
local_port = int(sys.argv[2])
elements1 = [ make_element("rtspsrc",name="source", location=location),
              make_element("decodebin2",name="decode"),
              make_element("queue"),
              make_element("ffmpegcolorspace"),
              make_element("deinterlace2",method=4),
              make_element("ffmpegcolorspace"),
              make_element("videoscale"),
              make_element("capsfilter", caps=gst.caps_from_string("video/x-raw-yuv,width=480")),
              make_element("videorate"), 
              make_element("capsfilter", caps=gst.caps_from_string("video/x-raw-yuv,framewate=30/1")),
              make_element("queue"),
              make_element("x264enc", bitrate=450,  quantizer=21,me="umh",subme=6,ref=3,cabac=0),
#              make_element("x264enc", bitrate=450,cabac=0,pass1="qual"),
#              make_element("capsfilter", caps=gst.caps_from_string("video/x-h264,width=480")),
              make_element("queue"),
              make_element("mpegtsmux",name="muxer"),
              make_element("tcpserversink", name="sink", host="127.0.0.1", port=local_port,timeout=20000000000)]
#              make_element("tcpserversink", name="sink", host="127.0.0.1", port=local_port)]

elements2 = [ make_element("queue",name="audio_sink"),
              make_element("capsfilter", 
                           caps=gst.caps_from_string("audio/x-raw-int;audio/x-raw-float")),
              make_element("audioconvert"),
#              make_element("capsfilter",
#                           caps=gst.caps_from_string("audio/x-raw-int")),
              make_element("audioresample"),
              make_element("capsfilter",
                           caps=gst.caps_from_string("audio/x-raw-int,rate=24000")),
              make_element("audiorate"),
              make_element("faac", bitrate=8000, profile=2),
              make_element("queue",name="audio_source") ]

pipeline = gst.element_factory_make("pipeline")

pipeline.add(*elements1)
pipeline.add(*elements2)
link_many(*elements1)  
link_many(*elements2)
link_many(pipeline.get_by_name("decode"),pipeline.get_by_name("audio_sink"))
link_many(pipeline.get_by_name("audio_source"),pipeline.get_by_name("muxer"))
pipeline.get_bus().add_signal_watch()
pipeline.get_bus().connect("message",on_message)
pipeline.get_by_name("source").set_locked_state(True)
pipeline.get_by_name("sink").client_count = 0;
pipeline.get_by_name("sink").connect("client-added",new_client)
pipeline.get_by_name("sink").connect("client-removed",client_closed)
pipeline.set_state(gst.STATE_PLAYING)
pipeline.get_by_name("source").set_locked_state(False)
print "before get state"
#print pipeline.get_state()
print "After get state"
loop = glib.MainLoop()
loop.run()
