gmyth-stream/server/plugins/media/gstreamer-rtp.py
author renatofilho
Tue Apr 03 16:42:04 2007 +0100 (2007-04-03)
branchtrunk
changeset 484 27e83a8f68d7
permissions -rw-r--r--
[svn r489] moved server implementation to new dir
renatofilho@484
     1
import pygst
renatofilho@484
     2
pygst.require("0.10")
renatofilho@484
     3
import gst
renatofilho@484
     4
import gobject
renatofilho@484
     5
renatofilho@484
     6
class Media:
renatofilho@484
     7
    class StreamData:
renatofilho@484
     8
        stream_count = 0
renatofilho@484
     9
		
renatofilho@484
    10
        def __init__ (self, pipe, abin, vbin):
renatofilho@484
    11
renatofilho@484
    12
	    self.stream_count += 1
renatofilho@484
    13
	    self.Id = self.stream_count
renatofilho@484
    14
	    self.Pipe = pipe
renatofilho@484
    15
	    self.Abin = abin
renatofilho@484
    16
	    self.Vbin = vbin
renatofilho@484
    17
	    self.Loop = gobject.MainLoop()
renatofilho@484
    18
	    self.ACaps = ""
renatofilho@484
    19
	    self.VCaps = ""
renatofilho@484
    20
	    self.Ready = False
renatofilho@484
    21
renatofilho@484
    22
renatofilho@484
    23
    def __init__(self, config):
renatofilho@484
    24
        # set gstreamer basic options
renatofilho@484
    25
        self.config = config
renatofilho@484
    26
        self.pipe = None
renatofilho@484
    27
        self.streams = []
renatofilho@484
    28
renatofilho@484
    29
renatofilho@484
    30
    def setup(self, filename, mux, vcodec, vbitrate,
renatofilho@484
    31
              fps, acodec, abitrate, width, height, port, options):
renatofilho@484
    32
renatofilho@484
    33
        ## Pipelines
renatofilho@484
    34
        self.pipe = gst.Pipeline ()
renatofilho@484
    35
        uri = "file://" + filename
renatofilho@484
    36
        print "Opening Uri:" + uri
renatofilho@484
    37
        src = gst.element_make_from_uri (gst.URI_SRC, uri, "src")
renatofilho@484
    38
        if (src is None):
renatofilho@484
    39
            return None
renatofilho@484
    40
        
renatofilho@484
    41
        decode = gst.element_factory_make ("decodebin", "decode")
renatofilho@484
    42
        if (decode is None):
renatofilho@484
    43
            return None
renatofilho@484
    44
        
renatofilho@484
    45
        
renatofilho@484
    46
        #video encode 
renatofilho@484
    47
        #queue ! videoscale ! video/x-raw-yuv,width=240,height=144 ! videorate ! ffenc_h263p bitrate=256000 me-method=2 ! rtph263ppay ! udpsink  host=224.0.0.1 port=5000
renatofilho@484
    48
        vbin = gst.Bin ()
renatofilho@484
    49
        vqueue = gst.element_factory_make ("queue", "vqueue")
renatofilho@484
    50
        vscale = gst.element_factory_make ("videoscale", "vscale")
renatofilho@484
    51
        vrate = gst.element_factory_make ("videorate", "vrate")
renatofilho@484
    52
        vencode = gst.element_factory_make ("ffenc_mpeg4", "vencode")
renatofilho@484
    53
        vpay = gst.element_factory_make ("rtpmp4vpay", "vpay")
renatofilho@484
    54
        vsink = gst.element_factory_make ("udpsink", "vsink")
renatofilho@484
    55
renatofilho@484
    56
        if (None in [vbin, vqueue, vscale, vrate, vencode, vpay, vsink]):
renatofilho@484
    57
            print "Fail to create video encode elements."
renatofilho@484
    58
            return None
renatofilho@484
    59
renatofilho@484
    60
        vscale_pad = vscale.get_pad("sink")
renatofilho@484
    61
        if (vscale_pad is None):
renatofilho@484
    62
            print "Fail to get vscale sink pad."
renatofilho@484
    63
            return None
renatofilho@484
    64
renatofilho@484
    65
        vscale_caps = gst.caps_from_string ("video/x-raw-yuv, width=%s, height=%s" % (width, height))
renatofilho@484
    66
        if (vscale_caps is None):
renatofilho@484
    67
            print "Fail to create video caps"
renatofilho@484
    68
            return None
renatofilho@484
    69
renatofilho@484
    70
        if (not vscale_pad.set_caps (vscale_caps)):
renatofilho@484
    71
            print "Fail to set video output caps"
renatofilho@484
    72
            return None
