After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 523393 - Linking a tee element to multiple audio convert elements causes exponential caps growth on the tee
Linking a tee element to multiple audio convert elements causes exponential c...
Status: RESOLVED OBSOLETE
Product: GStreamer
Classification: Platform
Component: gstreamer (core)
0.10.17
Other All
: Normal critical
: NONE
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2008-03-19 16:35 UTC by Joey Ekstrom
Modified: 2012-06-27 18:22 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Test case (8.77 KB, text/x-csrc)
2008-10-17 15:27 UTC, Dejan Sakelšak
Details

Description Joey Ekstrom 2008-03-19 16:35:07 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>'
Comment 1 Stefan Sauer (gstreamer, gtkdoc dev) 2008-10-17 12:03:30 UTC
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.
Comment 2 Dejan Sakelšak 2008-10-17 15:27:34 UTC
Created attachment 120792 [details]
Test case

Test case for exponential caps growth
Comment 3 Stefan Sauer (gstreamer, gtkdoc dev) 2009-01-30 10:35:34 UTC
Dejan, could you try what I suggested in comment #1?
Comment 4 Tobias Mueller 2009-06-14 21:50:18 UTC
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?
Comment 5 Stefan Sauer (gstreamer, gtkdoc dev) 2009-06-16 18:49:50 UTC
Lets keep it open. I need to look into that someday. I was hoping to get some support from Dejan.
Comment 6 Tobias Mueller 2010-04-04 16:48:07 UTC
Well. Keeping open and keeping visible translates to NEW, thus resetting :)
Comment 7 Dejan Sakelšak 2010-10-21 12:54:08 UTC
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.
Comment 8 Stefan Sauer (gstreamer, gtkdoc dev) 2010-10-22 05:49:33 UTC
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.
Comment 9 Tim-Philipp Müller 2012-06-27 18:22:16 UTC
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.