GstPad: Add new pad linking method with configurable checks.

To be used for cases where we don't need all checks to be validated.

API: gst_pad_link_full
API: GstPadLinkCheck

https://bugzilla.gnome.org/show_bug.cgi?id=622504
This commit is contained in:
Edward Hervey 2010-06-23 16:45:19 +02:00
parent 7a34c1cd18
commit 625c4e2d80
5 changed files with 87 additions and 12 deletions

View file

@ -1343,6 +1343,8 @@ GstPadFlags
GstPadLinkReturn
GST_PAD_LINK_FAILED
GST_PAD_LINK_SUCCESSFUL
GstPadLinkCheck
GST_PAD_LINK_CHECK_DEFAULT
GstFlowReturn
GstActivateMode
@ -1354,6 +1356,7 @@ gst_pad_get_parent_element
gst_pad_get_pad_template
gst_pad_link
gst_pad_link_full
gst_pad_unlink
gst_pad_is_linked
gst_pad_can_link
@ -1524,6 +1527,7 @@ GST_TYPE_PAD
GST_TYPE_PAD_DIRECTION
GST_TYPE_PAD_FLAGS
GST_TYPE_PAD_LINK_RETURN
GST_TYPE_PAD_LINK_CHECK
GST_TYPE_PAD_PRESENCE
GST_TYPE_FLOW_RETURN
GST_TYPE_ACTIVATE_MODE
@ -1533,6 +1537,7 @@ gst_pad_get_type
gst_pad_direction_get_type
gst_pad_flags_get_type
gst_pad_link_return_get_type
gst_pad_link_check_get_type
gst_pad_presence_get_type
gst_flow_return_get_type
gst_activate_mode_get_type

View file

@ -713,6 +713,7 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
g_type_class_ref (gst_message_type_get_type ());
g_type_class_ref (gst_mini_object_flags_get_type ());
g_type_class_ref (gst_pad_link_return_get_type ());
g_type_class_ref (gst_pad_link_check_get_type ());
g_type_class_ref (gst_flow_return_get_type ());
g_type_class_ref (gst_activate_mode_get_type ());
g_type_class_ref (gst_pad_direction_get_type ());
@ -1079,6 +1080,7 @@ gst_deinit (void)
g_type_class_unref (g_type_class_peek (gst_message_type_get_type ()));
g_type_class_unref (g_type_class_peek (gst_mini_object_flags_get_type ()));
g_type_class_unref (g_type_class_peek (gst_pad_link_return_get_type ()));
g_type_class_unref (g_type_class_peek (gst_pad_link_check_get_type ()));
g_type_class_unref (g_type_class_peek (gst_flow_return_get_type ()));
g_type_class_unref (g_type_class_peek (gst_activate_mode_get_type ()));
g_type_class_unref (g_type_class_peek (gst_pad_direction_get_type ()));

View file

