Add new use_explicit_caps() and set_explicit_caps() functions.
authorDavid Schleef <ds@schleef.org>
Fri, 2 Jan 2004 07:02:43 +0000 (07:02 +0000)
committerDavid Schleef <ds@schleef.org>
Fri, 2 Jan 2004 07:02:43 +0000 (07:02 +0000)
Original commit message from CVS:
Add new use_explicit_caps() and set_explicit_caps() functions.

ChangeLog
gst/gstpad.c
gst/gstpad.h

index 6bc6634..6081e08 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2004-01-01  David Schleef  <ds@schleef.org>
+
+       * gst/gstpad.c: (gst_pad_set_explicit_caps),
+       (gst_pad_explicit_getcaps), (gst_pad_explicit_link),
+       (gst_pad_use_explicit_caps):
+       * gst/gstpad.h:
+       Add new functions.  gst_pad_use_explicit_caps() sets up a pad
+       to use an internal getcaps and link fuction so that negotiation
+       always results in the explicitly set caps.
+       gst_pad_set_explicit_caps() sets the explicit caps.  These functions
+       are particularly useful for decoders.
+
 2003-12-31  David Schleef  <ds@schleef.org>
 
        * gst/elements/gstidentity.c: (gst_identity_class_init),
index eb2c57c..3137a08 100644 (file)
@@ -2099,6 +2099,95 @@ gst_pad_proxy_fixate (GstPad *pad, const GstCaps *caps, gpointer unused)
 }
 
 /**
+ * gst_pad_set_explicit_caps:
+ * @pad: a #GstPad to set the explicit caps of
+ * @caps: the #GstCaps to set
+ *
+ * If a pad has been told to use explicit caps, this function is used
+ * to set the explicit caps.  If @caps is NULL, the explicit caps are
+ * unset.
+ *
+ * This function calls gst_pad_try_set_caps() on the pad.  If that
+ * call fails, gst_element_error() is called to indicate a negotiation
+ * failure.
+ * 
+ * Returns: TRUE if the caps were set correctly, otherwise FALSE
+ */
+gboolean
+gst_pad_set_explicit_caps (GstPad *pad, GstCaps *caps)
+{
+  GstPadLinkReturn link_ret;
+
+  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
+
+  if (caps == NULL) {
+    gst_caps_replace (&GST_RPAD_EXPLICIT_CAPS (pad), NULL);
+    return TRUE;
+  }
+
+  if (!GST_PAD_IS_LINKED (pad)) {
+    gst_caps_replace (&GST_RPAD_EXPLICIT_CAPS (pad), caps);
+    return TRUE;
+  }
+  link_ret = gst_pad_try_set_caps (pad, caps);
+  if (GST_PAD_LINK_FAILED (link_ret)) {
+    gst_element_error (gst_pad_get_parent (pad), "negotiation failed");
+    return FALSE;
+  }
+
+  gst_caps_replace (&GST_RPAD_EXPLICIT_CAPS (pad), caps);
+
+  return TRUE;
+}
+
+static GstCaps *
+gst_pad_explicit_getcaps (GstPad *pad)
+{
+  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
+
+  if (GST_RPAD_EXPLICIT_CAPS (pad) == NULL) {
+    return gst_caps_copy (gst_pad_get_pad_template_caps (pad));
+  }
+  return gst_caps_copy (GST_RPAD_EXPLICIT_CAPS (pad));
+}
+
+static GstPadLinkReturn
+gst_pad_explicit_link (GstPad *pad, const GstCaps *caps)
+{
+  g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_LINK_REFUSED);
+  g_return_val_if_fail (caps != NULL, GST_PAD_LINK_REFUSED);
+
+  if (GST_RPAD_EXPLICIT_CAPS (pad) == NULL) {
+    return GST_PAD_LINK_DELAYED;
+  }
+
+  return GST_PAD_LINK_OK;
+}
+
+/**
+ * gst_pad_use_explicit_caps:
+ * @pad: a #GstPad to set to use explicit caps
+ *
+ * This function handles negotiation for pads that need to be set
+ * to particular caps under complete control of the element, based
+ * on some state in the element.  This is often the case with
+ * decoders and other elements whose caps is determined by the data
+ * stream.
+ *
+ * WARNING: This function is a hack and will be replaced with something
+ * better in gstreamer-0.9.
+ */
+void
+gst_pad_use_explicit_caps (GstPad *pad)
+{
+  g_return_if_fail (GST_IS_PAD (pad));
+
+  gst_pad_set_getcaps_function (pad, gst_pad_explicit_getcaps);
+  gst_pad_set_link_function (pad, gst_pad_explicit_link);
+  gst_caps_replace (&GST_RPAD_EXPLICIT_CAPS (pad), NULL);
+}
+
+/**
  * gst_pad_proxy_link:
  * @pad: a #GstPad to proxy to.
  * @caps: the #GstCaps to use in proxying.
index cf136be..8e46c4e 100644 (file)
@@ -199,8 +199,9 @@ struct _GstRealPad {
   GstProbeDispatcher            probedisp;
 
   GstPadLink                    *link;
+  GstCaps                      *explicit_caps;
 
-  gpointer _gst_reserved[GST_PADDING - 1];
+  gpointer _gst_reserved[GST_PADDING - 2];
 };
 
 struct _GstRealPadClass {
@@ -261,6 +262,7 @@ struct _GstGhostPadClass {
 #define GST_RPAD_FIXATEFUNC(pad)       (((GstRealPad *)(pad))->fixatefunc)
 #define GST_RPAD_BUFFERALLOCFUNC(pad)  (((GstRealPad *)(pad))->bufferallocfunc)
 #define GST_RPAD_LINK(pad)             (((GstRealPad *)(pad))->link)
+#define GST_RPAD_EXPLICIT_CAPS(pad)    (((GstRealPad *)(pad))->explicit_caps)
 
 /* GstGhostPad */
 #define GST_GPAD_REALPAD(pad)          (((GstGhostPad *)(pad))->realpad)
@@ -416,6 +418,8 @@ GstCaps *               gst_pad_proxy_fixate                    (GstPad *pad, co
 #ifndef GST_DISABLE_DEPRECATED
 GstPadLinkReturn       gst_pad_proxy_link                      (GstPad *pad, const GstCaps *caps);
 #endif
+gboolean               gst_pad_set_explicit_caps               (GstPad *pad, GstCaps *caps);
+void                   gst_pad_use_explicit_caps               (GstPad *pad);
 gboolean               gst_pad_relink_filtered                 (GstPad *srcpad, GstPad *sinkpad, const GstCaps *filtercaps);
 #ifndef GST_DISABLE_DEPRECATED
 gboolean               gst_pad_perform_negotiate               (GstPad *srcpad, GstPad *sinkpad);