#!/usr/bin/env python

import sys, os


import gobject
gobject.threads_init()

import gst

import glib
glib.threads_init()

import gtk
gtk.gdk.threads_init()

def player_timer_callback( player ):
    return player.timer()

class GTK_Main:
    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_default_size(800, 600)
        self.window.connect("destroy", gtk.main_quit, "WM destroy")
        vbox = gtk.VBox()
        self.window.add(vbox)
        hbox = gtk.HBox()
        vbox.pack_start(hbox, False)
        self.entry = gtk.Entry()
        hbox.add(self.entry)
        self.button = gtk.Button("Start")
        hbox.pack_start(self.button, False)
        self.button.connect("clicked", self.start_stop)
        self.movie_window = gtk.DrawingArea()
        vbox.add(self.movie_window)

        self.window.show_all()

        self.voutput_bin = gst.Bin( "video-output-bin" )
        queue = gst.element_factory_make( "queue" )
        self.voutput_bin.add( queue )
        self.deinterlace = gst.element_factory_make( "deinterlace" )
        self.deinterlace.set_property( "mode", 1 )
        self.deinterlace.set_property( 'method', 5 )
        self.voutput_bin.add( self.deinterlace )
        queue2 = gst.element_factory_make( "queue" )
        self.voutput_bin.add( queue2 )
        videosink = gst.element_factory_make( "xvimagesink" )
        self.voutput_bin.add( videosink )
        gst.element_link_many( queue, self.deinterlace, queue2, videosink )
        pad = queue.get_pad( "sink" )
        ghostpad = gst.GhostPad( "sink", pad )
        self.voutput_bin.add_pad( ghostpad )

        self.aoutput_bin = gst.Bin( "audio-output-bin" )
        self.alsasink = gst.element_factory_make( "alsasink" )
        self.aoutput_bin.add( self.alsasink )
        pad = self.alsasink.get_pad( "sink" )
        ghostpad = gst.GhostPad( "sink", pad )
        self.aoutput_bin.add_pad( ghostpad )

        self.player = gst.element_factory_make("playbin2", "player")
        self.player.set_property( "video-sink", self.voutput_bin )
        self.player.set_property( "audio-sink", self.aoutput_bin )

        flags = self.player.get_property("flags")
        flags |= 0x100
        self.player.set_property("flags", flags)
   
        bus = self.player.get_bus()
        bus.add_watch(self.on_message)
        bus.set_sync_handler(self.on_sync_message)

        glib.timeout_add_seconds(10, player_timer_callback, self)

        self.play("udp://239.193.88.0:20001")

    def timer(self):
        try:
            play_position = self.player.query_position( gst.FORMAT_TIME, None )[0]
            print 'Pos %fs' % (float( play_position ) / 1000000000.0,)
        except:
            pass

        return True

    def play(self, uri):
        if uri.startswith('/'):
            uri = 'file://' + uri
        self.player.set_property("uri", uri)
        self.player.set_state(gst.STATE_PLAYING)

    def start_stop(self, w):
        if self.button.get_label() == "Start":
            filepath = self.entry.get_text()
            self.button.set_label("Stop")
            self.play(filepath)
        else:
            self.player.set_state(gst.STATE_NULL)
            self.button.set_label("Start")

    def on_message(self, bus, message):
        t = message.type
        src = message.src.get_name()
        if t == gst.MESSAGE_EOS:
            self.player.set_state(gst.STATE_NULL)
            self.button.set_label("Start")
        elif t == gst.MESSAGE_ERROR:
            self.player.set_state(gst.STATE_NULL)
            err, debug = message.parse_error()
            print "Error: %s" % err, debug
            self.button.set_label("Start")
        elif t == gst.MESSAGE_BUFFERING:
            buffer_percent = message.structure['buffer-percent']
            print 'Buffering %d%%' % (buffer_percent,)
        elif t == gst.MESSAGE_QOS:
            src = message.src.get_name()
            frames_processed = message.structure['processed']
            frames_dropped = message.structure['dropped']
            qos_jitter = message.structure['jitter']
            qos_time = message.structure['stream-time']
            print 'QOS[%s] @ %fs rendered/dropped=%d/%d; jitter=%dms' % (src, float( qos_time ) / 1000000000.0, frames_processed, frames_dropped, qos_jitter / 1000000)

        return gst.BUS_PASS

    def on_sync_message(self, bus, message):
        if message.type == gst.MESSAGE_ELEMENT:
            message_name = message.structure.get_name()
            if message_name == "prepare-xwindow-id":
                imagesink = message.src
                gtk.gdk.threads_enter()
                imagesink.set_property("force-aspect-ratio", True)
                imagesink.set_xwindow_id(self.movie_window.window.xid)
                gtk.gdk.threads_leave()

        return gst.BUS_PASS

GTK_Main()
gtk.gdk.threads_init()
gtk.main()
