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