renatofilho@484
    73
        
renatofilho@484
    74
        vencode.set_property ("bitrate", 256000)
renatofilho@484
    75
        vencode.set_property ("me-method", 2)
renatofilho@484
    76
        
renatofilho@484
    77
        vsink.set_property ("host", "224.0.0.1")
renatofilho@484
    78
        vsink.set_property ("port", 5000)
renatofilho@484
    79
        
renatofilho@484
    80
        vbin.add (vqueue, vscale, vrate, vencode, vpay, vsink)
renatofilho@484
    81
        if (not gst.element_link_many (vqueue,  vscale, vrate, vencode, vpay, vsink)):
renatofilho@484
    82
            print "Fail to link video elements"
renatofilho@484
    83
            return None
renatofilho@484
    84
        
renatofilho@484
    85
        vbin.add_pad (gst.GhostPad ("sink", vqueue.get_pad ("sink")))
renatofilho@484
    86
renatofilho@484
    87
        #audio encode
renatofilho@484
    88
        #audio/x-raw-int ! queue ! audioconvert ! faac ! rtpmp4gpay !  udpsink name=upd_audio host=224.0.0.1 port=5002
renatofilho@484
    89
        abin = gst.Bin ()
renatofilho@484
    90
        aqueue = gst.element_factory_make ("queue", "vqueue")
renatofilho@484
    91
        aconvert = gst.element_factory_make ("audioconvert", "aconvert")
renatofilho@484
    92
        aencode = gst.element_factory_make ("faac", "aencode")
renatofilho@484
    93
        apay = gst.element_factory_make ("rtpmp4gpay", "apay")
renatofilho@484
    94
        asink = gst.element_factory_make ("udpsink", "asink")
renatofilho@484
    95
renatofilho@484
    96
        if (None in [abin, aqueue, aconvert, aencode, apay, asink]):
renatofilho@484
    97
            print "Fail to create video encode elements."
renatofilho@484
    98
            return None
renatofilho@484
    99
renatofilho@484
   100
        asink.set_property ("host", "224.0.0.1")
renatofilho@484
   101
        asink.set_property ("port", 5002)
renatofilho@484
   102
        
renatofilho@484
   103
        abin.add (aqueue, aconvert, aencode, apay, asink)
renatofilho@484
   104
        if (not gst.element_link_many (aqueue, aconvert, aencode, apay, asink)):
renatofilho@484
   105
            print "Fail to link video elements"
renatofilho@484
   106
            return None
renatofilho@484
   107
        
renatofilho@484
   108
        abin.add_pad (gst.GhostPad ("sink", aqueue.get_pad ("sink")))
renatofilho@484
   109
renatofilho@484
   110
	self.pipe.add (src, decode, abin, vbin)
renatofilho@484
   111
	gst.element_link_many (src, decode)
renatofilho@484
   112
renatofilho@484
   113
	stream_data = self.StreamData (self.pipe, abin, vbin)
renatofilho@484
   114
renatofilho@484
   115
	bus = self.pipe.get_bus()
renatofilho@484
   116
	bus.add_signal_watch()
renatofilho@484
   117
	bus.connect("message", self.__on_bus_message, stream_data)
renatofilho@484
   118
	
renatofilho@484
   119
	decode.connect("new-decoded-pad", self.__on_decode_new_pad, stream_data)
renatofilho@484
   120
	decode.connect("unknown-type", self.__on_decode_unknown_type, stream_data)
renatofilho@484
   121
renatofilho@484
   122
	
renatofilho@484
   123
	self.pipe.set_state (gst.STATE_PAUSED)
renatofilho@484
   124
        print "Running Pipe"
renatofilho@484
   125
	stream_data.Loop.run ()
renatofilho@484
   126
        print "End run"
renatofilho@484
   127
renatofilho@484
   128
	a_caps = stream_data.ACaps
renatofilho@484
   129
	v_caps = stream_data.VCaps
renatofilho@484
   130
	stream_id = stream_data.Id
renatofilho@484
   131
renatofilho@484
   132
        self.streams.append (stream_data)
renatofilho@484
   133
renatofilho@484
   134
    def play(self):
renatofilho@484
   135
renatofilho@484
   136
        print "Trying to play pipeline: %s" % self.pipe
renatofilho@484
   137
        try:
renatofilho@484
   138
            if (self.pipe):
renatofilho@484
   139
                self.pipe.set_state(gst.STATE_PLAYING)
renatofilho@484
   140
        except gobject.GError, e:
renatofilho@484
   141
            print "Error: " + str(e)
renatofilho@484
   142
renatofilho@484
   143
renatofilho@484
   144
    def stop(self):
