• Home
  • About
  • Blog Archives
  • Contact Me
  • FAQ
  • The Big 101
Subscribe: Posts | Comments | E-mail

jonobacon@home

Posted on November 3, 2006 - by jono

GStreamer Dynamic Pads, Explained

Desktop Jokosher

(for an intro to GStreamer, see my previous article)

You know, one thing that gets people confused in GStreamer is the idea of Dynamic Pads. Some elements, most notably the decodebin and gnlcomposition only have certain pads at certain times. This is because they figure out what kind of content they are processing, and apply the relevant pads where needed. This is often told to new users, but then they wonder how exactly these dynamic pads are handled.

Here is how it works, using decodebin as an example:

  • When the pipeline is run, the decodebin generates a signal that says a new pad has been added. In the case of decodebin this is the new-decoded-pad signal, in the case of gnlcomposition this is a pad-added signal.
  • You hook this signal up to your own callback, such as OnDecodedPad().
  • The signal passes your callback the pad that was added and some other stuff. You then link this pad to the next element along in the pipeline. So if your pipeline is filesrc ! decodebin ! audioconvert ! alsasink, the pad passed to your OnDecodeBin() method would be linked to the audioconvert.

To outline this, I have written a sample script to show how it works:

#!/usr/bin/python

import pygst
pygst.require("0.10")
import gst
import pygtk
import gtk

class Main:
    def __init__(self):
        self.pipeline = gst.Pipeline("mypipeline")

        self.filesrc = gst.element_factory_make("filesrc", "source")
        self.pipeline.add(self.filesrc)
        self.filesrc.set_property("location", "/home/jono/Desktop/jonobacon-voicesoffreedom.ogg")

        self.decode = gst.element_factory_make("decodebin", "decode")
        self.decode.connect("new-decoded-pad", self.OnDynamicPad)
        self.pipeline.add(self.decode)

        self.filesrc.link(self.decode)

        self.convert = gst.element_factory_make("audioconvert", "convert")
        self.pipeline.add(self.convert)

        self.sink = gst.element_factory_make("alsasink", "sink")
        self.pipeline.add(self.sink)

        self.convert.link(self.sink)

        self.pipeline.set_state(gst.STATE_PLAYING)

    def OnDynamicPad(self, dbin, pad, islast):
        print "OnDynamicPad Called!"
        pad.link(self.convert.get_pad("sink"))


start=Main()
gtk.main()

You can grab the script from here. Hope this helps some of you. :)



This entry was posted on Friday, November 3rd, 2006 at 10:18 am and is filed under Desktop, Jokosher. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

16 Comments

