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