gstpad: fix gst_pad_can_link()

Move the gst_pad_can_link() implementation from gstutils to gstpad and use
gst_pad_link_prepare() to make it work correctly and also check the caps.

Make the broken implementation in gstutils static.

Small cleanups in the _get_fixed_caps() function.

Fixes #575682.
This commit is contained in:
Zeeshan Ali (Khattak) 2009-03-18 17:01:16 +01:00 committed by Wim Taymans
parent 7d7fceced5
commit 8af9d58ea7
4 changed files with 96 additions and 72 deletions

View file

@ -1924,6 +1924,42 @@ no_format:
} }
} }
/**
* gst_pad_can_link:
* @srcpad: the source #GstPad.
* @sinkpad: the sink #GstPad.
*
* Checks if the source pad and the sink pad are compatible so they can be
* linked.
*
* Returns: TRUE if the pads can be linked.
*/
gboolean
gst_pad_can_link (GstPad * srcpad, GstPad * sinkpad)
{
GstPadLinkReturn result;
/* generic checks */
g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
GST_CAT_INFO (GST_CAT_PADS, "check if %s:%s can link with %s:%s",
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (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) == GST_PAD_LINK_OK;
if (result != GST_PAD_LINK_OK)
goto done;
GST_OBJECT_UNLOCK (srcpad);
GST_OBJECT_UNLOCK (sinkpad);
done:
return result == GST_PAD_LINK_OK;
}
/** /**
* gst_pad_link: * gst_pad_link:
* @srcpad: the source #GstPad to link. * @srcpad: the source #GstPad to link.

View file

@ -848,6 +848,7 @@ void gst_pad_set_event_function (GstPad *pad, GstPadEventFunction event);
void gst_pad_set_link_function (GstPad *pad, GstPadLinkFunction link); void gst_pad_set_link_function (GstPad *pad, GstPadLinkFunction link);
void gst_pad_set_unlink_function (GstPad *pad, GstPadUnlinkFunction unlink); 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 (GstPad *srcpad, GstPad *sinkpad);
gboolean gst_pad_unlink (GstPad *srcpad, GstPad *sinkpad); gboolean gst_pad_unlink (GstPad *srcpad, GstPad *sinkpad);
gboolean gst_pad_is_linked (GstPad *pad); gboolean gst_pad_is_linked (GstPad *pad);

View file

@ -39,7 +39,6 @@
#include "gstparse.h" #include "gstparse.h"
#include "gst-i18n-lib.h" #include "gst-i18n-lib.h"
/** /**
* gst_util_dump_mem: * gst_util_dump_mem:
* @mem: a pointer to the memory to dump * @mem: a pointer to the memory to dump
@ -918,6 +917,60 @@ gst_element_request_compatible_pad (GstElement * element,
return pad; return pad;
} }
/**
* Checks if the source pad and the sink pad can be linked.
* Both @srcpad and @sinkpad must be unlinked and have a parent.
*/
static gboolean
gst_pad_check_link (GstPad * srcpad, GstPad * sinkpad)
{
/* FIXME This function is gross. It's almost a direct copy of
* gst_pad_link_filtered(). Any decent programmer would attempt
* to merge the two functions, which I will do some day. --ds
*/
/* generic checks */
g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
GST_CAT_INFO (GST_CAT_PADS, "trying to link %s:%s and %s:%s",
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
/* FIXME: shouldn't we convert this to g_return_val_if_fail? */
if (GST_PAD_PEER (srcpad) != NULL) {
GST_CAT_INFO (GST_CAT_PADS, "Source pad %s:%s has a peer, failed",
GST_DEBUG_PAD_NAME (srcpad));
return FALSE;
}
if (GST_PAD_PEER (sinkpad) != NULL) {
GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s has a peer, failed",
GST_DEBUG_PAD_NAME (sinkpad));
return FALSE;
}
if (!GST_PAD_IS_SRC (srcpad)) {
GST_CAT_INFO (GST_CAT_PADS, "Src pad %s:%s is not source pad, failed",
GST_DEBUG_PAD_NAME (srcpad));
return FALSE;
}
if (!GST_PAD_IS_SINK (sinkpad)) {
GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s is not sink pad, failed",
GST_DEBUG_PAD_NAME (sinkpad));
return FALSE;
}
if (GST_PAD_PARENT (srcpad) == NULL) {
GST_CAT_INFO (GST_CAT_PADS, "Src pad %s:%s has no parent, failed",
GST_DEBUG_PAD_NAME (srcpad));
return FALSE;
}
if (GST_PAD_PARENT (sinkpad) == NULL) {
GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s has no parent, failed",
GST_DEBUG_PAD_NAME (srcpad));
return FALSE;
}
return TRUE;
}
/** /**
* gst_element_get_compatible_pad: * gst_element_get_compatible_pad:
* @element: a #GstElement in which the pad should be found. * @element: a #GstElement in which the pad should be found.
@ -969,7 +1022,7 @@ gst_element_get_compatible_pad (GstElement * element, GstPad * pad,
peer = gst_pad_get_peer (current); peer = gst_pad_get_peer (current);
if (peer == NULL && gst_pad_can_link (pad, current)) { if (peer == NULL && gst_pad_check_link (pad, current)) {
GstCaps *temp, *temp2, *intersection; GstCaps *temp, *temp2, *intersection;
/* Now check if the two pads' caps are compatible */ /* Now check if the two pads' caps are compatible */
@ -2107,66 +2160,6 @@ gst_element_seek_simple (GstElement * element, GstFormat format,
GST_SEEK_TYPE_SET, seek_pos, GST_SEEK_TYPE_NONE, 0); GST_SEEK_TYPE_SET, seek_pos, GST_SEEK_TYPE_NONE, 0);
} }
/**
* gst_pad_can_link:
* @srcpad: the source #GstPad to link.
* @sinkpad: the sink #GstPad to link.
*
* Checks if the source pad and the sink pad can be linked.
* Both @srcpad and @sinkpad must be unlinked.
*
* Returns: TRUE if the pads can be linked, FALSE otherwise.
*/
gboolean
gst_pad_can_link (GstPad * srcpad, GstPad * sinkpad)
{
/* FIXME This function is gross. It's almost a direct copy of
* gst_pad_link_filtered(). Any decent programmer would attempt
* to merge the two functions, which I will do some day. --ds
*/
/* generic checks */
g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
GST_CAT_INFO (GST_CAT_PADS, "trying to link %s:%s and %s:%s",
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
/* FIXME: shouldn't we convert this to g_return_val_if_fail? */
if (GST_PAD_PEER (srcpad) != NULL) {
GST_CAT_INFO (GST_CAT_PADS, "Source pad %s:%s has a peer, failed",
GST_DEBUG_PAD_NAME (srcpad));
return FALSE;
}
if (GST_PAD_PEER (sinkpad) != NULL) {
GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s has a peer, failed",
GST_DEBUG_PAD_NAME (sinkpad));
return FALSE;
}
if (!GST_PAD_IS_SRC (srcpad)) {
GST_CAT_INFO (GST_CAT_PADS, "Src pad %s:%s is not source pad, failed",
GST_DEBUG_PAD_NAME (srcpad));
return FALSE;
}
if (!GST_PAD_IS_SINK (sinkpad)) {
GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s is not sink pad, failed",
GST_DEBUG_PAD_NAME (sinkpad));
return FALSE;
}
if (GST_PAD_PARENT (srcpad) == NULL) {
GST_CAT_INFO (GST_CAT_PADS, "Src pad %s:%s has no parent, failed",
GST_DEBUG_PAD_NAME (srcpad));
return FALSE;
}
if (GST_PAD_PARENT (sinkpad) == NULL) {
GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s has no parent, failed",
GST_DEBUG_PAD_NAME (srcpad));
return FALSE;
}
return TRUE;
}
/** /**
* gst_pad_use_fixed_caps: * gst_pad_use_fixed_caps:
* @pad: the pad to use * @pad: the pad to use
@ -2210,9 +2203,7 @@ gst_pad_get_fixed_caps_func (GstPad * pad)
"using pad caps %p %" GST_PTR_FORMAT, result, result); "using pad caps %p %" GST_PTR_FORMAT, result, result);
result = gst_caps_ref (result); result = gst_caps_ref (result);
goto done; } else if (GST_PAD_PAD_TEMPLATE (pad)) {
}
if (GST_PAD_PAD_TEMPLATE (pad)) {
GstPadTemplate *templ = GST_PAD_PAD_TEMPLATE (pad); GstPadTemplate *templ = GST_PAD_PAD_TEMPLATE (pad);
result = GST_PAD_TEMPLATE_CAPS (templ); result = GST_PAD_TEMPLATE_CAPS (templ);
@ -2221,12 +2212,10 @@ gst_pad_get_fixed_caps_func (GstPad * pad)
result); result);
result = gst_caps_ref (result); result = gst_caps_ref (result);
goto done; } else {
}
GST_CAT_DEBUG (GST_CAT_CAPS, "pad has no caps"); GST_CAT_DEBUG (GST_CAT_CAPS, "pad has no caps");
result = gst_caps_new_empty (); result = gst_caps_new_empty ();
}
done:
GST_OBJECT_UNLOCK (pad); GST_OBJECT_UNLOCK (pad);
return result; return result;

View file

@ -1036,8 +1036,6 @@ void gst_element_class_install_std_props (GstElementClass * klass,
const gchar * first_name, ...) G_GNUC_NULL_TERMINATED; const gchar * first_name, ...) G_GNUC_NULL_TERMINATED;
/* pad functions */ /* pad functions */
gboolean gst_pad_can_link (GstPad *srcpad, GstPad *sinkpad);
void gst_pad_use_fixed_caps (GstPad *pad); void gst_pad_use_fixed_caps (GstPad *pad);
GstCaps* gst_pad_get_fixed_caps_func (GstPad *pad); GstCaps* gst_pad_get_fixed_caps_func (GstPad *pad);
GstCaps* gst_pad_proxy_getcaps (GstPad * pad); GstCaps* gst_pad_proxy_getcaps (GstPad * pad);