+2005-07-13 Andy Wingo <wingo@pobox.com>
+
+ * gst/base/gstbasesrc.c (gst_base_src_start): Post an error if the
+ source couldn't negotiate.
+
+ * gst/parse/grammar.y: Revert 1.54->1.55, so we now do filtered
+ connections again.
+
+ * gst/gstutils.h:
+ * gst/gstutils.c (gst_element_link_pads_filtered): New old
+ function. I am channeling Hades. Put your boots on suckers!!!
+
2005-07-13 Thomas Vander Stichele <thomas at apestaart dot org>
* testsuite/caps/Makefile.am:
</para>
+<!-- ##### SECTION Stability_Level ##### -->
+
+
<!-- ##### STRUCT GstMiniObject ##### -->
<para>
could_not_negotiate:
{
GST_DEBUG_OBJECT (basesrc, "could not negotiate, stopping");
+ GST_ELEMENT_ERROR (basesrc, STREAM, FORMAT,
+ ("Could not connect source to pipeline"),
+ ("Check your filtered caps, if any"));
gst_base_src_stop (basesrc);
return FALSE;
}
}
/**
+ * gst_element_link_pads_filtered:
+ * @src: a #GstElement containing the source pad.
+ * @srcpadname: the name of the #GstPad in source element or NULL for any pad.
+ * @dest: the #GstElement containing the destination pad.
+ * @destpadname: the name of the #GstPad in destination element or NULL for any pad.
+ * @caps: the #GstCaps to filter the link, or #NULL for no filter.
+ *
+ * Links the two named pads of the source and destination elements. Side effect
+ * is that if one of the pads has no parent, it becomes a child of the parent of
+ * the other element. If they have different parents, the link fails. If @caps
+ * is not #NULL, makes sure that the caps of the link is a subset of @caps.
+ *
+ * Returns: TRUE if the pads could be linked, FALSE otherwise.
+ */
+gboolean
+gst_element_link_pads_filtered (GstElement * src, const gchar * srcpadname,
+ GstElement * dest, const gchar * destpadname, GstCaps * filter)
+{
+ /* checks */
+ g_return_val_if_fail (GST_IS_ELEMENT (src), FALSE);
+ g_return_val_if_fail (GST_IS_ELEMENT (dest), FALSE);
+ g_return_val_if_fail (filter == NULL || GST_IS_CAPS (filter), FALSE);
+
+ if (filter) {
+ GstElement *capsfilter;
+ GstObject *parent;
+
+ capsfilter = gst_element_factory_make ("capsfilter", NULL);
+ if (!capsfilter) {
+ GST_ERROR ("Could not make a capsfilter");
+ return FALSE;
+ }
+
+ parent = gst_object_get_parent (GST_OBJECT (src));
+ g_return_val_if_fail (GST_IS_BIN (parent), FALSE);
+
+ if (!gst_bin_add (GST_BIN (parent), capsfilter)) {
+ GST_ERROR ("Could not add capsfilter");
+ gst_object_unref (capsfilter);
+ gst_object_unref (parent);
+ return FALSE;
+ }
+
+ gst_object_unref (parent);
+
+ g_object_set (capsfilter, "filter-caps", filter, NULL);
+
+ if (gst_element_link_pads (src, srcpadname, capsfilter, "sink")
+ && gst_element_link_pads (capsfilter, "src", dest, destpadname)) {
+ return TRUE;
+ } else {
+ GST_INFO ("Could not link elements");
+ gst_bin_remove (GST_BIN (GST_OBJECT_PARENT (capsfilter)), capsfilter);
+ /* will unref and unlink as appropriate */
+ return FALSE;
+ }
+ } else {
+ return gst_element_link_pads (src, srcpadname, dest, destpadname);
+ }
+}
+
+/**
* gst_element_link:
* @src: a #GstElement containing the source pad.
* @dest: the #GstElement containing the destination pad.
gboolean
gst_element_link (GstElement * src, GstElement * dest)
{
- return gst_element_link_pads (src, NULL, dest, NULL);
+ return gst_element_link_pads_filtered (src, NULL, dest, NULL, NULL);
}
/**
void gst_element_unlink_pads (GstElement *src, const gchar *srcpadname,
GstElement *dest, const gchar *destpadname);
+gboolean gst_element_link_pads_filtered (GstElement * src, const gchar * srcpadname,
+ GstElement * dest, const gchar * destpadname,
+ GstCaps *filter);
+
/* util elementfactory functions */
gboolean gst_element_factory_can_src_caps(GstElementFactory *factory, const GstCaps *caps);
gboolean gst_element_factory_can_sink_caps(GstElementFactory *factory, const GstCaps *caps);
GST_ELEMENT_NAME (src), link->src_pad,
GST_ELEMENT_NAME (link->sink), link->sink_pad);
- if (gst_element_link_pads (src, link->src_pad, link->sink, link->sink_pad)) {
+ if (gst_element_link_pads_filtered (src, link->src_pad, link->sink, link->sink_pad, link->caps)) {
/* do this here, we don't want to get any problems later on when unlocking states */
GST_CAT_DEBUG (GST_CAT_PIPELINE, "delayed linking %s:%s to %s:%s worked",
GST_ELEMENT_NAME (src), link->src_pad,
link->caps);
if (!srcs || !sinks) {
- if (gst_element_link_pads (src, srcs ? (const gchar *) srcs->data : NULL,
- sink, sinks ? (const gchar *) sinks->data : NULL)) {
+ if (gst_element_link_pads_filtered (src, srcs ? (const gchar *) srcs->data : NULL,
+ sink, sinks ? (const gchar *) sinks->data : NULL,
+ link->caps)) {
gst_parse_element_lock (sink, gst_element_is_locked_state (src));
goto success;
} else {
const gchar *sink_pad = (const gchar *) sinks->data;
srcs = g_slist_next (srcs);
sinks = g_slist_next (sinks);
- if (gst_element_link_pads (src, src_pad, sink, sink_pad)) {
+ if (gst_element_link_pads_filtered (src, src_pad, sink, sink_pad, link->caps)) {
gst_parse_element_lock (sink, gst_element_is_locked_state (src));
continue;
} else {
could_not_negotiate:
{
GST_DEBUG_OBJECT (basesrc, "could not negotiate, stopping");
+ GST_ELEMENT_ERROR (basesrc, STREAM, FORMAT,
+ ("Could not connect source to pipeline"),
+ ("Check your filtered caps, if any"));
gst_base_src_stop (basesrc);
return FALSE;
}