GList *sinkpads;
gboolean connected = FALSE;
- GST_DEBUG (0,"gstpipeline: autoplug pad connect function for \"%s\" to \"%s\"\n",
- GST_ELEMENT_NAME(src), GST_ELEMENT_NAME(sink));
+ GST_DEBUG (0,"gstpipeline: autoplug pad connect function for %s %s:%s to \"%s\"\n",
+ GST_ELEMENT_NAME (src), GST_DEBUG_PAD_NAME(pad), GST_ELEMENT_NAME(sink));
sinkpads = gst_element_get_pad_list(sink);
while (sinkpads) {
g_return_val_if_fail (pad != NULL, FALSE);
g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE); // NOTE this restriction
+ if (!gst_caps_check_compatibility (caps, gst_pad_get_padtemplate_caps (pad))) {
+ g_warning ("pad %s:%s tried to set caps incompatible with its padtemplate\n",
+ GST_DEBUG_PAD_NAME (pad));
+ return FALSE;
+ }
+
GST_PAD_CAPS(pad) = caps;
return gst_pad_renegotiate (pad);
g_strfreev (split);
}
-/**
- * gst_pad_renegotiate:
- * @pad: the pad to perform the negotiation on
- *
- * Perform the negotiation process with the peer pad.
- *
- * Returns: TRUE if the negotiation process succeded
- */
-gboolean
-gst_pad_renegotiate (GstPad *pad)
+static gboolean
+gst_pad_renegotiate_func (GstPad *pad, GstPad *peerpad, GstCaps **newcaps, gint *counter)
{
- gint counter = 0;
- GstCaps *newcaps = NULL;
- GstRealPad *peerpad, *currentpad, *otherpad;
- GstPadDirection currentdirection;
+ GstRealPad *currentpad, *otherpad;
GstPadNegotiateReturn result;
g_return_val_if_fail (pad != NULL, FALSE);
- peerpad = GST_PAD_PEER (pad);
-
currentpad = GST_PAD_REALIZE (pad);
-
- if (!peerpad) {
- GST_DEBUG (GST_CAT_ELEMENT_PADS, "no peer pad for pad %s:%s\n",
- GST_DEBUG_PAD_NAME(currentpad));
- return TRUE;
- }
-
otherpad = GST_REAL_PAD (peerpad);
- GST_INFO (GST_CAT_ELEMENT_PADS, "negotiating pad %s:%s and %s:%s",
- GST_DEBUG_PAD_NAME(pad), GST_DEBUG_PAD_NAME(peerpad));
-
- newcaps = GST_PAD_CAPS (pad);
- g_assert (newcaps != NULL);
-
- currentdirection = GST_PAD_DIRECTION (currentpad);
+ GST_DEBUG (GST_CAT_ELEMENT_PADS, "negotiating pad %s:%s and %s:%s counter:%d\n",
+ GST_DEBUG_PAD_NAME(pad), GST_DEBUG_PAD_NAME(peerpad), *counter);
do {
gboolean matchtempl;
- matchtempl = gst_caps_check_compatibility (newcaps, gst_pad_get_padtemplate_caps (GST_PAD (otherpad)));
+ matchtempl = gst_caps_check_compatibility (*newcaps, gst_pad_get_padtemplate_caps (GST_PAD (otherpad)));
+
+ GST_DEBUG (GST_CAT_ELEMENT_PADS, "caps compatibility check %d\n", matchtempl);
if (matchtempl) {
if (otherpad->negotiatefunc) {
GstRealPad *temp;
+ GST_DEBUG (GST_CAT_ELEMENT_PADS, "switching pad for next phase\n");
+
temp = currentpad;
currentpad = otherpad;
otherpad = temp;
}
- else if (gst_caps_check_compatibility (newcaps, GST_PAD_CAPS (otherpad))) {
- break;
+ else if (gst_caps_check_compatibility (*newcaps, GST_PAD_CAPS (otherpad))) {
+ GST_DEBUG (GST_CAT_ELEMENT_PADS, "negotiation succeeded\n");
+ return TRUE;
}
else {
- newcaps = GST_PAD_CAPS (otherpad);
+ *newcaps = GST_PAD_CAPS (otherpad);
}
}
else {
- newcaps = GST_PAD_CAPS (otherpad);
+ *newcaps = GST_PAD_CAPS (otherpad);
}
- counter++;
+ (*counter)++;
if (currentpad->negotiatefunc) {
- result = currentpad->negotiatefunc (GST_PAD (currentpad), &newcaps, counter);
+ GST_DEBUG (GST_CAT_ELEMENT_PADS, "calling negotiate function on pad %s:%s\n",
+ GST_DEBUG_PAD_NAME (currentpad));
+ result = currentpad->negotiatefunc (GST_PAD (currentpad), newcaps, *counter);
switch (result) {
case GST_PAD_NEGOTIATE_FAIL:
+ GST_DEBUG (GST_CAT_ELEMENT_PADS, "negotiation failed\n");
return FALSE;
case GST_PAD_NEGOTIATE_AGREE:
- goto succeed;
+ GST_DEBUG (GST_CAT_ELEMENT_PADS, "negotiation succeeded\n");
+ return TRUE;
case GST_PAD_NEGOTIATE_TRY:
+ GST_DEBUG (GST_CAT_ELEMENT_PADS, "try another option\n");
break;
}
}
else {
+ GST_DEBUG (GST_CAT_ELEMENT_PADS, "negotiation failed, no more options\n");
return FALSE;
}
- } while (counter < 100);
+ } while (*counter < 100);
-succeed:
+ GST_DEBUG (GST_CAT_ELEMENT_PADS, "negotiation failed, too many attempts\n");
- GST_DEBUG (GST_CAT_ELEMENT_PADS, "pads aggreed on caps :)\n");
+ return FALSE;
+}
- /* here we have some sort of aggreement of the caps */
- GST_PAD_CAPS (currentpad) = newcaps;
- GST_PAD_CAPS (otherpad) = newcaps;
+/**
+ * gst_pad_renegotiate:
+ * @pad: the pad to perform the negotiation on
+ *
+ * Perform the negotiation process with the peer pad.
+ *
+ * Returns: TRUE if the negotiation process succeded
+ */
+gboolean
+gst_pad_renegotiate (GstPad *pad)
+{
+ GstCaps *newcaps = NULL;
+ GstRealPad *peerpad, *currentpad, *otherpad;
+ gboolean result;
+ gint counter = 0;
+
+ g_return_val_if_fail (pad != NULL, FALSE);
+
+ peerpad = GST_PAD_PEER (pad);
+
+ currentpad = GST_PAD_REALIZE (pad);
+
+ if (!peerpad) {
+ GST_DEBUG (GST_CAT_ELEMENT_PADS, "no peer pad for pad %s:%s\n",
+ GST_DEBUG_PAD_NAME(currentpad));
+ return TRUE;
+ }
- return TRUE;
+ otherpad = GST_REAL_PAD (peerpad);
+
+ GST_INFO (GST_CAT_ELEMENT_PADS, "negotiating pad %s:%s and %s:%s",
+ GST_DEBUG_PAD_NAME(pad), GST_DEBUG_PAD_NAME(peerpad));
+
+ newcaps = GST_PAD_CAPS (pad);
+ g_assert (newcaps != NULL);
+
+ result = gst_pad_renegotiate_func (pad, GST_PAD (peerpad), &newcaps, &counter);
+
+ if (result) {
+ GST_DEBUG (GST_CAT_ELEMENT_PADS, "pads aggreed on caps :)\n");
+
+ /* here we have some sort of aggreement of the caps */
+ GST_PAD_CAPS (currentpad) = newcaps;
+ GST_PAD_CAPS (otherpad) = newcaps;
+ }
+
+ return result;
}
+
GstPadNegotiateReturn
gst_pad_negotiate_proxy (GstPad *pad, GstCaps **caps, gint counter)
{
GstRealPad *peer;
+ gboolean result;
g_return_val_if_fail (pad != NULL, GST_PAD_NEGOTIATE_FAIL);
- GST_DEBUG (GST_CAT_ELEMENT_PADS, "pad (%s:%s) proxied\n", GST_DEBUG_PAD_NAME (pad));
+ GST_DEBUG (GST_CAT_ELEMENT_PADS, "negotiation proxied to pad (%s:%s)\n", GST_DEBUG_PAD_NAME (pad));
peer = GST_RPAD_PEER (pad);
//GST_PAD_CAPS (pad) = caps;
if (peer) {
- if (peer->negotiatefunc) {
- GST_DEBUG (GST_CAT_ELEMENT_PADS, "calling negotiate on peer (%s:%s)\n", GST_DEBUG_PAD_NAME (peer));
- return peer->negotiatefunc (peer, caps, counter);
+ result = gst_pad_renegotiate_func (pad, GST_PAD (peer), caps, &counter);
+
+ if (result) {
+ GST_DEBUG (GST_CAT_ELEMENT_PADS, "pads aggreed on caps :)\n");
+
+ /* here we have some sort of aggreement of the caps */
+ GST_PAD_CAPS (pad) = *caps;
+ GST_PAD_CAPS (peer) = *caps;
+ }
+ else {
+ return GST_PAD_NEGOTIATE_FAIL;
}
}
}
static GstPadNegotiateReturn
-gst_queue_handle_negotiate_src (GstPad *pad, GstCaps **caps, gint count)
+gst_queue_handle_negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
{
GstQueue *queue;
queue = GST_QUEUE (GST_OBJECT_PARENT (pad));
- return gst_pad_negotiate_proxy (queue->sinkpad, caps, count);
+ if (counter == 0) {
+ *caps = NULL;
+ return GST_PAD_NEGOTIATE_TRY;
+ }
+ if (*caps) {
+ if (counter == 1) {
+ return gst_pad_negotiate_proxy (queue->sinkpad, caps, counter);
+ }
+ }
+
+ return GST_PAD_NEGOTIATE_FAIL;
}
static GstPadNegotiateReturn
-gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps **caps, gint count)
+gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
{
GstQueue *queue;
queue = GST_QUEUE (GST_OBJECT_PARENT (pad));
- return gst_pad_negotiate_proxy (queue->srcpad, caps, count);
+ if (counter == 0) {
+ *caps = NULL;
+ return GST_PAD_NEGOTIATE_TRY;
+ }
+ if (*caps) {
+ if (counter == 1) {
+ return gst_pad_negotiate_proxy (queue->srcpad, caps, counter);
+ }
+ }
+
+ return GST_PAD_NEGOTIATE_FAIL;
}
static gboolean
}
static GstPadNegotiateReturn
-gst_queue_handle_negotiate_src (GstPad *pad, GstCaps **caps, gint count)
+gst_queue_handle_negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
{
GstQueue *queue;
queue = GST_QUEUE (GST_OBJECT_PARENT (pad));
- return gst_pad_negotiate_proxy (queue->sinkpad, caps, count);
+ if (counter == 0) {
+ *caps = NULL;
+ return GST_PAD_NEGOTIATE_TRY;
+ }
+ if (*caps) {
+ if (counter == 1) {
+ return gst_pad_negotiate_proxy (queue->sinkpad, caps, counter);
+ }
+ }
+
+ return GST_PAD_NEGOTIATE_FAIL;
}
static GstPadNegotiateReturn
-gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps **caps, gint count)
+gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
{
GstQueue *queue;
queue = GST_QUEUE (GST_OBJECT_PARENT (pad));
- return gst_pad_negotiate_proxy (queue->srcpad, caps, count);
+ if (counter == 0) {
+ *caps = NULL;
+ return GST_PAD_NEGOTIATE_TRY;
+ }
+ if (*caps) {
+ if (counter == 1) {
+ return gst_pad_negotiate_proxy (queue->srcpad, caps, counter);
+ }
+ }
+
+ return GST_PAD_NEGOTIATE_FAIL;
}
static gboolean
.libs
capsnego
converter
+converter2
SUBDIRS =
-testprogs = capsnego converter
+testprogs = capsnego converter converter2
TESTS = $(testprogs)
--- /dev/null
+
+#include <gst/gst.h>
+
+GstPad *srcpad, *sinkpad;
+GstPad *srcconvpad, *sinkconvpad;
+GstPad *srcpadtempl, *sinkpadtempl;
+GstPad *srcconvtempl, *sinkconvtempl;
+
+gint converter_in = -1, converter_out = -1;
+gint target_rate = 2000;
+
+static GstPadFactory src_factory = {
+ "src",
+ GST_PAD_FACTORY_SRC,
+ GST_PAD_FACTORY_ALWAYS,
+ GST_PAD_FACTORY_CAPS(
+ "test_src",
+ "audio/raw",
+ "rate", GST_PROPS_INT_RANGE (16, 20000)
+ ),
+ NULL,
+};
+
+static GstPadFactory src_conv_factory = {
+ "src",
+ GST_PAD_FACTORY_SRC,
+ GST_PAD_FACTORY_ALWAYS,
+ GST_PAD_FACTORY_CAPS(
+ "test_src",
+ "audio/raw",
+ "rate", GST_PROPS_INT_RANGE (16, 20000)
+ ),
+ NULL,
+};
+
+static GstPadFactory sink_conv_factory = {
+ "src",
+ GST_PAD_FACTORY_SINK,
+ GST_PAD_FACTORY_ALWAYS,
+ GST_PAD_FACTORY_CAPS(
+ "test_src",
+ "audio/raw",
+ "rate", GST_PROPS_INT_RANGE (16, 20000)
+ ),
+ NULL,
+};
+
+static GstPadFactory sink_factory = {
+ "sink",
+ GST_PAD_FACTORY_SINK,
+ GST_PAD_FACTORY_ALWAYS,
+ GST_PAD_FACTORY_CAPS(
+ "test_sink",
+ "audio/raw",
+ "rate", GST_PROPS_INT_RANGE (16, 20000)
+ ),
+ NULL,
+};
+
+static GstCapsFactory sink_caps = {
+ "sink_caps",
+ "audio/raw",
+ "rate", GST_PROPS_INT (6000),
+ NULL
+};
+
+static GstCapsFactory src_caps = {
+ "src_caps",
+ "audio/raw",
+ "rate", GST_PROPS_INT (3000),
+ NULL
+};
+
+static GstPadTemplate *srctempl, *sinktempl;
+static GstCaps *srccaps, *sinkcaps;
+
+static GstPadNegotiateReturn
+converter_negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
+{
+ g_print (">");
+
+ if (counter == 0) {
+ *caps = NULL;
+ return GST_PAD_NEGOTIATE_TRY;
+ }
+ if (*caps) {
+ converter_out = gst_caps_get_int (*caps, "rate");
+ return GST_PAD_NEGOTIATE_AGREE;
+ }
+
+ return GST_PAD_NEGOTIATE_FAIL;
+}
+
+static GstPadNegotiateReturn
+converter_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
+{
+ g_print ("<");
+ if (counter == 0) {
+ *caps = GST_PAD_CAPS (srcconvpad);
+ return GST_PAD_NEGOTIATE_TRY;
+ }
+ if (*caps) {
+ converter_in = gst_caps_get_int (*caps, "rate");
+
+ if (counter == 1) {
+ converter_out = gst_caps_get_int (*caps, "rate");
+ return gst_pad_negotiate_proxy (srcconvpad, caps, counter);
+ }
+ return GST_PAD_NEGOTIATE_AGREE;
+ }
+
+ return GST_PAD_NEGOTIATE_FAIL;
+}
+
+static GstPadNegotiateReturn
+target_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
+{
+ g_print ("{");
+ if (counter == 0) {
+ *caps = gst_caps_new_with_props (
+ "target_caps",
+ "audio/raw",
+ gst_props_new (
+ "rate", GST_PROPS_INT (target_rate),
+ NULL)
+ );
+ return GST_PAD_NEGOTIATE_TRY;
+ }
+ if (*caps) {
+ target_rate = gst_caps_get_int (*caps, "rate");
+ g_print ("target set %d\n", target_rate);
+ return GST_PAD_NEGOTIATE_AGREE;
+ }
+
+ return GST_PAD_NEGOTIATE_FAIL;
+}
+
+int
+main (int argc, char *argv[])
+{
+ gboolean overall = TRUE;
+ gboolean result;
+
+ gst_init (&argc, &argv);
+
+ srctempl = gst_padtemplate_new (&src_factory);
+ sinktempl = gst_padtemplate_new (&sink_factory);
+ srcpad = gst_pad_new_from_template (srctempl, "src");
+ sinkpad = gst_pad_new_from_template (sinktempl, "sink");
+
+ srcconvtempl = gst_padtemplate_new (&src_conv_factory);
+ sinkconvtempl = gst_padtemplate_new (&sink_conv_factory);
+ srcconvpad = gst_pad_new_from_template (srcconvtempl, "csrc");
+ sinkconvpad = gst_pad_new_from_template (sinkconvtempl, "csink");
+
+ gst_pad_set_negotiate_function (srcconvpad, converter_negotiate_src);
+ gst_pad_set_negotiate_function (sinkconvpad, converter_negotiate_sink);
+ gst_pad_set_negotiate_function (sinkpad, target_negotiate_sink);
+
+ sinkcaps = gst_caps_register (&sink_caps);
+ srccaps = gst_caps_register (&src_caps);
+
+ g_print ("-------) (-----------) (----- \n");
+ g_print (" ! ! converter ! ! \n");
+ g_print (" src -- csink csrc -- sink \n");
+ g_print ("-------) (-----------) (----- \n\n");
+ g_print ("The convertor first tries to proxy the caps received\n");
+ g_print ("on its csink pad to its csrc pad, when that fails, it\n");
+ g_print ("sets up the conversion.\n\n");
+
+
+ g_print ("sink pad set caps (rate=%d), converter status: %d %d\n", target_rate,
+ converter_in, converter_out);
+ gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (target_rate));
+ result = gst_pad_set_caps (sinkpad, sinkcaps);
+ g_print ("result: %d, converter status: %d %d, target: %d\n\n", result,
+ converter_in, converter_out, target_rate);
+
+ result = gst_pad_connect (srcpad, sinkconvpad);
+ g_print ("pad connect 1: %d\n", result);
+ overall &= (result == TRUE);
+ result = gst_pad_connect (srcconvpad, sinkpad);
+ g_print ("pad connect 2: %d\n", result);
+ overall &= (result == TRUE);
+
+ g_print ("after connect, converter status: %d %d, target %d\n\n", converter_in, converter_out, target_rate);
+
+ g_print ("src pad set caps (rate=%d), converter status: %d %d, target %d \n", gst_caps_get_int (srccaps, "rate"),
+ converter_in, converter_out, target_rate);
+ result = gst_pad_set_caps (srcpad, srccaps);
+ g_print ("result %d, converter status: %d %d, target %d\n\n", result,
+ converter_in, converter_out, target_rate);
+
+ g_print ("sink pad set caps (rate=2000), converter status: %d %d, target %d \n",
+ converter_in, converter_out, target_rate);
+ target_rate = 2000;
+ gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (target_rate));
+ result = gst_pad_set_caps (sinkpad, sinkcaps);
+ g_print ("result %d, converter status: %d %d, target: %d\n\n", result,
+ converter_in, converter_out, target_rate);
+
+ gst_caps_set (srccaps, "rate", GST_PROPS_INT (4000));
+ result = gst_pad_renegotiate (srcpad);
+ g_print ("sink pad renegotiate caps %d, converter status: %d %d, target: %d\n", result,
+ converter_in, converter_out, target_rate);
+
+ gst_caps_set (srccaps, "rate", GST_PROPS_INT (40000));
+ result = gst_pad_set_caps (srcpad, srccaps);
+ g_print ("sink pad set caps %d, converter status: %d %d, target: %d\n", result,
+ converter_in, converter_out, target_rate);
+
+ gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (40000));
+ result = gst_pad_set_caps (sinkpad, sinkcaps);
+ g_print ("sink pad set caps %d, converter status: %d %d, target: %d\n", result,
+ converter_in, converter_out, target_rate);
+
+ target_rate = 9000;
+ gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (target_rate));
+ result = gst_pad_set_caps (sinkpad, sinkcaps);
+ g_print ("sink pad set caps %d, converter status: %d %d, target: %d\n", result,
+ converter_in, converter_out, target_rate);
+
+ exit (!overall);
+}
.libs
capsnego
converter
+converter2
SUBDIRS =
-testprogs = capsnego converter
+testprogs = capsnego converter converter2
TESTS = $(testprogs)
--- /dev/null
+
+#include <gst/gst.h>
+
+GstPad *srcpad, *sinkpad;
+GstPad *srcconvpad, *sinkconvpad;
+GstPad *srcpadtempl, *sinkpadtempl;
+GstPad *srcconvtempl, *sinkconvtempl;
+
+gint converter_in = -1, converter_out = -1;
+gint target_rate = 2000;
+
+static GstPadFactory src_factory = {
+ "src",
+ GST_PAD_FACTORY_SRC,
+ GST_PAD_FACTORY_ALWAYS,
+ GST_PAD_FACTORY_CAPS(
+ "test_src",
+ "audio/raw",
+ "rate", GST_PROPS_INT_RANGE (16, 20000)
+ ),
+ NULL,
+};
+
+static GstPadFactory src_conv_factory = {
+ "src",
+ GST_PAD_FACTORY_SRC,
+ GST_PAD_FACTORY_ALWAYS,
+ GST_PAD_FACTORY_CAPS(
+ "test_src",
+ "audio/raw",
+ "rate", GST_PROPS_INT_RANGE (16, 20000)
+ ),
+ NULL,
+};
+
+static GstPadFactory sink_conv_factory = {
+ "src",
+ GST_PAD_FACTORY_SINK,
+ GST_PAD_FACTORY_ALWAYS,
+ GST_PAD_FACTORY_CAPS(
+ "test_src",
+ "audio/raw",
+ "rate", GST_PROPS_INT_RANGE (16, 20000)
+ ),
+ NULL,
+};
+
+static GstPadFactory sink_factory = {
+ "sink",
+ GST_PAD_FACTORY_SINK,
+ GST_PAD_FACTORY_ALWAYS,
+ GST_PAD_FACTORY_CAPS(
+ "test_sink",
+ "audio/raw",
+ "rate", GST_PROPS_INT_RANGE (16, 20000)
+ ),
+ NULL,
+};
+
+static GstCapsFactory sink_caps = {
+ "sink_caps",
+ "audio/raw",
+ "rate", GST_PROPS_INT (6000),
+ NULL
+};
+
+static GstCapsFactory src_caps = {
+ "src_caps",
+ "audio/raw",
+ "rate", GST_PROPS_INT (3000),
+ NULL
+};
+
+static GstPadTemplate *srctempl, *sinktempl;
+static GstCaps *srccaps, *sinkcaps;
+
+static GstPadNegotiateReturn
+converter_negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
+{
+ g_print (">");
+
+ if (counter == 0) {
+ *caps = NULL;
+ return GST_PAD_NEGOTIATE_TRY;
+ }
+ if (*caps) {
+ converter_out = gst_caps_get_int (*caps, "rate");
+ return GST_PAD_NEGOTIATE_AGREE;
+ }
+
+ return GST_PAD_NEGOTIATE_FAIL;
+}
+
+static GstPadNegotiateReturn
+converter_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
+{
+ g_print ("<");
+ if (counter == 0) {
+ *caps = GST_PAD_CAPS (srcconvpad);
+ return GST_PAD_NEGOTIATE_TRY;
+ }
+ if (*caps) {
+ converter_in = gst_caps_get_int (*caps, "rate");
+
+ if (counter == 1) {
+ converter_out = gst_caps_get_int (*caps, "rate");
+ return gst_pad_negotiate_proxy (srcconvpad, caps, counter);
+ }
+ return GST_PAD_NEGOTIATE_AGREE;
+ }
+
+ return GST_PAD_NEGOTIATE_FAIL;
+}
+
+static GstPadNegotiateReturn
+target_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
+{
+ g_print ("{");
+ if (counter == 0) {
+ *caps = gst_caps_new_with_props (
+ "target_caps",
+ "audio/raw",
+ gst_props_new (
+ "rate", GST_PROPS_INT (target_rate),
+ NULL)
+ );
+ return GST_PAD_NEGOTIATE_TRY;
+ }
+ if (*caps) {
+ target_rate = gst_caps_get_int (*caps, "rate");
+ g_print ("target set %d\n", target_rate);
+ return GST_PAD_NEGOTIATE_AGREE;
+ }
+
+ return GST_PAD_NEGOTIATE_FAIL;
+}
+
+int
+main (int argc, char *argv[])
+{
+ gboolean overall = TRUE;
+ gboolean result;
+
+ gst_init (&argc, &argv);
+
+ srctempl = gst_padtemplate_new (&src_factory);
+ sinktempl = gst_padtemplate_new (&sink_factory);
+ srcpad = gst_pad_new_from_template (srctempl, "src");
+ sinkpad = gst_pad_new_from_template (sinktempl, "sink");
+
+ srcconvtempl = gst_padtemplate_new (&src_conv_factory);
+ sinkconvtempl = gst_padtemplate_new (&sink_conv_factory);
+ srcconvpad = gst_pad_new_from_template (srcconvtempl, "csrc");
+ sinkconvpad = gst_pad_new_from_template (sinkconvtempl, "csink");
+
+ gst_pad_set_negotiate_function (srcconvpad, converter_negotiate_src);
+ gst_pad_set_negotiate_function (sinkconvpad, converter_negotiate_sink);
+ gst_pad_set_negotiate_function (sinkpad, target_negotiate_sink);
+
+ sinkcaps = gst_caps_register (&sink_caps);
+ srccaps = gst_caps_register (&src_caps);
+
+ g_print ("-------) (-----------) (----- \n");
+ g_print (" ! ! converter ! ! \n");
+ g_print (" src -- csink csrc -- sink \n");
+ g_print ("-------) (-----------) (----- \n\n");
+ g_print ("The convertor first tries to proxy the caps received\n");
+ g_print ("on its csink pad to its csrc pad, when that fails, it\n");
+ g_print ("sets up the conversion.\n\n");
+
+
+ g_print ("sink pad set caps (rate=%d), converter status: %d %d\n", target_rate,
+ converter_in, converter_out);
+ gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (target_rate));
+ result = gst_pad_set_caps (sinkpad, sinkcaps);
+ g_print ("result: %d, converter status: %d %d, target: %d\n\n", result,
+ converter_in, converter_out, target_rate);
+
+ result = gst_pad_connect (srcpad, sinkconvpad);
+ g_print ("pad connect 1: %d\n", result);
+ overall &= (result == TRUE);
+ result = gst_pad_connect (srcconvpad, sinkpad);
+ g_print ("pad connect 2: %d\n", result);
+ overall &= (result == TRUE);
+
+ g_print ("after connect, converter status: %d %d, target %d\n\n", converter_in, converter_out, target_rate);
+
+ g_print ("src pad set caps (rate=%d), converter status: %d %d, target %d \n", gst_caps_get_int (srccaps, "rate"),
+ converter_in, converter_out, target_rate);
+ result = gst_pad_set_caps (srcpad, srccaps);
+ g_print ("result %d, converter status: %d %d, target %d\n\n", result,
+ converter_in, converter_out, target_rate);
+
+ g_print ("sink pad set caps (rate=2000), converter status: %d %d, target %d \n",
+ converter_in, converter_out, target_rate);
+ target_rate = 2000;
+ gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (target_rate));
+ result = gst_pad_set_caps (sinkpad, sinkcaps);
+ g_print ("result %d, converter status: %d %d, target: %d\n\n", result,
+ converter_in, converter_out, target_rate);
+
+ gst_caps_set (srccaps, "rate", GST_PROPS_INT (4000));
+ result = gst_pad_renegotiate (srcpad);
+ g_print ("sink pad renegotiate caps %d, converter status: %d %d, target: %d\n", result,
+ converter_in, converter_out, target_rate);
+
+ gst_caps_set (srccaps, "rate", GST_PROPS_INT (40000));
+ result = gst_pad_set_caps (srcpad, srccaps);
+ g_print ("sink pad set caps %d, converter status: %d %d, target: %d\n", result,
+ converter_in, converter_out, target_rate);
+
+ gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (40000));
+ result = gst_pad_set_caps (sinkpad, sinkcaps);
+ g_print ("sink pad set caps %d, converter status: %d %d, target: %d\n", result,
+ converter_in, converter_out, target_rate);
+
+ target_rate = 9000;
+ gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (target_rate));
+ result = gst_pad_set_caps (sinkpad, sinkcaps);
+ g_print ("sink pad set caps %d, converter status: %d %d, target: %d\n", result,
+ converter_in, converter_out, target_rate);
+
+ exit (!overall);
+}