[gst-devel] Linking pads in 0.9

Benjamin Otte in7y118 at public.uni-hamburg.de
Fri Apr 29 02:47:19 CEST 2005


On Wed, 27 Apr 2005, David Schleef wrote:

> We need to make a collective decision about how pads work while
> linking in 0.9.  Two choices:
>
>  1) Linking succeeds or fails based only on the pad template
>     caps.
>
>  2) Linking succeeds of fails based on the current caps of the
>     pad.
>
I'm very in favour of 1, for a very simple reason:
With choice 2, whether linking ffmpegcolorspace to xvimagesink works can
be dependant on your soundcard driver.

Though I'd go one step further and allow linking of any srcpad to any sink
pad, no matter the caps.
And then I'd provide an easy way to query a link if it is negotiable, like
gst_pad_can_negotiate_link(pad) or something.
And it might be useful to provide convenience linking functions that check
if the link is unnegotiable and if so unlink and return a failure code.


About the autoplugging issue:
An autoplugger needs these things to work:
1) Does the pad already know all possible caps?
   This is important for example in the demuxer case. Consider this:
   filesrc ! wavparse
   Now we can only decide this if wavparse already knows what kind of
   audio is in the wave file (mp3, raw, whatever). In the current get_caps
   situation we don't know, get_caps might return template caps which are
   totally useless.
2) What caps will the pad be able to accept?
   This is just listed for completeness. Obviously you need a way to query
   the caps. Currently get_caps does this just fine.
3) Notification when the caps change
   This is important for the stuff outlined in point 1). If an autoplugger
   sees that the caps of a pad are not known yet, it needs to delay
   linking that pad until they are known. To know when they are known, the
   autoplugger needs some kind of notification callback.

My preferred solution for this is still a property "possible-caps" on a
pad. When set to NULL, the pads aren't known yet, otherwise it's the caps
the pad will accept. Give pads an optional peer_changed_possible_caps
vfunc that does the proxying and you're pretty much set.
Some example code:

void
gst_pad_set_possible_caps (GstPad *pad, const GstCaps *caps)
{
  GstPad *peer;

  /* shortcut to avoid costly operations when plugging identity like
     elements */
  if (gst_caps_equal (pad->possible_caps, caps))
    return;

  if (pad->possible_caps)
    gst_caps_free (pad->possible_caps);

  if (caps)
    pad->possible_caps = gst_caps_copy (caps);
  else
   pad->possible_caps = NULL;

  g_object_notify (pad, "possible-caps");
  peer = GST_PAD_PEER (pad);
  if (peer && peer->peer_changed_possible_caps) {
    peer->peer_changed_possible_caps (peer, caps);
  }
}

/* This is an easy proxying example */
/* Note that peercaps may be NULL */
static void
gst_identity_peer_changed_caps (GstPad *pad, const GstCaps *peercaps)
{
  GstIdentity *identity = GST_IDENTITY (gst_pad_get_parentr (pad));
  GstPad *otherpad = (pad == identity->srcpad ? identity->sinkpad :
                      identity->srcpad);

  gst_pad_set_possible_caps (otherpad, peercaps);
}

What else does this buy you:
- No need to ever call gst_pad_negotiate again. The core will negotiate
  links itself when both sides have set possible caps.
- Since we don't need to call negotiate, negotiation can be fully
  abstracted away inside the core.
- get_caps is not an expensive operation anymore. Since the possible caps
  are cached by the pad, it's just a simple lookup.
- by doing the gst_caps_is_equal comparison in set_possible_caps, you
  won't have to traverse lots of elements in long pipelines with simple
  caps when plugging an identity for example.
- by calling the peer_changed_possible_caps functions on linking and
  unlinking, you even get live updates to possible caps when modifying a
  pipeline.
- not only autopluggers, but all kinds of applications (for visualizing,
  debugging nego failures, simple autoplugging [like "do I need a
  colorspace here?"] or whatever) can monitor the caps.


That got longer than I thought,
Benjamin





More information about the gstreamer-devel mailing list