@ -1775,14 +1775,28 @@ gst_pad_is_linked (GstPad * pad)
* pads
*/
static gboolean
gst_pad_link_check_compatible_unlocked (GstPad * src, GstPad * sink)
gst_pad_link_check_compatible_unlocked (GstPad * src, GstPad * sink,
GstPadLinkCheck flags)
{
GstCaps *srccaps;
GstCaps *sinkcaps;
GstCaps *srccaps = NULL;
GstCaps *sinkcaps = NULL;
gboolean compatible = FALSE;
if (!(flags & (GST_PAD_LINK_CHECK_CAPS | GST_PAD_LINK_CHECK_TEMPLATE_CAPS)))
return TRUE;
/* Doing the expensive caps checking takes priority over only checking the template caps */
if (flags & GST_PAD_LINK_CHECK_CAPS) {
srccaps = gst_pad_get_caps_unlocked (src);
sinkcaps = gst_pad_get_caps_unlocked (sink);
} else {
if (GST_PAD_PAD_TEMPLATE (src))
srccaps =
gst_caps_ref (GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (src)));
if (GST_PAD_PAD_TEMPLATE (sink))
sinkcaps =
gst_caps_ref (GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (sink)));
}
GST_CAT_DEBUG (GST_CAT_CAPS, "src caps %" GST_PTR_FORMAT, srccaps);
GST_CAT_DEBUG (GST_CAT_CAPS, "sink caps %" GST_PTR_FORMAT, sinkcaps);
@ -1880,7 +1894,7 @@ wrong_grandparents:
/* call with the two pads unlocked, when this function returns GST_PAD_LINK_OK,
* the two pads will be locked in the srcpad, sinkpad order. */
static GstPadLinkReturn
gst_pad_link_prepare (GstPad * srcpad, GstPad * sinkpad)
gst_pad_link_prepare (GstPad * srcpad, GstPad * sinkpad, GstPadLinkCheck flags)
{
GST_CAT_INFO (GST_CAT_PADS, "trying to link %s:%s and %s:%s",
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
@ -1897,11 +1911,12 @@ gst_pad_link_prepare (GstPad * srcpad, GstPad * sinkpad)
/* check hierarchy, pads can only be linked if the grandparents
* are the same. */
if (!gst_pad_link_check_hierarchy (srcpad, sinkpad))
if ((flags & GST_PAD_LINK_CHECK_HIERARCHY)
&& !gst_pad_link_check_hierarchy (srcpad, sinkpad))
goto wrong_hierarchy;
/* check pad caps for non-empty intersection */
if (!gst_pad_link_check_compatible_unlocked (srcpad, sinkpad))
if (!gst_pad_link_check_compatible_unlocked (srcpad, sinkpad, flags))
goto no_format;
/* FIXME check pad scheduling for non-empty intersection */
@ -1970,7 +1985,7 @@ gst_pad_can_link (GstPad * srcpad, GstPad * sinkpad)
/* gst_pad_link_prepare does everything for us, we only release the locks
* on the pads that it gets us. If this function returns !OK the locks are not
* taken anymore. */
result = gst_pad_link_prepare (srcpad, sinkpad);
result = gst_pad_link_prepare (srcpad, sinkpad, GST_PAD_LINK_CHECK_DEFAULT);
if (result != GST_PAD_LINK_OK)
goto done;
@ -1982,19 +1997,22 @@ done:
}
/**
* gst_pad_link:
* gst_pad_link_full:
* @srcpad: the source #GstPad to link.
* @sinkpad: the sink #GstPad to link.
* @flags: the checks to validate when linking
*
* Links the source pad and the sink pad.
*
* Returns: A result code indicating if the connection worked or
* what went wrong.
*
* Since: 0.10.30
*
* MT Safe.
*/
GstPadLinkReturn
gst_pad_link (GstPad * srcpad, GstPad * sinkpad)
gst_pad_link_full (GstPad * srcpad, GstPad * sinkpad, GstPadLinkCheck flags)
{
GstPadLinkReturn result;
GstElement *parent;
@ -2018,7 +2036,7 @@ gst_pad_link (GstPad * srcpad, GstPad * sinkpad)
}
/* prepare will also lock the two pads */
result = gst_pad_link_prepare (srcpad, sinkpad);
result = gst_pad_link_prepare (srcpad, sinkpad, flags);
if (result != GST_PAD_LINK_OK)
goto done;
@ -2079,6 +2097,24 @@ done:
return result;
}
/**
* gst_pad_link:
* @srcpad: the source #GstPad to link.
* @sinkpad: the sink #GstPad to link.
*
* Links the source pad and the sink pad.
*
* Returns: A result code indicating if the connection worked or
* what went wrong.
*
* MT Safe.
*/
GstPadLinkReturn
gst_pad_link (GstPad * srcpad, GstPad * sinkpad)
{
return gst_pad_link_full (srcpad, sinkpad, GST_PAD_LINK_CHECK_DEFAULT);
}
static void
gst_pad_set_pad_template (GstPad * pad, GstPadTemplate * templ)
{

View file

@ -177,6 +177,35 @@ typedef enum {
G_CONST_RETURN gchar* gst_flow_get_name (GstFlowReturn ret);
GQuark gst_flow_to_quark (GstFlowReturn ret);
/**
* GstPadLinkCheck:
* @GST_PAD_LINK_CHECK_NOTHING: Don't check hierarchy or compatibily
* @GST_PAD_LINK_CHECK_HIERARCHY: Check the pads have same parents/grandparents
* @GST_PAD_LINK_CHECK_TEMPLATE_CAPS: Check if the pads are compatible by using their
* template caps.
* @GST_PAD_LINK_CHECK_CAPS: Check if the pads are compatible by checking their full caps
*
* The amount of check to be done when linking pads.
*
* Since: 0.10.30
*/
typedef enum {
GST_PAD_LINK_CHECK_NOTHING = 1 << 0,
GST_PAD_LINK_CHECK_HIERARCHY = 1 << 1,
GST_PAD_LINK_CHECK_TEMPLATE_CAPS = 1 << 2,
GST_PAD_LINK_CHECK_CAPS = 1 << 3,
} GstPadLinkCheck;
/**
* GST_PAD_LINK_CHECK_DEFAULT:
*
* The default checks done when linking pads (i.e. the ones used by #gst_pad_link.
*
* Since: 0.10.30
*/
#define GST_PAD_LINK_CHECK_DEFAULT (GST_PAD_LINK_CHECK_HIERARCHY | GST_PAD_LINK_CHECK_CAPS)
/**
* GstActivateMode:
* @GST_ACTIVATE_NONE: Pad will not handle dataflow
@ -892,6 +921,7 @@ void gst_pad_set_unlink_function (GstPad *pad, GstPadUnlinkFunction unlink);
gboolean gst_pad_can_link (GstPad *srcpad, GstPad *sinkpad);
GstPadLinkReturn gst_pad_link (GstPad *srcpad, GstPad *sinkpad);
GstPadLinkReturn gst_pad_link_full (GstPad *srcpad, GstPad *sinkpad, GstPadLinkCheck flags);
gboolean gst_pad_unlink (GstPad *srcpad, GstPad *sinkpad);
gboolean gst_pad_is_linked (GstPad *pad);

View file

@ -615,6 +615,8 @@ EXPORTS
gst_pad_iterate_internal_links
gst_pad_iterate_internal_links_default
gst_pad_link
gst_pad_link_check_get_type
gst_pad_link_full
gst_pad_link_return_get_type
gst_pad_load_and_link
gst_pad_new