GNOME Bugzilla – Bug 523393
Linking a tee element to multiple audio convert elements causes exponential caps growth on the tee
Last modified: 2012-06-27 18:22:16 UTC
Please describe the problem: Linking a tee element to multiple audio convert elements causes exponential Caps growth on the tee which causes slow/hung pipeline construction. If 1-3 audio convert elements are linked to the tee, caps appear relatively normal. The more elements that are linked to the tee, the larger the caps grows. If 13 audioconvert elements are linked in the pipeline fails (killed after a couple hours) to construct. Steps to reproduce: Run "python tee_test.py <video file> <number of elements to connect to the tee>" for example "python tee_test.py foo.avi 13" http://www.ekstrom.org/~jce/tee_test.py Actual results: The pipeline hangs in creation and the caps of the tee element appear to grow exponentially. A smaller number of elements connected to the tee slows pipeline creation down, but exhibits the problem of tee caps growth. Expected results: The caps to be an aggregate at a minimum, not exponential growth of the caps on the tee element. Does this happen every time? yes Other information: # tee_test.py - python code to reproduce the bug import gobject gobject.threads_init() import pygst pygst.require('0.10') import gst, sys, os def Main(filename, forks): test = Test(filename, int(forks)) return 0 class Test(object): def __init__(self, filename, forks): self.pipeline = gst.Pipeline() source = gst.element_factory_make('filesrc') source.set_property('location', filename) decode = gst.element_factory_make('decodebin') self.vidsink = gst.element_factory_make('fakesink') self.tee = gst.element_factory_make('tee') self.pipeline.add(source, decode, self.vidsink, self.tee) source.link(decode) for i in range(forks): audioconvert = gst.element_factory_make('audioconvert') encoder = gst.element_factory_make('vorbisenc') sink = gst.element_factory_make('fakesink') self.pipeline.add(audioconvert, encoder, sink) self.tee.link(audioconvert) audioconvert.link(encoder) encoder.link(sink) decode.connect('new-decoded-pad', self.NewDecodedPad) decode.connect('no-more-pads', self.DecodeBinDone) self.pipeline.set_state(gst.STATE_PLAYING) gobject.MainLoop().run() def NewDecodedPad(self, element, pad, arg): print 'DECODE NEW PAD', element, arg, pad caps = pad.get_caps() if caps[0].get_name().startswith('audio/'): print 'linking to tee' element.link(self.tee) else: element.link(self.vidsink) def DecodeBinDone(self, element): DisplayBin(self.pipeline) def DisplayCaps(caps, level): for cap in caps: print "%s%s"%(level,cap.to_string()[:180]) def DisplayPad(pad, level): peerpad = pad.get_peer() peerparentname = "" peername = "" if peerpad: peername = peerpad.get_name() peerparentname = peerpad.get_parent().get_name() else: print "++++++++++++ ERROR NO PAD ++++++++++++++" print "%s%s: %s %d, A:%d, B:%d, L:%d<==> %s:%s" % (level, type(pad), pad.get_name(), len(pad.get_caps()), pad.is_active(), pad.is_blocked(), pad.is_linked(), peerparentname, peername) if pad.is_blocked(): print "****** BLOCKED ******" DisplayCaps(pad.get_caps(), " %s"%(level)) def DisplayElement(element, level): print "%s%s: %s" % (level, type(element), element.get_name()) for pad in element.pads(): DisplayPad(pad, "%s "%level) def DisplayBin(bin, level="", parents=True): if parents: while bin.get_parent(): bin = bin.get_parent() print "%s%s: %s" % (level, type(bin), bin.get_name()) for pad in bin.pads(): DisplayPad(pad, "%s "%level) for element in bin.elements(): if isinstance(element, gst.Bin): DisplayBin(element, "%s "%level, False) elif isinstance(element, gst.Element): DisplayElement(element, "%s "%level) else: print "ERROR" if __name__ == '__main__': try: sys.exit(Main(*sys.argv[1:])) except TypeError: print 'Usage: gsttest.py <file> <forks>'
If uncommenting gst_caps_do_simplify() in gstbasetransform.c::gst_base_transform_transform_caps() fixes it, then gst_caps_do_simplify() should be improved to actually keep the order somehow so that we can use it here.
Created attachment 120792 [details] Test case Test case for exponential caps growth
Dejan, could you try what I suggested in comment #1?
Hey folks, this bug is set to NEEDINFO for quite some time now. Dejan, could you please try what is suggested in comment #1? Stefan, given that there's no reaction, would you mind to actually close this bug as INCOMPLETE?
Lets keep it open. I need to look into that someday. I was hoping to get some support from Dejan.
Well. Keeping open and keeping visible translates to NEW, thus resetting :)
Oh, look, had something to work on at that moment and actually managed to forget about this bug for 2 years regardless to all updates. :) Stefan should I expect an enormous amount of caps printed? If so, then yes for 10 forks it takes about 50s to negotiate.
Dejan, I was wondering if you could get the timings, with and without then chage in core. If not, I'll retry this myself in hopefully no too far away future.
Given how little has happened here in the last four years, let's close this as OBSOLETE. The caps explosion thing should be fixed in 0.11.