renatofilho@484
   145
renatofilho@484
   146
        print "Trying to stop pipeline: %s" % self.pipe
renatofilho@484
   147
        try:
renatofilho@484
   148
            if (self.pipeline):
renatofilho@484
   149
                self.pipeline.set_state(gst.STATE_NULL)
renatofilho@484
   150
        except gobject.GError, e:
renatofilho@484
   151
            print "Error: " + str(e)
renatofilho@484
   152
renatofilho@484
   153
    def __on_bus_message (self, bus, message, stream_data):
renatofilho@484
   154
renatofilho@484
   155
        t = message.type
renatofilho@484
   156
        if (t == gst.MESSAGE_STATE_CHANGED):
renatofilho@484
   157
            oldstate = -1
renatofilho@484
   158
            newstate = -1
renatofilho@484
   159
            pending = -1
renatofilho@484
   160
            oldstate, newstate, pending = message.parse_state_changed ()
renatofilho@484
   161
            if ((oldstate == gst.STATE_READY) and \
renatofilho@484
   162
                (newstate == gst.STATE_PAUSED) and \
renatofilho@484
   163
                (pending == gst.STATE_VOID_PENDING) and \
renatofilho@484
   164
                (stream_data.Ready == False)):
renatofilho@484
   165
                state_changed_status, current_state, pending_state = stream_data.Pipe.get_state () 
renatofilho@484
   166
		if ((current_state == gst.STATE_PAUSED) and \
renatofilho@484
   167
                    (pending_state == gst.STATE_VOID_PENDING)):
renatofilho@484
   168
                    print "Pipe paused"
renatofilho@484
   169
                    self.__fill_sink_pads (stream_data)
renatofilho@484
   170
                    stream_data.Loop.quit ()
renatofilho@484
   171
                    stream_data.Ready = True
renatofilho@484
   172
        elif (t == gst.MESSAGE_ERROR):
renatofilho@484
   173
            err, debug = message.parse_error()
renatofilho@484
   174
	    print "Error: %s" % err, debug
renatofilho@484
   175
            stream_data.Loop.quit ()
renatofilho@484
   176
            stream_data.Ready = False
renatofilho@484
   177
renatofilho@484
   178
        return True
renatofilho@484
   179
 
renatofilho@484
   180
renatofilho@484
   181
    def __fill_sink_pads (self, stream_data):
renatofilho@484
   182
        
renatofilho@484
   183
        asink = stream_data.Abin.get_by_name ("asink")
renatofilho@484
   184
        vsink = stream_data.Vbin.get_by_name ("vsink")
renatofilho@484
   185
renatofilho@484
   186
        asink_pad = asink.get_pad ("sink")
renatofilho@484
   187
        stream_data.ACaps = asink_pad.get_negotiated_caps().to_string()
renatofilho@484
   188
        print "ACAPS " + stream_data.ACaps
renatofilho@484
   189
renatofilho@484
   190
        vsink_pad = vsink.get_pad ("sink")
renatofilho@484
   191
        stream_data.VCaps = vsink_pad.get_negotiated_caps().to_string()
renatofilho@484
   192
        print "ACAPS " + stream_data.VCaps
renatofilho@484
   193
 
renatofilho@484
   194
 
renatofilho@484
   195
renatofilho@484
   196
    def __on_decode_unknown_type (self, decode, pad, caps, stream_data):
renatofilho@484
   197
renatofilho@484
   198
        print "Unknown Type"
renatofilho@484
   199
        return None
renatofilho@484
   200
renatofilho@484
   201
    def __on_decode_new_pad (self, decode, pad, arg1, stream_data):
renatofilho@484
   202
        
renatofilho@484
   203
        caps = pad.get_caps().to_string()
renatofilho@484
   204
        print "New pad " + caps
renatofilho@484
   205
	if (caps.rfind ("audio") != -1):
renatofilho@484
   206
            apad = stream_data.Abin.get_pad ("sink")
renatofilho@484
   207
            if (pad.link (apad) != gst.PAD_LINK_OK):
renatofilho@484
   208
                print "Error on link audio pad"
renatofilho@484
   209
                return None
renatofilho@484
   210
        elif (caps.rfind ("video") != -1):
renatofilho@484
   211
            vpad = stream_data.Vbin.get_pad ("sink")
renatofilho@484
   212
            if (pad.link (vpad) != gst.PAD_LINK_OK):
renatofilho@484
   213
                print "Error on link video pad"
renatofilho@484
   214
                return None
renatofilho@484
   215
        else:
renatofilho@484
   216
            print "Invalid caps"
renatofilho@484
   217
renatofilho@484
   218