From 625c4e2d80f02ed54eb8bfd2ff3cde41da06f9da Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Wed, 23 Jun 2010 16:45:19 +0200 Subject: [PATCH] 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 --- docs/gst/gstreamer-sections.txt | 5 ++++ gst/gst.c | 2 ++ gst/gstpad.c | 60 ++++++++++++++++++++++++++++++++--------- gst/gstpad.h | 30 +++++++++++++++++++++ win32/common/libgstreamer.def | 2 ++ 5 files changed, 87 insertions(+), 12 deletions(-) diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index f1d3cb9..076a567 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -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 diff --git a/gst/gst.c b/gst/gst.c index e0cee3b..18d346d 100644 --- a/gst/gst.c +++ b/gst/gst.c @@ -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 ())); diff --git a/gst/gstpad.c b/gst/gstpad.c index 90c8577..efb1abe 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -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; - srccaps = gst_pad_get_caps_unlocked (src); - sinkcaps = gst_pad_get_caps_unlocked (sink); + 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) { diff --git a/gst/gstpad.h b/gst/gstpad.h index e953322..b30c300 100644 --- a/gst/gstpad.h +++ b/gst/gstpad.h @@ -178,6 +178,35 @@ 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 * @GST_ACTIVATE_PUSH: Pad handles dataflow in downstream push mode @@ -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); diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def index 91ac1d8..4ccbd3e 100644 --- a/win32/common/libgstreamer.def +++ b/win32/common/libgstreamer.def @@ -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 -- 2.7.4