#!/usr/bin/env python import pygst pygst.require('0.10') import gst import sys import gobject gobject.threads_init() class PyTee(gst.Element): __gstdetails__ = ('Tee Plugin', "tee", "Simple Tee Plugin", "Corey O.") _srcpadtemplate = gst.PadTemplate ("src%d", gst.PAD_SRC, gst.PAD_REQUEST, gst.caps_new_any()) _sinkpadtemplate = gst.PadTemplate ("sink", gst.PAD_SINK, gst.PAD_ALWAYS, gst.caps_new_any()) __gsttemplates__ = (_srcpadtemplate, _sinkpadtemplate) def __init__(self): gst.Element.__init__(self) self.src_pad_count = 0 self.src_pads = [] self.sinkpad = gst.Pad(self._sinkpadtemplate) self.add_pad(self.sinkpad) self.sinkpad.set_chain_function(self.chainfunc) self.sinkpad.set_event_function(self.eventfunc) def do_request_new_pad(self, template, name=None): name = "src%d" % self.src_pad_count self.src_pad_count += 1 pad = gst.Pad(template, name) self.src_pads.append(pad) self.add_pad(pad) return pad def do_release_pad(self, pad): self.src_pads.pop(self.src_pads.index(pad)) self.remove_pad(pad) def chainfunc(self, pad, buffer): if len(self.src_pads) == 0: return gst.FLOW_NOT_LINKED else: for pad in self.src_pads: status = pad.push(buffer) if status != gst.FLOW_OK: return status return gst.FLOW_OK def eventfunc(self, pad, event): for srcpad in self.src_pads: status = srcpad.push_event(event) return status gobject.type_register(PyTee) gst.element_register(PyTee, 'pytee') def on_message(bus, message): type = message.type if type == gst.MESSAGE_ERROR: err, debug = message.parse_error() print 'MESSAGE_ERROR =', err print 'MESSAGE_DEBUG =', debug def main(args): # NOTE: the following two pipelines work properly #pipeline = gst.parse_launch ("fakesrc ! pytee name=tee .src0 ! fakesink") #pipeline = gst.parse_launch ("fakesrc ! pytee name=tee .src0 ! fakesink tee.src1 ! fakesink") # this pipeline causes a segfault pipeline = gst.parse_launch ("fakesrc ! pytee name=tee ! fakesink") bus = pipeline.get_bus() bus.add_signal_watch() bus.connect('message', on_message) pipeline.set_state(gst.STATE_PLAYING) try: gobject.MainLoop().run() except KeyboardInterrupt: pipeline.set_state(gst.STATE_NULL) return 0 return -1 if __name__ == '__main__': sys.exit(main(sys.argv))