mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 11:41:09 +00:00
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:
parent
22c6305b00
commit
29cb713b21
10 changed files with 606 additions and 71 deletions
|
@ -140,8 +140,8 @@ gst_autoplug_pads_autoplug_func (GstElement *src, GstPad *pad, GstElement *sink)
|
|||
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) {
|
||||
|
|
163
gst/gstpad.c
163
gst/gstpad.c
|
@ -737,6 +737,12 @@ gst_pad_set_caps (GstPad *pad,
|
|||
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);
|
||||
|
@ -920,6 +926,80 @@ cleanup:
|
|||
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:
|
||||
* @pad: the pad to perform the negotiation on
|
||||
|
@ -931,11 +1011,10 @@ cleanup:
|
|||
gboolean
|
||||
gst_pad_renegotiate (GstPad *pad)
|
||||
{
|
||||
gint counter = 0;
|
||||
GstCaps *newcaps = NULL;
|
||||
GstRealPad *peerpad, *currentpad, *otherpad;
|
||||
GstPadDirection currentdirection;
|
||||
GstPadNegotiateReturn result;
|
||||
gboolean result;
|
||||
gint counter = 0;
|
||||
|
||||
g_return_val_if_fail (pad != NULL, FALSE);
|
||||
|
||||
|
@ -957,80 +1036,46 @@ gst_pad_renegotiate (GstPad *pad)
|
|||
newcaps = GST_PAD_CAPS (pad);
|
||||
g_assert (newcaps != NULL);
|
||||
|
||||
currentdirection = GST_PAD_DIRECTION (currentpad);
|
||||
result = gst_pad_renegotiate_func (pad, GST_PAD (peerpad), &newcaps, &counter);
|
||||
|
||||
do {
|
||||
gboolean matchtempl;
|
||||
if (result) {
|
||||
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) {
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -153,23 +153,43 @@ gst_queue_init (GstQueue *queue)
|
|||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -153,23 +153,43 @@ gst_queue_init (GstQueue *queue)
|
|||
}
|
||||
|
||||
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
|
||||
|
|
1
tests/old/testsuite/capsnego/.gitignore
vendored
1
tests/old/testsuite/capsnego/.gitignore
vendored
|
@ -7,3 +7,4 @@ Makefile.in
|
|||
.libs
|
||||
capsnego
|
||||
converter
|
||||
converter2
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
SUBDIRS =
|
||||
|
||||
testprogs = capsnego converter
|
||||
testprogs = capsnego converter converter2
|
||||
|
||||
TESTS = $(testprogs)
|
||||
|
||||
|
|
224
tests/old/testsuite/capsnego/converter2.c
Normal file
224
tests/old/testsuite/capsnego/converter2.c
Normal 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);
|
||||
}
|
1
testsuite/capsnego/.gitignore
vendored
1
testsuite/capsnego/.gitignore
vendored
|
@ -7,3 +7,4 @@ Makefile.in
|
|||
.libs
|
||||
capsnego
|
||||
converter
|
||||
converter2
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
SUBDIRS =
|
||||
|
||||
testprogs = capsnego converter
|
||||
testprogs = capsnego converter converter2
|
||||
|
||||
TESTS = $(testprogs)
|
||||
|
||||
|
|
224
testsuite/capsnego/converter2.c
Normal file
224
testsuite/capsnego/converter2.c
Normal 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);
|
||||
}
|
Loading…
Reference in a new issue