We'd love to hear yours!



  1. Visit My Website

    November 3, 2006

    Permalink

    David Nielsen said:

    In the example pipeline don’t you mean filesrc not filesink… otherwise with my meager understanding you’d have two sinks and no source.. right?

    Reply


  2. Visit My Website

    November 3, 2006

    Permalink

    jono said:

    Fixed! Thanks David. :)

    Reply


  3. Visit My Website

    November 3, 2006

    Permalink

    cbx33 said:

    Dude you more than rock – thank you for your help with this :mrgreen:

    Reply


  4. Visit My Website

    November 3, 2006

    Permalink

    David Nielsen said:

    Not being a big Python fan this strikes me as inconsistent: self.pipeline.add(self.filesrc)

    when everywhere else you use the passed name from the factory_make function I would have though it should be: self.pipeline.add(self.source)

    Reply


  5. Visit My Website

    November 3, 2006

    Permalink

    jono said:

    David – wha?

    Reply


  6. Visit My Website

    November 3, 2006

    Permalink

    David Nielsen said:

    okay, I’ll try slower for your sake Jono:

    shouldn’t: self.filesrc = gst.element_factory_make(“filesrc”, “source”) self.pipeline.add(self.filesrc)

    be: self.filesrc = gst.element_factory_make(“filesrc”, “source”) self.pipeline.add(self.source)

    Reply


  7. Visit My Website

    November 4, 2006

    Permalink

    Jonathan Hitchcock said:

    Insert “not a gstreamer fundi” disclaimer here, but doesn’t your decodebin element want to link to the ‘convert’ element, and not to the ’sink’ element?

    In other words, your callback:

    def OnDynamicPad(self, dbin, pad, islast): print “OnDynamicPad Called!” pad.link(self.convert.get_pad(“sink”))

    Should be, if I’m right: def OnDynamicPad(self, dbin, pad, islast): print “OnDynamicPad Called!” pad.link(self.convert.get_pad(“convert”))

    Not so?

    Still, we get the point – thanks for the explanation!

    Reply


  8. Visit My Website

    November 5, 2006

    Permalink

    David Nielsen said:

    well at least we are all learning from this.. I had never touched GStreamer code before but now I’m getting into it by reading Jono’ examples..

    Reply


  9. Visit My Website

    November 19, 2006

    Permalink

    Kushal Das said:

    while running the above example follwing error is coming:

    python: Python/ceval.c:2531: PyEval_EvalCodeEx: Assertion `tstate != ((void *)0)’ failed. Aborted

    Reply


  10. Visit My Website

    November 22, 2006

    Permalink

    Tristan said:

    David,

    I see where you’re coming from.

    Here, self.filesrc is a GStreamer filesrc element, which is a Python object. This object has various properties, one of which is a “name” field, which in this case is equal to “source”. This name is how GStreamer refers to the element.

    I agree that it’s a bit confusing, that an element can have a (Python) object name that’s different from its GStreamer name; I tend to set them to be the same whenever I create an element, so I don’t get mixed up :)

    Reply


  11. Visit My Website

    June 19, 2007

    Permalink

    Kyle said:

    How would you set up a queue to play many files sequentially or randomly? Would you have a pipeline in your play pipeline or just have a boolean test after it is done playing and if it isn’t the last in the a queue list and then play that file? Thanks for nay response.

    Reply


  12. Visit My Website

    July 14, 2007

    Permalink

    GroteBozeWolf said:

    I would like to create a never stopping stream of data (to send to an icecast server, with shout2send..). In my case, i want to play files, using a playlist. But i don’t understand how to make gstreamer aware of loading the next file, if the other one is ended. I understand i have to change something in the pipeline.

    The pipeline for one file is: filesrc file1.mp3 ! decodebin ! audioconvert ! lame ! etc.

    After file1.mp3 is finished, i have to make filesrc aware to load a new file, or i have to cut filesrc file1 from the pipeline and reconnect anew filesrc element. But how do i do that?

    Reply


  13. Visit My Website

    March 18, 2009

    Permalink

    Christian Schaller said:

    Hi Jono, I am actually using your tutorials to teach myself some basic python/gstreamer hacking. One thing you might want to change in your example is naming your alsasink element ’sink’ as it confused the hell out of me when I then saw ’sink’ again in the pad.link argument.

    Reply


Leave a Reply


Here's your chance to speak.

Click here to cancel reply.

  1. Name (required)

    Mail (required)

    Website

    Message

  • Ad Ad Ad Ad
  • Prepare For Awesome

  • Recent Articles

    • Unwrapping The Community Manager at OSBC in San Francisco
    • System 76 Lemur Review
    • I Never Realized…
    • International Women’s Day
    • Live Announcement Of Ubuntu International Women’s Day Competition Winners!
    • The Grand App Writing Challenge Submissions!
    • This Is Exactly What We Want
    • Ubuntu Opportunistic Developer Week and Python Snippets Day
    • Refreshing The Ubuntu Brand
    • Ubuntu Opportunistic Developer Week Day 3 Kicks Off In An hour
  • Recent Comments

    • Mike Sheldon on Unwrapping The Community Manager at OSBC in San Francisco
    • Diego Castro on Acire 0.3 Released
    • Ras on Refreshing The Ubuntu Brand
    • YokoZar’s Writings » Blog Archive » It’s time to fix the window controls on Refreshing The Ubuntu Brand
    • Ilya Skorik on I Never Realized…
    • Alex (Handy Backup team) on International Women’s Day
    • Ralf on I Never Realized…
    • Ralf on I Never Realized…
    • Andrew on Unwrapping The Community Manager at OSBC in San Francisco
    • Patrick D. on System 76 Lemur Review
  • Flickr Photos

  •  

    November 2006
    M T W T F S S
    « Oct   Dec »
     12345
    6789101112
    13141516171819
    20212223242526
    27282930  
  • jb@h Rockstars This Year

    • ethana2 (23)
    • Digitivity (9)
    • James Duncan (9)
    • Zac (9)
    • w1ngnutz (8)
    • Aaron Toponce (7)
    • Benji (7)
    • Bruno Girin (7)
    • Gerv (7)
    • Brett (6)
© 2008 jonobacon@home - At home with Jono Bacon, Community Manager and Author