More work on capsnego, mostly proxying

Original commit message from CVS:
More work on capsnego, mostly proxying
Added another testsuite for capsnego
Added caps to vorbisdec, mp3parse, mp1videoparse
Redid the queue proxy handling a bit.
This commit is contained in:
Wim Taymans 2001-03-18 16:17:39 +00:00
parent 22c6305b00
commit 29cb713b21
10 changed files with 606 additions and 71 deletions

View file

@ -140,8 +140,8 @@ gst_autoplug_pads_autoplug_func (GstElement *src, GstPad *pad, GstElement *sink)
GList *sinkpads; GList *sinkpads;
gboolean connected = FALSE; gboolean connected = FALSE;
GST_DEBUG (0,"gstpipeline: autoplug pad connect function for \"%s\" to \"%s\"\n", GST_DEBUG (0,"gstpipeline: autoplug pad connect function for %s %s:%s to \"%s\"\n",
GST_ELEMENT_NAME(src), GST_ELEMENT_NAME(sink)); GST_ELEMENT_NAME (src), GST_DEBUG_PAD_NAME(pad), GST_ELEMENT_NAME(sink));
sinkpads = gst_element_get_pad_list(sink); sinkpads = gst_element_get_pad_list(sink);
while (sinkpads) { while (sinkpads) {

View file

@ -737,6 +737,12 @@ gst_pad_set_caps (GstPad *pad,
g_return_val_if_fail (pad != NULL, FALSE); g_return_val_if_fail (pad != NULL, FALSE);
g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE); // NOTE this restriction 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; GST_PAD_CAPS(pad) = caps;
return gst_pad_renegotiate (pad); return gst_pad_renegotiate (pad);
@ -920,6 +926,80 @@ cleanup:
g_strfreev (split); g_strfreev (split);
} }
static gboolean
gst_pad_renegotiate_func (GstPad *pad, GstPad *peerpad, GstCaps **newcaps, gint *counter)
{
GstRealPad *currentpad, *otherpad;
GstPadNegotiateReturn result;
g_return_val_if_fail (pad != NULL, FALSE);
currentpad = GST_PAD_REALIZE (pad);
otherpad = GST_REAL_PAD (peerpad);
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)));
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))) {
GST_DEBUG (GST_CAT_ELEMENT_PADS, "negotiation succeeded\n");
return TRUE;
}
else {
*newcaps = GST_PAD_CAPS (otherpad);
}
}
else {
*newcaps = GST_PAD_CAPS (otherpad);
}
(*counter)++;
if (currentpad->negotiatefunc) {
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:
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);
GST_DEBUG (GST_CAT_ELEMENT_PADS, "negotiation failed, too many attempts\n");
return FALSE;
}
/** /**
* gst_pad_renegotiate: * gst_pad_renegotiate:
* @pad: the pad to perform the negotiation on * @pad: the pad to perform the negotiation on
@ -931,11 +1011,10 @@ cleanup:
gboolean gboolean
gst_pad_renegotiate (GstPad *pad) gst_pad_renegotiate (GstPad *pad)
{ {
gint counter = 0;
GstCaps *newcaps = NULL; GstCaps *newcaps = NULL;
GstRealPad *peerpad, *currentpad, *otherpad; GstRealPad *peerpad, *currentpad, *otherpad;
GstPadDirection currentdirection; gboolean result;
GstPadNegotiateReturn result; gint counter = 0;
g_return_val_if_fail (pad != NULL, FALSE); g_return_val_if_fail (pad != NULL, FALSE);
@ -957,80 +1036,46 @@ gst_pad_renegotiate (GstPad *pad)
newcaps = GST_PAD_CAPS (pad); newcaps = GST_PAD_CAPS (pad);
g_assert (newcaps != NULL); g_assert (newcaps != NULL);
currentdirection = GST_PAD_DIRECTION (currentpad); result = gst_pad_renegotiate_func (pad, GST_PAD (peerpad), &newcaps, &counter);
do { if (result) {
gboolean matchtempl; GST_DEBUG (GST_CAT_ELEMENT_PADS, "pads aggreed on caps :)\n");
matchtempl = gst_caps_check_compatibility (newcaps, gst_pad_get_padtemplate_caps (GST_PAD (otherpad))); /* here we have some sort of aggreement of the caps */
GST_PAD_CAPS (currentpad) = newcaps;
GST_PAD_CAPS (otherpad) = newcaps;
}
if (matchtempl) { return result;
if (otherpad->negotiatefunc) {
GstRealPad *temp;
temp = currentpad;
currentpad = otherpad;
otherpad = temp;
}
else if (gst_caps_check_compatibility (newcaps, GST_PAD_CAPS (otherpad))) {
break;
}
else {
newcaps = GST_PAD_CAPS (otherpad);
}
}
else {
newcaps = GST_PAD_CAPS (otherpad);
}
counter++;
if (currentpad->negotiatefunc) {
result = currentpad->negotiatefunc (GST_PAD (currentpad), &newcaps, counter);
switch (result) {
case GST_PAD_NEGOTIATE_FAIL:
return FALSE;
case GST_PAD_NEGOTIATE_AGREE:
goto succeed;
case GST_PAD_NEGOTIATE_TRY:
break;
}
}
else {
return FALSE;
}
} while (counter < 100);
succeed:
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 TRUE;
} }
GstPadNegotiateReturn GstPadNegotiateReturn
gst_pad_negotiate_proxy (GstPad *pad, GstCaps **caps, gint counter) gst_pad_negotiate_proxy (GstPad *pad, GstCaps **caps, gint counter)
{ {
GstRealPad *peer; GstRealPad *peer;
gboolean result;
g_return_val_if_fail (pad != NULL, GST_PAD_NEGOTIATE_FAIL); 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); peer = GST_RPAD_PEER (pad);
//GST_PAD_CAPS (pad) = caps; //GST_PAD_CAPS (pad) = caps;
if (peer) { if (peer) {
if (peer->negotiatefunc) { result = gst_pad_renegotiate_func (pad, GST_PAD (peer), caps, &counter);
GST_DEBUG (GST_CAT_ELEMENT_PADS, "calling negotiate on peer (%s:%s)\n", GST_DEBUG_PAD_NAME (peer));
return peer->negotiatefunc (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;
} }
} }

View file

@ -153,23 +153,43 @@ gst_queue_init (GstQueue *queue)
} }
static GstPadNegotiateReturn 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; GstQueue *queue;
queue = GST_QUEUE (GST_OBJECT_PARENT (pad)); 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 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; GstQueue *queue;
queue = GST_QUEUE (GST_OBJECT_PARENT (pad)); 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 gboolean

View file

@ -153,23 +153,43 @@ gst_queue_init (GstQueue *queue)
} }
static GstPadNegotiateReturn 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; GstQueue *queue;
queue = GST_QUEUE (GST_OBJECT_PARENT (pad)); 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 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; GstQueue *queue;
queue = GST_QUEUE (GST_OBJECT_PARENT (pad)); 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 gboolean

View file

@ -7,3 +7,4 @@ Makefile.in
.libs .libs
capsnego capsnego
converter converter
converter2

View file

@ -1,6 +1,6 @@
SUBDIRS = SUBDIRS =
testprogs = capsnego converter testprogs = capsnego converter converter2
TESTS = $(testprogs) TESTS = $(testprogs)

View file

@ -0,0 +1,224 @@
#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);
}

View file

@ -7,3 +7,4 @@ Makefile.in
.libs .libs
capsnego capsnego
converter converter
converter2

View file

@ -1,6 +1,6 @@
SUBDIRS = SUBDIRS =
testprogs = capsnego converter testprogs = capsnego converter converter2
TESTS = $(testprogs) TESTS = $(testprogs)

View file

@ -0,0 +1,224 @@
#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);
}