mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 03:31:05 +00:00
Merged the CAPSNEGO1 branch..
Original commit message from CVS: Merged the CAPSNEGO1 branch..
This commit is contained in:
parent
db74410739
commit
3ec275832a
26 changed files with 661 additions and 292 deletions
|
@ -770,6 +770,7 @@ tests/Makefile
|
||||||
tests/sched/Makefile
|
tests/sched/Makefile
|
||||||
tests/eos/Makefile
|
tests/eos/Makefile
|
||||||
testsuite/Makefile
|
testsuite/Makefile
|
||||||
|
tests/nego/Makefile
|
||||||
examples/Makefile
|
examples/Makefile
|
||||||
examples/autoplug/Makefile
|
examples/autoplug/Makefile
|
||||||
examples/helloworld/Makefile
|
examples/helloworld/Makefile
|
||||||
|
|
|
@ -128,7 +128,7 @@ the element when it knows the values for the caps.
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
when two pads are connected the following steps will take
|
when two pads are connected the following steps will take
|
||||||
placei (not sure, FIXME):
|
place (not sure, FIXME):
|
||||||
|
|
||||||
- if both pads have caps, the caps are checked. If the caps
|
- if both pads have caps, the caps are checked. If the caps
|
||||||
are incompatible, the padtemplates are checked, if they
|
are incompatible, the padtemplates are checked, if they
|
||||||
|
|
|
@ -329,14 +329,14 @@ gst_editor_pads_create (GstEditorProperty *property, GstEditorElement *element)
|
||||||
|
|
||||||
while (pads) {
|
while (pads) {
|
||||||
GstPad *pad = (GstPad *)pads->data;
|
GstPad *pad = (GstPad *)pads->data;
|
||||||
GList *caps = gst_pad_get_caps_list (pad);
|
GstCaps *caps = gst_pad_get_caps (pad);
|
||||||
gchar *mime;
|
gchar *mime;
|
||||||
gchar *data[2];
|
gchar *data[2];
|
||||||
GtkCTreeNode *padnode;
|
GtkCTreeNode *padnode;
|
||||||
|
|
||||||
if (caps) {
|
if (caps) {
|
||||||
GstType *type;
|
GstType *type;
|
||||||
type = gst_type_find_by_id (((GstCaps *)caps->data)->id);
|
type = gst_type_find_by_id (caps->id);
|
||||||
mime = type->mime;
|
mime = type->mime;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -348,13 +348,8 @@ gst_editor_pads_create (GstEditorProperty *property, GstEditorElement *element)
|
||||||
padnode = gtk_ctree_insert_node (GTK_CTREE (tree), NULL, NULL, data, 0,
|
padnode = gtk_ctree_insert_node (GTK_CTREE (tree), NULL, NULL, data, 0,
|
||||||
NULL, NULL, NULL, NULL, FALSE, TRUE);
|
NULL, NULL, NULL, NULL, FALSE, TRUE);
|
||||||
|
|
||||||
while (caps) {
|
|
||||||
GstCaps *cap = (GstCaps *)caps->data;
|
|
||||||
|
|
||||||
gst_editor_add_caps_to_tree (cap, tree, padnode);
|
gst_editor_add_caps_to_tree (caps, tree, padnode);
|
||||||
|
|
||||||
caps = g_list_next (caps);
|
|
||||||
}
|
|
||||||
|
|
||||||
pads = g_list_next (pads);
|
pads = g_list_next (pads);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ static GList* gst_autoplug_func (gpointer src, gpointer sink,
|
||||||
|
|
||||||
|
|
||||||
static GstElement* gst_static_autoplug_to_caps (GstAutoplug *autoplug,
|
static GstElement* gst_static_autoplug_to_caps (GstAutoplug *autoplug,
|
||||||
GList *srccaps, GList *sinkcaps, va_list args);
|
GstCaps *srccaps, GstCaps *sinkcaps, va_list args);
|
||||||
|
|
||||||
static GstAutoplugClass *parent_class = NULL;
|
static GstAutoplugClass *parent_class = NULL;
|
||||||
|
|
||||||
|
@ -118,7 +118,8 @@ gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest)
|
||||||
|
|
||||||
if (srctemp->direction == GST_PAD_SRC &&
|
if (srctemp->direction == GST_PAD_SRC &&
|
||||||
desttemp->direction == GST_PAD_SINK) {
|
desttemp->direction == GST_PAD_SINK) {
|
||||||
if (gst_caps_list_check_compatibility (srctemp->caps, desttemp->caps)) {
|
if (gst_caps_check_compatibility (gst_padtemplate_get_caps (srctemp),
|
||||||
|
gst_padtemplate_get_caps (desttemp))) {
|
||||||
GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,
|
GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,
|
||||||
"factory \"%s\" can connect with factory \"%s\"", src->name, dest->name);
|
"factory \"%s\" can connect with factory \"%s\"", src->name, dest->name);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -151,7 +152,7 @@ gst_autoplug_pads_autoplug_func (GstElement *src, GstPad *pad, GstElement *sink)
|
||||||
if (gst_pad_get_direction(sinkpad) == GST_PAD_SINK &&
|
if (gst_pad_get_direction(sinkpad) == GST_PAD_SINK &&
|
||||||
!GST_PAD_CONNECTED(sinkpad))
|
!GST_PAD_CONNECTED(sinkpad))
|
||||||
{
|
{
|
||||||
if (gst_caps_list_check_compatibility (gst_pad_get_caps_list(pad), gst_pad_get_caps_list(sinkpad))) {
|
if (gst_caps_check_compatibility (gst_pad_get_caps(pad), gst_pad_get_caps(sinkpad))) {
|
||||||
gst_pad_connect(pad, sinkpad);
|
gst_pad_connect(pad, sinkpad);
|
||||||
GST_DEBUG (0,"gstpipeline: autoconnect pad \"%s\" in element %s <-> ", GST_PAD_NAME (pad),
|
GST_DEBUG (0,"gstpipeline: autoconnect pad \"%s\" in element %s <-> ", GST_PAD_NAME (pad),
|
||||||
GST_ELEMENT_NAME(src));
|
GST_ELEMENT_NAME(src));
|
||||||
|
@ -175,7 +176,7 @@ gst_autoplug_pads_autoplug_func (GstElement *src, GstPad *pad, GstElement *sink)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GstElement *result;
|
GstElement *result;
|
||||||
GList *endcap;
|
GstCaps *endcap;
|
||||||
gint i;
|
gint i;
|
||||||
} dynamic_pad_struct;
|
} dynamic_pad_struct;
|
||||||
|
|
||||||
|
@ -190,9 +191,10 @@ autoplug_dynamic_pad (GstElement *element, GstPad *pad, gpointer data)
|
||||||
|
|
||||||
while (pads) {
|
while (pads) {
|
||||||
GstPad *pad = GST_PAD (pads->data);
|
GstPad *pad = GST_PAD (pads->data);
|
||||||
|
GstPadTemplate *templ = GST_PAD_PADTEMPLATE (pad);
|
||||||
pads = g_list_next (pads);
|
pads = g_list_next (pads);
|
||||||
|
|
||||||
if (gst_caps_list_check_compatibility (gst_pad_get_caps_list (pad), info->endcap)) {
|
if (gst_caps_check_compatibility (GST_PADTEMPLATE_CAPS (templ), info->endcap)) {
|
||||||
gst_element_add_ghost_pad (info->result, pad, g_strdup_printf("src_%02d", info->i));
|
gst_element_add_ghost_pad (info->result, pad, g_strdup_printf("src_%02d", info->i));
|
||||||
GST_DEBUG (0,"gstpipeline: new dynamic pad %s\n", GST_PAD_NAME (pad));
|
GST_DEBUG (0,"gstpipeline: new dynamic pad %s\n", GST_PAD_NAME (pad));
|
||||||
break;
|
break;
|
||||||
|
@ -232,8 +234,8 @@ gst_autoplug_elementfactory_get_list (gpointer data)
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GList *src;
|
GstCaps *src;
|
||||||
GList *sink;
|
GstCaps *sink;
|
||||||
} caps_struct;
|
} caps_struct;
|
||||||
|
|
||||||
#define IS_CAPS(cap) (((cap) == caps->src) || (cap) == caps->sink)
|
#define IS_CAPS(cap) (((cap) == caps->src) || (cap) == caps->sink)
|
||||||
|
@ -245,16 +247,13 @@ gst_autoplug_caps_find_cost (gpointer src, gpointer dest, gpointer data)
|
||||||
gboolean res;
|
gboolean res;
|
||||||
|
|
||||||
if (IS_CAPS (src) && IS_CAPS (dest)) {
|
if (IS_CAPS (src) && IS_CAPS (dest)) {
|
||||||
res = gst_caps_list_check_compatibility ((GList *)src, (GList *)dest);
|
res = gst_caps_check_compatibility ((GstCaps *)src, (GstCaps *)dest);
|
||||||
//GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"caps %d to caps %d %d", ((GstCaps *)src)->id, ((GstCaps *)dest)->id, res);
|
|
||||||
}
|
}
|
||||||
else if (IS_CAPS (src)) {
|
else if (IS_CAPS (src)) {
|
||||||
res = gst_elementfactory_can_sink_caps_list ((GstElementFactory *)dest, (GList *)src);
|
res = gst_elementfactory_can_sink_caps ((GstElementFactory *)dest, (GstCaps *)src);
|
||||||
//GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory %s to src caps %d %d", ((GstElementFactory *)dest)->name, ((GstCaps *)src)->id, res);
|
|
||||||
}
|
}
|
||||||
else if (IS_CAPS (dest)) {
|
else if (IS_CAPS (dest)) {
|
||||||
res = gst_elementfactory_can_src_caps_list ((GstElementFactory *)src, (GList *)dest);
|
res = gst_elementfactory_can_src_caps ((GstElementFactory *)src, (GstCaps *)dest);
|
||||||
//GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory %s to sink caps %d %d", ((GstElementFactory *)src)->name, ((GstCaps *)dest)->id, res);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
res = gst_autoplug_can_match ((GstElementFactory *)src, (GstElementFactory *)dest);
|
res = gst_autoplug_can_match ((GstElementFactory *)src, (GstElementFactory *)dest);
|
||||||
|
@ -267,10 +266,10 @@ gst_autoplug_caps_find_cost (gpointer src, gpointer dest, gpointer data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstElement*
|
static GstElement*
|
||||||
gst_static_autoplug_to_caps (GstAutoplug *autoplug, GList *srccaps, GList *sinkcaps, va_list args)
|
gst_static_autoplug_to_caps (GstAutoplug *autoplug, GstCaps *srccaps, GstCaps *sinkcaps, va_list args)
|
||||||
{
|
{
|
||||||
caps_struct caps;
|
caps_struct caps;
|
||||||
GList *capslist;
|
GstCaps *capslist;
|
||||||
GstElement *result = NULL, *srcelement = NULL;
|
GstElement *result = NULL, *srcelement = NULL;
|
||||||
GList **factories;
|
GList **factories;
|
||||||
GList *chains = NULL;
|
GList *chains = NULL;
|
||||||
|
@ -307,7 +306,7 @@ gst_static_autoplug_to_caps (GstAutoplug *autoplug, GList *srccaps, GList *sinkc
|
||||||
else {
|
else {
|
||||||
}
|
}
|
||||||
|
|
||||||
capslist = va_arg (args, GList *);
|
capslist = va_arg (args, GstCaps *);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -376,8 +375,9 @@ gst_static_autoplug_to_caps (GstAutoplug *autoplug, GList *srccaps, GList *sinkc
|
||||||
|
|
||||||
while (pads) {
|
while (pads) {
|
||||||
GstPad *pad = GST_PAD (pads->data);
|
GstPad *pad = GST_PAD (pads->data);
|
||||||
|
GstPadTemplate *templ = GST_PAD_PADTEMPLATE (pad);
|
||||||
|
|
||||||
if (gst_caps_list_check_compatibility (srccaps, gst_pad_get_caps_list (pad))) {
|
if (gst_caps_check_compatibility (srccaps, GST_PADTEMPLATE_CAPS (templ))) {
|
||||||
gst_element_add_ghost_pad (result, pad, "sink");
|
gst_element_add_ghost_pad (result, pad, "sink");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -430,7 +430,7 @@ differ:
|
||||||
* find a suitable pad to turn into a ghostpad
|
* find a suitable pad to turn into a ghostpad
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
GList *endcap = (GList *)(endcaps->data);
|
GstCaps *endcap = (GstCaps *)(endcaps->data);
|
||||||
GList *pads = gst_element_get_pad_list (thesrcelement);
|
GList *pads = gst_element_get_pad_list (thesrcelement);
|
||||||
gboolean have_pad = FALSE;
|
gboolean have_pad = FALSE;
|
||||||
endcaps = g_list_next (endcaps);
|
endcaps = g_list_next (endcaps);
|
||||||
|
@ -439,9 +439,10 @@ differ:
|
||||||
|
|
||||||
while (pads) {
|
while (pads) {
|
||||||
GstPad *pad = GST_PAD (pads->data);
|
GstPad *pad = GST_PAD (pads->data);
|
||||||
|
GstPadTemplate *templ = GST_PAD_PADTEMPLATE (pad);
|
||||||
pads = g_list_next (pads);
|
pads = g_list_next (pads);
|
||||||
|
|
||||||
if (gst_caps_list_check_compatibility (gst_pad_get_caps_list (pad), endcap)) {
|
if (gst_caps_check_compatibility (GST_PADTEMPLATE_CAPS (templ), endcap)) {
|
||||||
gst_element_add_ghost_pad (result, pad, g_strdup_printf("src_%02d", i));
|
gst_element_add_ghost_pad (result, pad, g_strdup_printf("src_%02d", i));
|
||||||
have_pad = TRUE;
|
have_pad = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -41,7 +41,7 @@ static GList* gst_autoplug_func (gpointer src, gpointer sink,
|
||||||
|
|
||||||
|
|
||||||
static GstElement* gst_static_autoplug_to_render (GstAutoplug *autoplug,
|
static GstElement* gst_static_autoplug_to_render (GstAutoplug *autoplug,
|
||||||
GList *srccaps, GstElement *target, va_list args);
|
GstCaps *srccaps, GstElement *target, va_list args);
|
||||||
|
|
||||||
static GstAutoplugClass *parent_class = NULL;
|
static GstAutoplugClass *parent_class = NULL;
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest)
|
||||||
|
|
||||||
if (srctemp->direction == GST_PAD_SRC &&
|
if (srctemp->direction == GST_PAD_SRC &&
|
||||||
desttemp->direction == GST_PAD_SINK) {
|
desttemp->direction == GST_PAD_SINK) {
|
||||||
if (gst_caps_list_check_compatibility (srctemp->caps, desttemp->caps)) {
|
if (gst_caps_check_compatibility (GST_PADTEMPLATE_CAPS (srctemp), GST_PADTEMPLATE_CAPS (desttemp))) {
|
||||||
GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,
|
GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,
|
||||||
"factory \"%s\" can connect with factory \"%s\"", src->name, dest->name);
|
"factory \"%s\" can connect with factory \"%s\"", src->name, dest->name);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -149,15 +149,9 @@ gst_autoplug_pads_autoplug_func (GstElement *src, GstPad *pad, GstElement *sink)
|
||||||
|
|
||||||
// if we have a match, connect the pads
|
// if we have a match, connect the pads
|
||||||
if (gst_pad_get_direction(sinkpad) == GST_PAD_SINK &&
|
if (gst_pad_get_direction(sinkpad) == GST_PAD_SINK &&
|
||||||
!GST_PAD_CONNECTED(sinkpad))
|
!GST_PAD_CONNECTED (pad) && !GST_PAD_CONNECTED(sinkpad))
|
||||||
{
|
{
|
||||||
if (gst_caps_list_check_compatibility (gst_pad_get_caps_list(pad), gst_pad_get_caps_list(sinkpad))) {
|
if ((connected = gst_pad_connect (pad, sinkpad))) {
|
||||||
gst_pad_connect(pad, sinkpad);
|
|
||||||
GST_DEBUG (0,"gstpipeline: autoconnect pad \"%s\" in element %s <-> ", GST_PAD_NAME (pad),
|
|
||||||
GST_ELEMENT_NAME(src));
|
|
||||||
GST_DEBUG (0,"pad \"%s\" in element %s\n", GST_PAD_NAME (sinkpad),
|
|
||||||
GST_ELEMENT_NAME(sink));
|
|
||||||
connected = TRUE;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -173,33 +167,6 @@ gst_autoplug_pads_autoplug_func (GstElement *src, GstPad *pad, GstElement *sink)
|
||||||
return connected;
|
return connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
GstElement *result;
|
|
||||||
GList *endcap;
|
|
||||||
gint i;
|
|
||||||
} dynamic_pad_struct;
|
|
||||||
|
|
||||||
static void
|
|
||||||
autoplug_dynamic_pad (GstElement *element, GstPad *pad, gpointer data)
|
|
||||||
{
|
|
||||||
dynamic_pad_struct *info = (dynamic_pad_struct *)data;
|
|
||||||
GList *pads = gst_element_get_pad_list (element);
|
|
||||||
|
|
||||||
GST_DEBUG (0,"attempting to dynamically create a ghostpad for %s=%s\n", GST_ELEMENT_NAME (element),
|
|
||||||
GST_PAD_NAME (pad));
|
|
||||||
|
|
||||||
while (pads) {
|
|
||||||
GstPad *pad = GST_PAD (pads->data);
|
|
||||||
pads = g_list_next (pads);
|
|
||||||
|
|
||||||
if (gst_caps_list_check_compatibility (gst_pad_get_caps_list (pad), info->endcap)) {
|
|
||||||
gst_element_add_ghost_pad (info->result, pad, g_strdup_printf("src_%02d", info->i));
|
|
||||||
GST_DEBUG (0,"gstpipeline: new dynamic pad %s\n", GST_PAD_NAME (pad));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_autoplug_pads_autoplug (GstElement *src, GstElement *sink)
|
gst_autoplug_pads_autoplug (GstElement *src, GstElement *sink)
|
||||||
{
|
{
|
||||||
|
@ -211,8 +178,11 @@ gst_autoplug_pads_autoplug (GstElement *src, GstElement *sink)
|
||||||
while (srcpads && !connected) {
|
while (srcpads && !connected) {
|
||||||
GstPad *srcpad = (GstPad *)srcpads->data;
|
GstPad *srcpad = (GstPad *)srcpads->data;
|
||||||
|
|
||||||
if (gst_pad_get_direction(srcpad) == GST_PAD_SRC)
|
if (gst_pad_get_direction(srcpad) == GST_PAD_SRC) {
|
||||||
connected = gst_autoplug_pads_autoplug_func (src, srcpad, sink);
|
connected = gst_autoplug_pads_autoplug_func (src, srcpad, sink);
|
||||||
|
if (connected)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
srcpads = g_list_next(srcpads);
|
srcpads = g_list_next(srcpads);
|
||||||
}
|
}
|
||||||
|
@ -234,8 +204,8 @@ gst_autoplug_elementfactory_get_list (gpointer data)
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GList *src;
|
GstCaps *src;
|
||||||
GList *sink;
|
GstCaps *sink;
|
||||||
} caps_struct;
|
} caps_struct;
|
||||||
|
|
||||||
#define IS_CAPS(cap) (((cap) == caps->src) || (cap) == caps->sink)
|
#define IS_CAPS(cap) (((cap) == caps->src) || (cap) == caps->sink)
|
||||||
|
@ -247,15 +217,15 @@ gst_autoplug_caps_find_cost (gpointer src, gpointer dest, gpointer data)
|
||||||
gboolean res;
|
gboolean res;
|
||||||
|
|
||||||
if (IS_CAPS (src) && IS_CAPS (dest)) {
|
if (IS_CAPS (src) && IS_CAPS (dest)) {
|
||||||
res = gst_caps_list_check_compatibility ((GList *)src, (GList *)dest);
|
res = gst_caps_check_compatibility ((GstCaps *)src, (GstCaps *)dest);
|
||||||
//GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"caps %d to caps %d %d", ((GstCaps *)src)->id, ((GstCaps *)dest)->id, res);
|
//GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"caps %d to caps %d %d", ((GstCaps *)src)->id, ((GstCaps *)dest)->id, res);
|
||||||
}
|
}
|
||||||
else if (IS_CAPS (src)) {
|
else if (IS_CAPS (src)) {
|
||||||
res = gst_elementfactory_can_sink_caps_list ((GstElementFactory *)dest, (GList *)src);
|
res = gst_elementfactory_can_sink_caps ((GstElementFactory *)dest, (GstCaps *)src);
|
||||||
//GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory %s to src caps %d %d", ((GstElementFactory *)dest)->name, ((GstCaps *)src)->id, res);
|
//GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory %s to src caps %d %d", ((GstElementFactory *)dest)->name, ((GstCaps *)src)->id, res);
|
||||||
}
|
}
|
||||||
else if (IS_CAPS (dest)) {
|
else if (IS_CAPS (dest)) {
|
||||||
res = gst_elementfactory_can_src_caps_list ((GstElementFactory *)src, (GList *)dest);
|
res = gst_elementfactory_can_src_caps ((GstElementFactory *)src, (GstCaps *)dest);
|
||||||
//GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory %s to sink caps %d %d", ((GstElementFactory *)src)->name, ((GstCaps *)dest)->id, res);
|
//GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory %s to sink caps %d %d", ((GstElementFactory *)src)->name, ((GstCaps *)dest)->id, res);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -269,7 +239,7 @@ gst_autoplug_caps_find_cost (gpointer src, gpointer dest, gpointer data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstElement*
|
static GstElement*
|
||||||
gst_static_autoplug_to_render (GstAutoplug *autoplug, GList *srccaps, GstElement *target, va_list args)
|
gst_static_autoplug_to_render (GstAutoplug *autoplug, GstCaps *srccaps, GstElement *target, va_list args)
|
||||||
{
|
{
|
||||||
caps_struct caps;
|
caps_struct caps;
|
||||||
GstElement *targetelement;
|
GstElement *targetelement;
|
||||||
|
@ -292,10 +262,12 @@ gst_static_autoplug_to_render (GstAutoplug *autoplug, GList *srccaps, GstElement
|
||||||
while (targetelement) {
|
while (targetelement) {
|
||||||
GList *elements;
|
GList *elements;
|
||||||
GstPad *pad;
|
GstPad *pad;
|
||||||
|
GstPadTemplate *templ;
|
||||||
|
|
||||||
pad = GST_PAD (gst_element_get_pad_list (targetelement)->data);
|
pad = GST_PAD (gst_element_get_pad_list (targetelement)->data);
|
||||||
|
templ = GST_PAD_PADTEMPLATE (pad);
|
||||||
|
|
||||||
caps.sink = gst_pad_get_caps_list (pad);
|
caps.sink = GST_PADTEMPLATE_CAPS (templ);
|
||||||
|
|
||||||
GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"autoplugging two caps structures");
|
GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"autoplugging two caps structures");
|
||||||
|
|
||||||
|
@ -381,8 +353,9 @@ gst_static_autoplug_to_render (GstAutoplug *autoplug, GList *srccaps, GstElement
|
||||||
|
|
||||||
while (pads) {
|
while (pads) {
|
||||||
GstPad *pad = GST_PAD (pads->data);
|
GstPad *pad = GST_PAD (pads->data);
|
||||||
|
GstPadTemplate *templ = GST_PAD_PADTEMPLATE (pad);
|
||||||
|
|
||||||
if (gst_caps_list_check_compatibility (srccaps, gst_pad_get_caps_list (pad))) {
|
if (gst_caps_check_compatibility (srccaps, GST_PADTEMPLATE_CAPS (templ))) {
|
||||||
gst_element_add_ghost_pad (result, pad, "sink");
|
gst_element_add_ghost_pad (result, pad, "sink");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -435,8 +408,7 @@ differ:
|
||||||
// this element suggests the use of a thread, so we set one up...
|
// this element suggests the use of a thread, so we set one up...
|
||||||
if (GST_ELEMENT_IS_THREAD_SUGGESTED(element) || use_thread) {
|
if (GST_ELEMENT_IS_THREAD_SUGGESTED(element) || use_thread) {
|
||||||
GstElement *queue;
|
GstElement *queue;
|
||||||
GList *sinkpads;
|
GstPad *srcpad;
|
||||||
GstPad *srcpad, *sinkpad;
|
|
||||||
|
|
||||||
use_thread = FALSE;
|
use_thread = FALSE;
|
||||||
|
|
||||||
|
@ -453,22 +425,6 @@ differ:
|
||||||
|
|
||||||
srcpad = gst_element_get_pad(queue, "src");
|
srcpad = gst_element_get_pad(queue, "src");
|
||||||
|
|
||||||
sinkpads = gst_element_get_pad_list(element);
|
|
||||||
while (sinkpads) {
|
|
||||||
sinkpad = (GstPad *)sinkpads->data;
|
|
||||||
|
|
||||||
// FIXME connect matching pads, not just the first one...
|
|
||||||
if (gst_pad_get_direction(sinkpad) == GST_PAD_SINK &&
|
|
||||||
!GST_PAD_CONNECTED(sinkpad)) {
|
|
||||||
GList *caps = gst_pad_get_caps_list (sinkpad);
|
|
||||||
|
|
||||||
// the queue has the type of the elements it connects
|
|
||||||
gst_pad_set_caps_list (srcpad, caps);
|
|
||||||
gst_pad_set_caps_list (gst_element_get_pad(queue, "sink"), caps);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sinkpads = g_list_next(sinkpads);
|
|
||||||
}
|
|
||||||
gst_autoplug_pads_autoplug(thesrcelement, queue);
|
gst_autoplug_pads_autoplug(thesrcelement, queue);
|
||||||
|
|
||||||
GST_DEBUG (0,"adding element %s\n", GST_ELEMENT_NAME (element));
|
GST_DEBUG (0,"adding element %s\n", GST_ELEMENT_NAME (element));
|
||||||
|
|
|
@ -417,8 +417,9 @@ gst_audiosink_change_state (GstElement *element)
|
||||||
/* otherwise (READY or higher) we need to open the sound card */
|
/* otherwise (READY or higher) we need to open the sound card */
|
||||||
} else {
|
} else {
|
||||||
if (!GST_FLAG_IS_SET (element, GST_AUDIOSINK_OPEN)) {
|
if (!GST_FLAG_IS_SET (element, GST_AUDIOSINK_OPEN)) {
|
||||||
if (!gst_audiosink_open_audio (GST_AUDIOSINK (element)))
|
if (!gst_audiosink_open_audio (GST_AUDIOSINK (element))) {
|
||||||
return GST_STATE_FAILURE;
|
//return GST_STATE_FAILURE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ gst_autoplug_signal_new_object (GstAutoplug *autoplug, GstObject *object)
|
||||||
|
|
||||||
|
|
||||||
GstElement*
|
GstElement*
|
||||||
gst_autoplug_to_caps (GstAutoplug *autoplug, GList *srccaps, GList *sinkcaps, ...)
|
gst_autoplug_to_caps (GstAutoplug *autoplug, GstCaps *srccaps, GstCaps *sinkcaps, ...)
|
||||||
{
|
{
|
||||||
GstAutoplugClass *oclass;
|
GstAutoplugClass *oclass;
|
||||||
GstElement *element = NULL;
|
GstElement *element = NULL;
|
||||||
|
@ -120,7 +120,7 @@ gst_autoplug_to_caps (GstAutoplug *autoplug, GList *srccaps, GList *sinkcaps, ..
|
||||||
}
|
}
|
||||||
|
|
||||||
GstElement*
|
GstElement*
|
||||||
gst_autoplug_to_renderers (GstAutoplug *autoplug, GList *srccaps, GstElement *target, ...)
|
gst_autoplug_to_renderers (GstAutoplug *autoplug, GstCaps *srccaps, GstElement *target, ...)
|
||||||
{
|
{
|
||||||
GstAutoplugClass *oclass;
|
GstAutoplugClass *oclass;
|
||||||
GstElement *element = NULL;
|
GstElement *element = NULL;
|
||||||
|
|
|
@ -63,8 +63,8 @@ struct _GstAutoplugClass {
|
||||||
void (*new_object) (GstAutoplug *autoplug, GstObject *object);
|
void (*new_object) (GstAutoplug *autoplug, GstObject *object);
|
||||||
|
|
||||||
/* perform the autoplugging */
|
/* perform the autoplugging */
|
||||||
GstElement* (*autoplug_to_caps) (GstAutoplug *autoplug, GList *srccaps, GList *sinkcaps, va_list args);
|
GstElement* (*autoplug_to_caps) (GstAutoplug *autoplug, GstCaps *srccaps, GstCaps *sinkcaps, va_list args);
|
||||||
GstElement* (*autoplug_to_renderers) (GstAutoplug *autoplug, GList *srccaps, GstElement *target, va_list args);
|
GstElement* (*autoplug_to_renderers) (GstAutoplug *autoplug, GstCaps *srccaps, GstElement *target, va_list args);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _GstAutoplugFactory GstAutoplugFactory;
|
typedef struct _GstAutoplugFactory GstAutoplugFactory;
|
||||||
|
@ -79,8 +79,8 @@ GtkType gst_autoplug_get_type (void);
|
||||||
|
|
||||||
void gst_autoplug_signal_new_object (GstAutoplug *autoplug, GstObject *object);
|
void gst_autoplug_signal_new_object (GstAutoplug *autoplug, GstObject *object);
|
||||||
|
|
||||||
GstElement* gst_autoplug_to_caps (GstAutoplug *autoplug, GList *srccaps, GList *sinkcaps, ...);
|
GstElement* gst_autoplug_to_caps (GstAutoplug *autoplug, GstCaps *srccaps, GstCaps *sinkcaps, ...);
|
||||||
GstElement* gst_autoplug_to_renderers (GstAutoplug *autoplug, GList *srccaps,
|
GstElement* gst_autoplug_to_renderers (GstAutoplug *autoplug, GstCaps *srccaps,
|
||||||
GstElement *target, ...);
|
GstElement *target, ...);
|
||||||
|
|
||||||
|
|
||||||
|
|
132
gst/gstcaps.c
132
gst/gstcaps.c
|
@ -72,6 +72,7 @@ gst_caps_new (const gchar *name, const gchar *mime)
|
||||||
caps->name = g_strdup (name);
|
caps->name = g_strdup (name);
|
||||||
caps->id = get_type_for_mime (mime);
|
caps->id = get_type_for_mime (mime);
|
||||||
caps->properties = NULL;
|
caps->properties = NULL;
|
||||||
|
caps->next = NULL;
|
||||||
|
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
|
@ -297,19 +298,76 @@ gst_caps_get_props (GstCaps *caps)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_caps_check_compatibility:
|
* gst_caps_append:
|
||||||
* @fromcaps: a capabilty
|
* @caps: a capabilty
|
||||||
* @tocaps: a capabilty
|
* @capstoadd: the capability to append
|
||||||
*
|
*
|
||||||
* Checks whether two capabilities are compatible.
|
* Appends a capability to the existing capability.
|
||||||
*
|
*
|
||||||
* Returns: TRUE if compatible, FALSE otherwise
|
* Returns: the new capability
|
||||||
*/
|
*/
|
||||||
gboolean
|
GstCaps*
|
||||||
gst_caps_check_compatibility (GstCaps *fromcaps, GstCaps *tocaps)
|
gst_caps_append (GstCaps *caps, GstCaps *capstoadd)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (fromcaps != NULL, FALSE);
|
GstCaps *orig = caps;
|
||||||
g_return_val_if_fail (tocaps != NULL, FALSE);
|
|
||||||
|
if (caps == NULL)
|
||||||
|
return capstoadd;
|
||||||
|
|
||||||
|
while (caps->next) {
|
||||||
|
caps = caps->next;
|
||||||
|
}
|
||||||
|
caps->next = capstoadd;
|
||||||
|
|
||||||
|
return orig;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_caps_prepend:
|
||||||
|
* @caps: a capabilty
|
||||||
|
* @capstoadd: a capabilty to prepend
|
||||||
|
*
|
||||||
|
* prepend the capability to the list of capabilities
|
||||||
|
*
|
||||||
|
* Returns: the new capability
|
||||||
|
*/
|
||||||
|
GstCaps*
|
||||||
|
gst_caps_prepend (GstCaps *caps, GstCaps *capstoadd)
|
||||||
|
{
|
||||||
|
GstCaps *orig = capstoadd;
|
||||||
|
|
||||||
|
if (capstoadd == NULL)
|
||||||
|
return caps;
|
||||||
|
|
||||||
|
while (capstoadd->next) {
|
||||||
|
capstoadd = capstoadd->next;
|
||||||
|
}
|
||||||
|
capstoadd->next = caps;
|
||||||
|
|
||||||
|
return orig;
|
||||||
|
}
|
||||||
|
|
||||||
|
GstCaps*
|
||||||
|
gst_caps_get_by_name (GstCaps *caps, const gchar *name)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (caps != NULL, NULL);
|
||||||
|
g_return_val_if_fail (name != NULL, NULL);
|
||||||
|
|
||||||
|
while (caps) {
|
||||||
|
if (!strcmp (caps->name, name))
|
||||||
|
return caps;
|
||||||
|
caps = caps->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_caps_check_compatibility_func (GstCaps *fromcaps, GstCaps *tocaps)
|
||||||
|
{
|
||||||
|
if (fromcaps == NULL ||
|
||||||
|
tocaps == NULL)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
if (fromcaps->id != tocaps->id) {
|
if (fromcaps->id != tocaps->id) {
|
||||||
GST_DEBUG (0,"gstcaps: mime types differ (%d to %d)\n",
|
GST_DEBUG (0,"gstcaps: mime types differ (%d to %d)\n",
|
||||||
|
@ -343,21 +401,18 @@ gst_caps_check_compatibility (GstCaps *fromcaps, GstCaps *tocaps)
|
||||||
* Returns: TRUE if compatible, FALSE otherwise
|
* Returns: TRUE if compatible, FALSE otherwise
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
gst_caps_list_check_compatibility (GList *fromcaps, GList *tocaps)
|
gst_caps_check_compatibility (GstCaps *fromcaps, GstCaps *tocaps)
|
||||||
{
|
{
|
||||||
while (fromcaps) {
|
while (fromcaps) {
|
||||||
GstCaps *fromcap = (GstCaps *)fromcaps->data;
|
GstCaps *destcaps = tocaps;
|
||||||
GList *destcaps = tocaps;
|
|
||||||
|
|
||||||
while (destcaps) {
|
while (destcaps) {
|
||||||
GstCaps *destcap = (GstCaps *)destcaps->data;
|
if (gst_caps_check_compatibility_func (fromcaps, destcaps))
|
||||||
|
|
||||||
if (gst_caps_check_compatibility (fromcap, destcap))
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
destcaps = g_list_next (destcaps);
|
destcaps = destcaps->next;
|
||||||
}
|
}
|
||||||
fromcaps = g_list_next (fromcaps);
|
fromcaps = fromcaps->next;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -375,15 +430,20 @@ xmlNodePtr
|
||||||
gst_caps_save_thyself (GstCaps *caps, xmlNodePtr parent)
|
gst_caps_save_thyself (GstCaps *caps, xmlNodePtr parent)
|
||||||
{
|
{
|
||||||
xmlNodePtr subtree;
|
xmlNodePtr subtree;
|
||||||
|
xmlNodePtr subsubtree;
|
||||||
|
|
||||||
g_return_val_if_fail (caps != NULL, NULL);
|
while (caps) {
|
||||||
|
subtree = xmlNewChild (parent, NULL, "capscomp", NULL);
|
||||||
|
|
||||||
xmlNewChild (parent, NULL, "name", caps->name);
|
xmlNewChild (subtree, NULL, "name", caps->name);
|
||||||
xmlNewChild (parent, NULL, "type", gst_type_find_by_id (caps->id)->mime);
|
xmlNewChild (subtree, NULL, "type", gst_type_find_by_id (caps->id)->mime);
|
||||||
if (caps->properties) {
|
if (caps->properties) {
|
||||||
subtree = xmlNewChild (parent, NULL, "properties", NULL);
|
subsubtree = xmlNewChild (subtree, NULL, "properties", NULL);
|
||||||
|
|
||||||
gst_props_save_thyself (caps->properties, subtree);
|
gst_props_save_thyself (caps->properties, subsubtree);
|
||||||
|
}
|
||||||
|
|
||||||
|
caps = caps->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent;
|
return parent;
|
||||||
|
@ -400,26 +460,36 @@ gst_caps_save_thyself (GstCaps *caps, xmlNodePtr parent)
|
||||||
GstCaps*
|
GstCaps*
|
||||||
gst_caps_load_thyself (xmlNodePtr parent)
|
gst_caps_load_thyself (xmlNodePtr parent)
|
||||||
{
|
{
|
||||||
GstCaps *caps = g_new0 (GstCaps, 1);
|
GstCaps *result = NULL;
|
||||||
xmlNodePtr field = parent->xmlChildrenNode;
|
xmlNodePtr field = parent->xmlChildrenNode;
|
||||||
gchar *content;
|
|
||||||
|
|
||||||
while (field) {
|
while (field) {
|
||||||
if (!strcmp (field->name, "name")) {
|
if (!strcmp (field->name, "capscomp")) {
|
||||||
caps->name = xmlNodeGetContent (field);
|
xmlNodePtr subfield = field->xmlChildrenNode;
|
||||||
|
GstCaps *caps = g_new0 (GstCaps, 1);
|
||||||
|
gchar *content;
|
||||||
|
|
||||||
|
while (subfield) {
|
||||||
|
if (!strcmp (subfield->name, "name")) {
|
||||||
|
caps->name = xmlNodeGetContent (subfield);
|
||||||
}
|
}
|
||||||
if (!strcmp (field->name, "type")) {
|
if (!strcmp (subfield->name, "type")) {
|
||||||
content = xmlNodeGetContent (field);
|
content = xmlNodeGetContent (subfield);
|
||||||
caps->id = get_type_for_mime (content);
|
caps->id = get_type_for_mime (content);
|
||||||
g_free (content);
|
g_free (content);
|
||||||
}
|
}
|
||||||
else if (!strcmp (field->name, "properties")) {
|
else if (!strcmp (subfield->name, "properties")) {
|
||||||
caps->properties = gst_props_load_thyself (field);
|
caps->properties = gst_props_load_thyself (subfield);
|
||||||
|
}
|
||||||
|
|
||||||
|
subfield = subfield->next;
|
||||||
|
}
|
||||||
|
result = gst_caps_append (result, caps);
|
||||||
}
|
}
|
||||||
field = field->next;
|
field = field->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return caps;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,8 @@ struct _GstCaps {
|
||||||
guint16 id; /* type id (major type) */
|
guint16 id; /* type id (major type) */
|
||||||
|
|
||||||
GstProps *properties; /* properties for this capability */
|
GstProps *properties; /* properties for this capability */
|
||||||
|
|
||||||
|
GstCaps *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* initialize the subsystem */
|
/* initialize the subsystem */
|
||||||
|
@ -71,8 +73,12 @@ void gst_caps_set_type_id (GstCaps *caps, guint16 type_id);
|
||||||
GstCaps* gst_caps_set_props (GstCaps *caps, GstProps *props);
|
GstCaps* gst_caps_set_props (GstCaps *caps, GstProps *props);
|
||||||
GstProps* gst_caps_get_props (GstCaps *caps);
|
GstProps* gst_caps_get_props (GstCaps *caps);
|
||||||
|
|
||||||
|
GstCaps* gst_caps_get_by_name (GstCaps *caps, const gchar *name);
|
||||||
|
|
||||||
|
GstCaps* gst_caps_append (GstCaps *caps, GstCaps *capstoadd);
|
||||||
|
GstCaps* gst_caps_prepend (GstCaps *caps, GstCaps *capstoadd);
|
||||||
|
|
||||||
gboolean gst_caps_check_compatibility (GstCaps *fromcaps, GstCaps *tocaps);
|
gboolean gst_caps_check_compatibility (GstCaps *fromcaps, GstCaps *tocaps);
|
||||||
gboolean gst_caps_list_check_compatibility (GList *fromcaps, GList *tocaps);
|
|
||||||
|
|
||||||
xmlNodePtr gst_caps_save_thyself (GstCaps *caps, xmlNodePtr parent);
|
xmlNodePtr gst_caps_save_thyself (GstCaps *caps, xmlNodePtr parent);
|
||||||
GstCaps* gst_caps_load_thyself (xmlNodePtr parent);
|
GstCaps* gst_caps_load_thyself (xmlNodePtr parent);
|
||||||
|
|
|
@ -461,14 +461,14 @@ gst_element_get_padtemplate_by_compatible (GstElement *element, GstPadTemplate *
|
||||||
if (padtempl->direction == GST_PAD_SRC &&
|
if (padtempl->direction == GST_PAD_SRC &&
|
||||||
compattempl->direction == GST_PAD_SINK) {
|
compattempl->direction == GST_PAD_SINK) {
|
||||||
GST_DEBUG(0,"compatible direction: found src pad template\n");
|
GST_DEBUG(0,"compatible direction: found src pad template\n");
|
||||||
compat = gst_caps_list_check_compatibility(padtempl->caps,
|
compat = gst_caps_check_compatibility(GST_PADTEMPLATE_CAPS (padtempl),
|
||||||
compattempl->caps);
|
GST_PADTEMPLATE_CAPS (compattempl));
|
||||||
GST_DEBUG(0,"caps are %scompatible\n", (compat?"":"not "));
|
GST_DEBUG(0,"caps are %scompatible\n", (compat?"":"not "));
|
||||||
} else if (padtempl->direction == GST_PAD_SINK &&
|
} else if (padtempl->direction == GST_PAD_SINK &&
|
||||||
compattempl->direction == GST_PAD_SRC) {
|
compattempl->direction == GST_PAD_SRC) {
|
||||||
GST_DEBUG(0,"compatible direction: found sink pad template\n");
|
GST_DEBUG(0,"compatible direction: found sink pad template\n");
|
||||||
compat = gst_caps_list_check_compatibility(compattempl->caps,
|
compat = gst_caps_check_compatibility(GST_PADTEMPLATE_CAPS (compattempl),
|
||||||
padtempl->caps);
|
GST_PADTEMPLATE_CAPS (padtempl));
|
||||||
GST_DEBUG(0,"caps are %scompatible\n", (compat?"":"not "));
|
GST_DEBUG(0,"caps are %scompatible\n", (compat?"":"not "));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -251,10 +251,10 @@ gboolean gst_elementfactory_can_src_caps (GstElementFactory *factory,
|
||||||
GstCaps *caps);
|
GstCaps *caps);
|
||||||
gboolean gst_elementfactory_can_sink_caps (GstElementFactory *factory,
|
gboolean gst_elementfactory_can_sink_caps (GstElementFactory *factory,
|
||||||
GstCaps *caps);
|
GstCaps *caps);
|
||||||
gboolean gst_elementfactory_can_src_caps_list (GstElementFactory *factory,
|
gboolean gst_elementfactory_can_src_caps (GstElementFactory *factory,
|
||||||
GList *caps);
|
GstCaps *caps);
|
||||||
gboolean gst_elementfactory_can_sink_caps_list (GstElementFactory *factory,
|
gboolean gst_elementfactory_can_sink_caps (GstElementFactory *factory,
|
||||||
GList *caps);
|
GstCaps *caps);
|
||||||
|
|
||||||
GstElement* gst_elementfactory_create (GstElementFactory *factory,
|
GstElement* gst_elementfactory_create (GstElementFactory *factory,
|
||||||
const gchar *name);
|
const gchar *name);
|
||||||
|
|
|
@ -222,17 +222,17 @@ gst_elementfactory_add_padtemplate (GstElementFactory *factory,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_elementfactory_can_src_caps_list :
|
* gst_elementfactory_can_src_caps :
|
||||||
* @factory: factory to query
|
* @factory: factory to query
|
||||||
* @caps: the caps list to check
|
* @caps: the caps to check
|
||||||
*
|
*
|
||||||
* Checks if the factory can source the given capability list.
|
* Checks if the factory can source the given capability.
|
||||||
*
|
*
|
||||||
* Returns: true if it can src the capabilities
|
* Returns: true if it can src the capabilities
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
gst_elementfactory_can_src_caps_list (GstElementFactory *factory,
|
gst_elementfactory_can_src_caps (GstElementFactory *factory,
|
||||||
GList *caps)
|
GstCaps *caps)
|
||||||
{
|
{
|
||||||
GList *templates;
|
GList *templates;
|
||||||
|
|
||||||
|
@ -245,7 +245,7 @@ gst_elementfactory_can_src_caps_list (GstElementFactory *factory,
|
||||||
GstPadTemplate *template = (GstPadTemplate *)templates->data;
|
GstPadTemplate *template = (GstPadTemplate *)templates->data;
|
||||||
|
|
||||||
if (template->direction == GST_PAD_SRC) {
|
if (template->direction == GST_PAD_SRC) {
|
||||||
if (gst_caps_list_check_compatibility (template->caps, caps))
|
if (gst_caps_check_compatibility (GST_PADTEMPLATE_CAPS (template), caps))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
templates = g_list_next (templates);
|
templates = g_list_next (templates);
|
||||||
|
@ -255,17 +255,17 @@ gst_elementfactory_can_src_caps_list (GstElementFactory *factory,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_elementfactory_can_sink_caps_list :
|
* gst_elementfactory_can_sink_caps :
|
||||||
* @factory: factory to query
|
* @factory: factory to query
|
||||||
* @caps: the caps list to check
|
* @caps: the caps to check
|
||||||
*
|
*
|
||||||
* Checks if the factory can sink the given capability list.
|
* Checks if the factory can sink the given capability.
|
||||||
*
|
*
|
||||||
* Returns: true if it can sink the capabilities
|
* Returns: true if it can sink the capabilities
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
gst_elementfactory_can_sink_caps_list (GstElementFactory *factory,
|
gst_elementfactory_can_sink_caps (GstElementFactory *factory,
|
||||||
GList *caps)
|
GstCaps *caps)
|
||||||
{
|
{
|
||||||
GList *templates;
|
GList *templates;
|
||||||
|
|
||||||
|
@ -278,7 +278,7 @@ gst_elementfactory_can_sink_caps_list (GstElementFactory *factory,
|
||||||
GstPadTemplate *template = (GstPadTemplate *)templates->data;
|
GstPadTemplate *template = (GstPadTemplate *)templates->data;
|
||||||
|
|
||||||
if (template->direction == GST_PAD_SINK) {
|
if (template->direction == GST_PAD_SINK) {
|
||||||
if (gst_caps_list_check_compatibility (caps, template->caps))
|
if (gst_caps_check_compatibility (caps, GST_PADTEMPLATE_CAPS (template)))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
templates = g_list_next (templates);
|
templates = g_list_next (templates);
|
||||||
|
@ -287,56 +287,6 @@ gst_elementfactory_can_sink_caps_list (GstElementFactory *factory,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* gst_elementfactory_can_src_caps :
|
|
||||||
* @factory: factory to query
|
|
||||||
* @caps: the caps to check
|
|
||||||
*
|
|
||||||
* Checks if the factory can src the given capability.
|
|
||||||
*
|
|
||||||
* Returns: true if it can sink the capability
|
|
||||||
*/
|
|
||||||
gboolean
|
|
||||||
gst_elementfactory_can_src_caps (GstElementFactory *factory,
|
|
||||||
GstCaps *caps)
|
|
||||||
{
|
|
||||||
GList *dummy;
|
|
||||||
gboolean ret;
|
|
||||||
|
|
||||||
dummy = g_list_prepend (NULL, caps);
|
|
||||||
|
|
||||||
ret = gst_elementfactory_can_src_caps_list (factory, dummy);
|
|
||||||
|
|
||||||
g_list_free (dummy);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gst_elementfactory_can_sink_caps :
|
|
||||||
* @factory: factory to query
|
|
||||||
* @caps: the caps to check
|
|
||||||
*
|
|
||||||
* Checks if the factory can sink the given capability.
|
|
||||||
*
|
|
||||||
* Returns: true if it can sink the capability
|
|
||||||
*/
|
|
||||||
gboolean
|
|
||||||
gst_elementfactory_can_sink_caps (GstElementFactory *factory,
|
|
||||||
GstCaps *caps)
|
|
||||||
{
|
|
||||||
GList *dummy;
|
|
||||||
gboolean ret;
|
|
||||||
|
|
||||||
dummy = g_list_prepend (NULL, caps);
|
|
||||||
|
|
||||||
ret = gst_elementfactory_can_sink_caps_list (factory, dummy);
|
|
||||||
|
|
||||||
g_list_free (dummy);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_elementfactory_save_thyself:
|
* gst_elementfactory_save_thyself:
|
||||||
* @factory: factory to save
|
* @factory: factory to save
|
||||||
|
|
315
gst/gstpad.c
315
gst/gstpad.c
|
@ -259,8 +259,8 @@ gst_pad_new_from_template (GstPadTemplate *templ,
|
||||||
g_return_val_if_fail (templ != NULL, NULL);
|
g_return_val_if_fail (templ != NULL, NULL);
|
||||||
|
|
||||||
pad = gst_pad_new (name, templ->direction);
|
pad = gst_pad_new (name, templ->direction);
|
||||||
GST_PAD_CAPS(pad) = templ->caps;
|
|
||||||
GST_PAD_PADTEMPLATE(pad) = templ;
|
GST_PAD_PADTEMPLATE(pad) = templ;
|
||||||
|
GST_PAD_CAPS (pad) = GST_PADTEMPLATE_CAPS (templ);
|
||||||
|
|
||||||
return pad;
|
return pad;
|
||||||
}
|
}
|
||||||
|
@ -410,6 +410,25 @@ gst_pad_set_eos_function (GstPad *pad,
|
||||||
GST_DEBUG_PAD_NAME(pad),pad,&GST_RPAD_EOSFUNC(pad),eos);
|
GST_DEBUG_PAD_NAME(pad),pad,&GST_RPAD_EOSFUNC(pad),eos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_pad_set_eos_function:
|
||||||
|
* @pad: the pad to set the eos function for
|
||||||
|
* @eos: the eos function
|
||||||
|
*
|
||||||
|
* Set the given EOS function for the pad.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gst_pad_set_negotiate_function (GstPad *pad,
|
||||||
|
GstPadNegotiateFunction nego)
|
||||||
|
{
|
||||||
|
g_return_if_fail (pad != NULL);
|
||||||
|
g_return_if_fail (GST_IS_REAL_PAD (pad));
|
||||||
|
|
||||||
|
GST_RPAD_NEGOTIATEFUNC(pad) = nego;
|
||||||
|
GST_DEBUG (0,"negotiatefunc for %s:%s(@%p) at %p is set to %p\n",
|
||||||
|
GST_DEBUG_PAD_NAME(pad),pad,&GST_RPAD_NEGOTIATEFUNC(pad),nego);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -503,26 +522,32 @@ gst_pad_disconnect (GstPad *srcpad,
|
||||||
* @sinkpad: the sink pad to connect
|
* @sinkpad: the sink pad to connect
|
||||||
*
|
*
|
||||||
* Connects the source pad to the sink pad.
|
* Connects the source pad to the sink pad.
|
||||||
|
*
|
||||||
|
* Returns: TRUE if the pad could be connected
|
||||||
*/
|
*/
|
||||||
void
|
gboolean
|
||||||
gst_pad_connect (GstPad *srcpad,
|
gst_pad_connect (GstPad *srcpad,
|
||||||
GstPad *sinkpad)
|
GstPad *sinkpad)
|
||||||
{
|
{
|
||||||
GstRealPad *realsrc, *realsink;
|
GstRealPad *realsrc, *realsink;
|
||||||
GstRealPad *temppad;
|
GstRealPad *temppad;
|
||||||
|
gboolean negotiated = FALSE;
|
||||||
|
|
||||||
/* generic checks */
|
/* generic checks */
|
||||||
g_return_if_fail(srcpad != NULL);
|
g_return_val_if_fail(srcpad != NULL, FALSE);
|
||||||
g_return_if_fail(GST_IS_PAD(srcpad));
|
g_return_val_if_fail(GST_IS_PAD(srcpad), FALSE);
|
||||||
g_return_if_fail(sinkpad != NULL);
|
g_return_val_if_fail(sinkpad != NULL, FALSE);
|
||||||
g_return_if_fail(GST_IS_PAD(sinkpad));
|
g_return_val_if_fail(GST_IS_PAD(sinkpad), FALSE);
|
||||||
|
|
||||||
|
GST_INFO (GST_CAT_ELEMENT_PADS, "about to connect %s:%s and %s:%s",
|
||||||
|
GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
|
||||||
|
|
||||||
// now we need to deal with the real/ghost stuff
|
// now we need to deal with the real/ghost stuff
|
||||||
realsrc = GST_PAD_REALIZE(srcpad);
|
realsrc = GST_PAD_REALIZE(srcpad);
|
||||||
realsink = GST_PAD_REALIZE(sinkpad);
|
realsink = GST_PAD_REALIZE(sinkpad);
|
||||||
|
|
||||||
g_return_if_fail(GST_RPAD_PEER(realsrc) == NULL);
|
g_return_val_if_fail(GST_RPAD_PEER(realsrc) == NULL, FALSE);
|
||||||
g_return_if_fail(GST_RPAD_PEER(realsink) == NULL);
|
g_return_val_if_fail(GST_RPAD_PEER(realsink) == NULL, FALSE);
|
||||||
|
|
||||||
/* check for reversed directions and swap if necessary */
|
/* check for reversed directions and swap if necessary */
|
||||||
if ((GST_RPAD_DIRECTION(realsrc) == GST_PAD_SINK) &&
|
if ((GST_RPAD_DIRECTION(realsrc) == GST_PAD_SINK) &&
|
||||||
|
@ -531,27 +556,31 @@ gst_pad_connect (GstPad *srcpad,
|
||||||
realsrc = realsink;
|
realsrc = realsink;
|
||||||
realsink = temppad;
|
realsink = temppad;
|
||||||
}
|
}
|
||||||
g_return_if_fail((GST_RPAD_DIRECTION(realsrc) == GST_PAD_SRC) &&
|
g_return_val_if_fail((GST_RPAD_DIRECTION(realsrc) == GST_PAD_SRC) &&
|
||||||
(GST_RPAD_DIRECTION(realsink) == GST_PAD_SINK));
|
(GST_RPAD_DIRECTION(realsink) == GST_PAD_SINK), FALSE);
|
||||||
|
|
||||||
if (!gst_pad_check_compatibility (srcpad, sinkpad)) {
|
|
||||||
g_warning ("gstpad: connecting incompatible pads (%s:%s) and (%s:%s)\n",
|
|
||||||
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
GST_DEBUG (0,"gstpad: connecting compatible pads (%s:%s) and (%s:%s)\n",
|
|
||||||
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* first set peers */
|
/* first set peers */
|
||||||
GST_RPAD_PEER(realsrc) = realsink;
|
GST_RPAD_PEER(realsrc) = realsink;
|
||||||
GST_RPAD_PEER(realsink) = realsrc;
|
GST_RPAD_PEER(realsink) = realsrc;
|
||||||
|
|
||||||
/* set the connected flag */
|
|
||||||
/* FIXME: set connected flag */
|
/* FIXME: set connected flag */
|
||||||
|
|
||||||
GST_INFO (GST_CAT_ELEMENT_PADS, "connected %s:%s and %s:%s",
|
GST_INFO (GST_CAT_ELEMENT_PADS, "connected %s:%s and %s:%s",
|
||||||
GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
|
GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
|
||||||
|
|
||||||
|
if (GST_PAD_CAPS (srcpad)) {
|
||||||
|
negotiated = gst_pad_renegotiate (srcpad);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
negotiated = gst_pad_renegotiate (sinkpad);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!negotiated) {
|
||||||
|
gst_pad_disconnect (srcpad, sinkpad);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -575,6 +604,23 @@ gst_pad_set_parent (GstPad *pad,
|
||||||
gst_object_set_parent (GST_OBJECT (pad), parent);
|
gst_object_set_parent (GST_OBJECT (pad), parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_pad_get_parent:
|
||||||
|
* @pad: the pad to get the parent from
|
||||||
|
*
|
||||||
|
* Get the parent object of this pad.
|
||||||
|
*
|
||||||
|
* Returns: the parent object
|
||||||
|
*/
|
||||||
|
GstPadTemplate*
|
||||||
|
gst_pad_get_padtemplate (GstPad *pad)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (pad != NULL, NULL);
|
||||||
|
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
|
||||||
|
|
||||||
|
return GST_PAD_PADTEMPLATE (pad);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_pad_get_parent:
|
* gst_pad_get_parent:
|
||||||
* @pad: the pad to get the parent from
|
* @pad: the pad to get the parent from
|
||||||
|
@ -676,20 +722,22 @@ gst_pad_get_ghost_pad_list (GstPad *pad)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_pad_set_caps_list:
|
* gst_pad_set_caps:
|
||||||
* @pad: the pad to set the caps to
|
* @pad: the pad to set the caps to
|
||||||
* @caps: a GList of the capabilities to attach to this pad
|
* @caps: a GList of the capabilities to attach to this pad
|
||||||
*
|
*
|
||||||
* Set the capabilities of this pad.
|
* Set the capabilities of this pad.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
gst_pad_set_caps_list (GstPad *pad,
|
gst_pad_set_caps (GstPad *pad,
|
||||||
GList *caps)
|
GstCaps *caps)
|
||||||
{
|
{
|
||||||
g_return_if_fail (pad != NULL);
|
g_return_if_fail (pad != NULL);
|
||||||
g_return_if_fail (GST_IS_REAL_PAD (pad)); // NOTE this restriction
|
g_return_if_fail (GST_IS_REAL_PAD (pad)); // NOTE this restriction
|
||||||
|
|
||||||
GST_PAD_CAPS(pad) = caps;
|
GST_PAD_CAPS(pad) = caps;
|
||||||
|
|
||||||
|
gst_pad_renegotiate (pad);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -700,8 +748,8 @@ gst_pad_set_caps_list (GstPad *pad,
|
||||||
*
|
*
|
||||||
* Returns: a list of the capabilities of this pad
|
* Returns: a list of the capabilities of this pad
|
||||||
*/
|
*/
|
||||||
GList *
|
GstCaps*
|
||||||
gst_pad_get_caps_list (GstPad *pad)
|
gst_pad_get_caps (GstPad *pad)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (pad != NULL, NULL);
|
g_return_val_if_fail (pad != NULL, NULL);
|
||||||
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
|
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
|
||||||
|
@ -719,25 +767,17 @@ gst_pad_get_caps_list (GstPad *pad)
|
||||||
* Returns: a capability or NULL if not found
|
* Returns: a capability or NULL if not found
|
||||||
*/
|
*/
|
||||||
GstCaps*
|
GstCaps*
|
||||||
gst_pad_get_caps_by_name (GstPad *pad, gchar *name)
|
gst_padtemplate_get_caps_by_name (GstPadTemplate *templ, const gchar *name)
|
||||||
{
|
{
|
||||||
GList *caps;
|
GstCaps *caps;
|
||||||
|
|
||||||
g_return_val_if_fail (pad != NULL, NULL);
|
g_return_val_if_fail (templ != NULL, NULL);
|
||||||
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
|
|
||||||
|
|
||||||
caps = GST_PAD_CAPS(pad);
|
|
||||||
|
|
||||||
while (caps) {
|
|
||||||
GstCaps *cap = (GstCaps *)caps->data;
|
|
||||||
|
|
||||||
if (!strcmp (cap->name, name))
|
|
||||||
return cap;
|
|
||||||
|
|
||||||
caps = g_list_next (caps);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
caps = GST_PADTEMPLATE_CAPS (templ);
|
||||||
|
if (!caps)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
return gst_caps_get_by_name (caps, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -753,18 +793,13 @@ gst_pad_get_caps_by_name (GstPad *pad, gchar *name)
|
||||||
gboolean
|
gboolean
|
||||||
gst_pad_check_compatibility (GstPad *srcpad, GstPad *sinkpad)
|
gst_pad_check_compatibility (GstPad *srcpad, GstPad *sinkpad)
|
||||||
{
|
{
|
||||||
GstRealPad *realsrc, *realsink;
|
|
||||||
|
|
||||||
g_return_val_if_fail (srcpad != NULL, FALSE);
|
g_return_val_if_fail (srcpad != NULL, FALSE);
|
||||||
g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
|
g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
|
||||||
g_return_val_if_fail (sinkpad != NULL, FALSE);
|
g_return_val_if_fail (sinkpad != NULL, FALSE);
|
||||||
g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
|
g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
|
||||||
|
|
||||||
realsrc = GST_PAD_REALIZE(srcpad);
|
if (GST_PAD_CAPS(srcpad) && GST_PAD_CAPS(sinkpad)) {
|
||||||
realsink = GST_PAD_REALIZE(sinkpad);
|
if (!gst_caps_check_compatibility (GST_PAD_CAPS(srcpad), GST_PAD_CAPS(sinkpad))) {
|
||||||
|
|
||||||
if (GST_RPAD_CAPS(realsrc) && GST_RPAD_CAPS(realsink)) {
|
|
||||||
if (!gst_caps_list_check_compatibility (GST_RPAD_CAPS(realsrc), GST_RPAD_CAPS(realsink))) {
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -772,8 +807,9 @@ gst_pad_check_compatibility (GstPad *srcpad, GstPad *sinkpad)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
GST_DEBUG (0,"gstpad: could not check capabilities of pads (%s:%s) and (%s:%s)\n",
|
GST_DEBUG (0,"gstpad: could not check capabilities of pads (%s:%s) and (%s:%s) %p %p\n",
|
||||||
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
|
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad),
|
||||||
|
GST_PAD_CAPS (srcpad), GST_PAD_CAPS (sinkpad));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -864,6 +900,143 @@ cleanup:
|
||||||
g_strfreev (split);
|
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)
|
||||||
|
{
|
||||||
|
gint counter = 0;
|
||||||
|
GstCaps *newcaps = NULL;
|
||||||
|
GstRealPad *peerpad, *currentpad, *otherpad;
|
||||||
|
GstCaps *currentcaps;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
do {
|
||||||
|
currentcaps = newcaps;
|
||||||
|
|
||||||
|
/* this pad wants to negotiate */
|
||||||
|
if (currentpad->negotiatefunc) {
|
||||||
|
|
||||||
|
GST_DEBUG (GST_CAT_ELEMENT_PADS, "calling negotiate function on pad %s:%s, count=%d\n",
|
||||||
|
GST_DEBUG_PAD_NAME(currentpad), counter);
|
||||||
|
newcaps = (currentpad->negotiatefunc) (GST_PAD (currentpad), currentcaps, counter);
|
||||||
|
|
||||||
|
if (newcaps == NULL) {
|
||||||
|
GST_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s has refused, negotiation failed :(, count=%d\n",
|
||||||
|
GST_DEBUG_PAD_NAME(currentpad), counter);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (newcaps == currentcaps) {
|
||||||
|
GST_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s aggreed with caps, count=%d\n",
|
||||||
|
GST_DEBUG_PAD_NAME(currentpad), counter);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* this pad doesn't want to negotiate, take its caps and that will be it then */
|
||||||
|
else {
|
||||||
|
GST_DEBUG (GST_CAT_ELEMENT_PADS, "getting caps from pad %s:%s, count=%d\n",
|
||||||
|
GST_DEBUG_PAD_NAME(currentpad), counter);
|
||||||
|
newcaps = GST_PAD_CAPS (currentpad);
|
||||||
|
}
|
||||||
|
/* we have a caps structure now */
|
||||||
|
|
||||||
|
/* check if the other pad wants to negotiate */
|
||||||
|
if (!otherpad->negotiatefunc) {
|
||||||
|
/* the pad doesn't want to negotiate, so we check if the caps
|
||||||
|
* we got from the current pad are compatible */
|
||||||
|
GST_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s doesn't want to negotiate, count=%d\n",
|
||||||
|
GST_DEBUG_PAD_NAME(otherpad), counter);
|
||||||
|
if (!otherpad->caps ||
|
||||||
|
gst_caps_check_compatibility (newcaps, otherpad->caps)) {
|
||||||
|
GST_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s has compatible caps, count=%d\n",
|
||||||
|
GST_DEBUG_PAD_NAME(otherpad), counter);
|
||||||
|
/* we're lucky */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* else, we let the current pad select another caps */
|
||||||
|
}
|
||||||
|
/* if the other pad wants to negotiate, setup the pointers */
|
||||||
|
else {
|
||||||
|
GstRealPad *temp;
|
||||||
|
|
||||||
|
GST_DEBUG (GST_CAT_ELEMENT_PADS, "switching pads for next phase\n");
|
||||||
|
|
||||||
|
temp = currentpad;
|
||||||
|
currentpad = otherpad;
|
||||||
|
otherpad = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
counter++;
|
||||||
|
|
||||||
|
} while (counter < 100); // FIXME
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
GstCaps*
|
||||||
|
gst_pad_negotiate_proxy (GstPad *pad, GstCaps *caps, gint count)
|
||||||
|
{
|
||||||
|
GstRealPad *peer;
|
||||||
|
GstCaps *newcaps = caps;
|
||||||
|
|
||||||
|
g_return_val_if_fail (pad != NULL, NULL);
|
||||||
|
|
||||||
|
GST_DEBUG (GST_CAT_ELEMENT_PADS, "pad (%s:%s) proxied\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));
|
||||||
|
newcaps = peer->negotiatefunc (pad, caps, count);
|
||||||
|
}
|
||||||
|
else if (!peer->caps ||
|
||||||
|
gst_caps_check_compatibility (newcaps, peer->caps)) {
|
||||||
|
GST_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s has compatible caps\n",
|
||||||
|
GST_DEBUG_PAD_NAME(peer));
|
||||||
|
}
|
||||||
|
else return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (caps == newcaps) {
|
||||||
|
GST_PAD_CAPS (pad) = newcaps;
|
||||||
|
if (peer) GST_PAD_CAPS (peer) = newcaps;
|
||||||
|
}
|
||||||
|
|
||||||
|
return newcaps;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_pad_save_thyself:
|
* gst_pad_save_thyself:
|
||||||
|
@ -1113,8 +1286,9 @@ gst_padtemplate_new (GstPadFactory *factory)
|
||||||
|
|
||||||
tag = (*factory)[i++];
|
tag = (*factory)[i++];
|
||||||
|
|
||||||
while (GPOINTER_TO_INT (tag) == 1) {
|
while (GPOINTER_TO_INT (tag) == GST_PAD_FACTORY_CAPS_ID) {
|
||||||
new->caps = g_list_append (new->caps, gst_caps_register_count ((GstCapsFactory *)&(*factory)[i], &counter));
|
GST_PADTEMPLATE_CAPS (new) = gst_caps_append (GST_PADTEMPLATE_CAPS (new),
|
||||||
|
gst_caps_register_count ((GstCapsFactory *)&(*factory)[i], &counter));
|
||||||
i+=counter;
|
i+=counter;
|
||||||
tag = (*factory)[i++];
|
tag = (*factory)[i++];
|
||||||
}
|
}
|
||||||
|
@ -1136,7 +1310,7 @@ gst_padtemplate_new (GstPadFactory *factory)
|
||||||
GstPadTemplate*
|
GstPadTemplate*
|
||||||
gst_padtemplate_create (gchar *name_template,
|
gst_padtemplate_create (gchar *name_template,
|
||||||
GstPadDirection direction, GstPadPresence presence,
|
GstPadDirection direction, GstPadPresence presence,
|
||||||
GList *caps)
|
GstCaps *caps)
|
||||||
{
|
{
|
||||||
GstPadTemplate *new;
|
GstPadTemplate *new;
|
||||||
|
|
||||||
|
@ -1144,14 +1318,29 @@ gst_padtemplate_create (gchar *name_template,
|
||||||
|
|
||||||
new = gtk_type_new (gst_padtemplate_get_type ());
|
new = gtk_type_new (gst_padtemplate_get_type ());
|
||||||
|
|
||||||
new->name_template = name_template;
|
GST_PADTEMPLATE_NAME_TEMPLATE (new) = name_template;
|
||||||
new->direction = direction;
|
GST_PADTEMPLATE_DIRECTION (new) = direction;
|
||||||
new->presence = presence;
|
GST_PADTEMPLATE_PRESENCE (new) = presence;
|
||||||
new->caps = caps;
|
GST_PADTEMPLATE_CAPS (new) = caps;
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_padtemplate_get_caps:
|
||||||
|
* @templ: the padtemplate to use
|
||||||
|
*
|
||||||
|
* Get the capabilities of the padtemplate
|
||||||
|
*
|
||||||
|
* Returns: a GstCaps*
|
||||||
|
*/
|
||||||
|
GstCaps*
|
||||||
|
gst_padtemplate_get_caps (GstPadTemplate *templ)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (templ != NULL, NULL);
|
||||||
|
|
||||||
|
return GST_PADTEMPLATE_CAPS (templ);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_padtemplate_save_thyself:
|
* gst_padtemplate_save_thyself:
|
||||||
|
@ -1166,9 +1355,10 @@ xmlNodePtr
|
||||||
gst_padtemplate_save_thyself (GstPadTemplate *templ, xmlNodePtr parent)
|
gst_padtemplate_save_thyself (GstPadTemplate *templ, xmlNodePtr parent)
|
||||||
{
|
{
|
||||||
xmlNodePtr subtree;
|
xmlNodePtr subtree;
|
||||||
GList *caps;
|
|
||||||
guchar *presence;
|
guchar *presence;
|
||||||
|
|
||||||
|
GST_DEBUG (0,"saving padtemplate %s\n", templ->name_template);
|
||||||
|
|
||||||
xmlNewChild(parent,NULL,"nametemplate", templ->name_template);
|
xmlNewChild(parent,NULL,"nametemplate", templ->name_template);
|
||||||
xmlNewChild(parent,NULL,"direction", (templ->direction == GST_PAD_SINK? "sink":"src"));
|
xmlNewChild(parent,NULL,"direction", (templ->direction == GST_PAD_SINK? "sink":"src"));
|
||||||
|
|
||||||
|
@ -1188,14 +1378,9 @@ gst_padtemplate_save_thyself (GstPadTemplate *templ, xmlNodePtr parent)
|
||||||
}
|
}
|
||||||
xmlNewChild(parent,NULL,"presence", presence);
|
xmlNewChild(parent,NULL,"presence", presence);
|
||||||
|
|
||||||
caps = templ->caps;
|
if (GST_PADTEMPLATE_CAPS (templ)) {
|
||||||
while (caps) {
|
|
||||||
GstCaps *cap = (GstCaps *)caps->data;
|
|
||||||
|
|
||||||
subtree = xmlNewChild (parent, NULL, "caps", NULL);
|
subtree = xmlNewChild (parent, NULL, "caps", NULL);
|
||||||
gst_caps_save_thyself (cap, subtree);
|
gst_caps_save_thyself (GST_PADTEMPLATE_CAPS (templ), subtree);
|
||||||
|
|
||||||
caps = g_list_next (caps);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent;
|
return parent;
|
||||||
|
@ -1217,7 +1402,7 @@ gst_padtemplate_load_thyself (xmlNodePtr parent)
|
||||||
gchar *name_template = NULL;
|
gchar *name_template = NULL;
|
||||||
GstPadDirection direction = GST_PAD_UNKNOWN;
|
GstPadDirection direction = GST_PAD_UNKNOWN;
|
||||||
GstPadPresence presence = GST_PAD_ALWAYS;
|
GstPadPresence presence = GST_PAD_ALWAYS;
|
||||||
GList *caps = NULL;
|
GstCaps *caps = NULL;
|
||||||
|
|
||||||
while (field) {
|
while (field) {
|
||||||
if (!strcmp(field->name, "nametemplate")) {
|
if (!strcmp(field->name, "nametemplate")) {
|
||||||
|
@ -1249,7 +1434,7 @@ gst_padtemplate_load_thyself (xmlNodePtr parent)
|
||||||
g_free (value);
|
g_free (value);
|
||||||
}
|
}
|
||||||
else if (!strcmp(field->name, "caps")) {
|
else if (!strcmp(field->name, "caps")) {
|
||||||
caps = g_list_append (caps, gst_caps_load_thyself (field));
|
caps = gst_caps_load_thyself (field);
|
||||||
}
|
}
|
||||||
field = field->next;
|
field = field->next;
|
||||||
}
|
}
|
||||||
|
|
36
gst/gstpad.h
36
gst/gstpad.h
|
@ -92,6 +92,7 @@ typedef void (*GstPadPushFunction) (GstPad *pad, GstBuffer *buf);
|
||||||
typedef GstBuffer *(*GstPadPullFunction) (GstPad *pad);
|
typedef GstBuffer *(*GstPadPullFunction) (GstPad *pad);
|
||||||
typedef GstBuffer *(*GstPadPullRegionFunction) (GstPad *pad, GstRegionType type, guint64 offset, guint64 len);
|
typedef GstBuffer *(*GstPadPullRegionFunction) (GstPad *pad, GstRegionType type, guint64 offset, guint64 len);
|
||||||
typedef gboolean (*GstPadEOSFunction) (GstPad *pad);
|
typedef gboolean (*GstPadEOSFunction) (GstPad *pad);
|
||||||
|
typedef GstCaps* (*GstPadNegotiateFunction) (GstPad *pad, GstCaps *caps, gint count);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GST_PAD_UNKNOWN,
|
GST_PAD_UNKNOWN,
|
||||||
|
@ -121,7 +122,7 @@ struct _GstPadClass {
|
||||||
struct _GstRealPad {
|
struct _GstRealPad {
|
||||||
GstPad pad;
|
GstPad pad;
|
||||||
|
|
||||||
GList *caps;
|
GstCaps *caps;
|
||||||
GstPadDirection direction;
|
GstPadDirection direction;
|
||||||
|
|
||||||
cothread_state *threadstate;
|
cothread_state *threadstate;
|
||||||
|
@ -143,6 +144,8 @@ struct _GstRealPad {
|
||||||
GstPadPullFunction pullfunc;
|
GstPadPullFunction pullfunc;
|
||||||
GstPadPullRegionFunction pullregionfunc;
|
GstPadPullRegionFunction pullregionfunc;
|
||||||
|
|
||||||
|
GstPadNegotiateFunction negotiatefunc;
|
||||||
|
|
||||||
GList *ghostpads;
|
GList *ghostpads;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -186,6 +189,7 @@ struct _GstGhostPadClass {
|
||||||
#define GST_RPAD_PULLREGIONFUNC(pad) (((GstRealPad *)(pad))->pullregionfunc)
|
#define GST_RPAD_PULLREGIONFUNC(pad) (((GstRealPad *)(pad))->pullregionfunc)
|
||||||
#define GST_RPAD_QOSFUNC(pad) (((GstRealPad *)(pad))->qosfunc)
|
#define GST_RPAD_QOSFUNC(pad) (((GstRealPad *)(pad))->qosfunc)
|
||||||
#define GST_RPAD_EOSFUNC(pad) (((GstRealPad *)(pad))->eosfunc)
|
#define GST_RPAD_EOSFUNC(pad) (((GstRealPad *)(pad))->eosfunc)
|
||||||
|
#define GST_RPAD_NEGOTIATEFUNC(pad) (((GstRealPad *)(pad))->negotiatefunc)
|
||||||
|
|
||||||
#define GST_RPAD_REGIONTYPE(pad) (((GstRealPad *)(pad))->regiontype)
|
#define GST_RPAD_REGIONTYPE(pad) (((GstRealPad *)(pad))->regiontype)
|
||||||
#define GST_RPAD_OFFSET(pad) (((GstRealPad *)(pad))->offset)
|
#define GST_RPAD_OFFSET(pad) (((GstRealPad *)(pad))->offset)
|
||||||
|
@ -201,7 +205,7 @@ struct _GstGhostPadClass {
|
||||||
#define GST_PAD_PEER(pad) GST_RPAD_PEER(GST_PAD_REALIZE(pad))
|
#define GST_PAD_PEER(pad) GST_RPAD_PEER(GST_PAD_REALIZE(pad))
|
||||||
|
|
||||||
/* Some check functions (unused?) */
|
/* Some check functions (unused?) */
|
||||||
#define GST_PAD_CONNECTED(pad) (GST_IS_REAL_PAD(pad) && GST_REAL_PAD(pad)->peer != NULL)
|
#define GST_PAD_CONNECTED(pad) (GST_PAD_PEER(pad) != NULL)
|
||||||
#define GST_PAD_CAN_PULL(pad) (GST_IS_REAL_PAD(pad) && GST_REAL_PAD(pad)->pullfunc != NULL)
|
#define GST_PAD_CAN_PULL(pad) (GST_IS_REAL_PAD(pad) && GST_REAL_PAD(pad)->pullfunc != NULL)
|
||||||
|
|
||||||
|
|
||||||
|
@ -218,13 +222,18 @@ typedef enum {
|
||||||
GST_PAD_REQUEST,
|
GST_PAD_REQUEST,
|
||||||
} GstPadPresence;
|
} GstPadPresence;
|
||||||
|
|
||||||
|
#define GST_PADTEMPLATE_NAME_TEMPLATE(templ) (((GstPadTemplate *)(templ))->name_template)
|
||||||
|
#define GST_PADTEMPLATE_DIRECTION(templ) (((GstPadTemplate *)(templ))->direction)
|
||||||
|
#define GST_PADTEMPLATE_PRESENCE(templ) (((GstPadTemplate *)(templ))->presence)
|
||||||
|
#define GST_PADTEMPLATE_CAPS(templ) (((GstPadTemplate *)(templ))->caps)
|
||||||
|
|
||||||
struct _GstPadTemplate {
|
struct _GstPadTemplate {
|
||||||
GstObject object;
|
GstObject object;
|
||||||
|
|
||||||
gchar *name_template;
|
gchar *name_template;
|
||||||
GstPadDirection direction;
|
GstPadDirection direction;
|
||||||
GstPadPresence presence;
|
GstPadPresence presence;
|
||||||
GList *caps;
|
GstCaps *caps;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstPadTemplateClass {
|
struct _GstPadTemplateClass {
|
||||||
|
@ -246,7 +255,8 @@ typedef GstPadFactoryEntry GstPadFactory[];
|
||||||
#define GST_PAD_FACTORY_SRC GINT_TO_POINTER(GST_PAD_SRC)
|
#define GST_PAD_FACTORY_SRC GINT_TO_POINTER(GST_PAD_SRC)
|
||||||
#define GST_PAD_FACTORY_SINK GINT_TO_POINTER(GST_PAD_SINK)
|
#define GST_PAD_FACTORY_SINK GINT_TO_POINTER(GST_PAD_SINK)
|
||||||
|
|
||||||
#define GST_PAD_FACTORY_CAPS(a...) GINT_TO_POINTER(1),##a,NULL
|
#define GST_PAD_FACTORY_CAPS_ID 1
|
||||||
|
#define GST_PAD_FACTORY_CAPS(a...) GINT_TO_POINTER(GST_PAD_FACTORY_CAPS_ID),##a,NULL
|
||||||
|
|
||||||
|
|
||||||
GtkType gst_pad_get_type (void);
|
GtkType gst_pad_get_type (void);
|
||||||
|
@ -264,10 +274,10 @@ void gst_pad_set_get_function (GstPad *pad, GstPadGetFunction get);
|
||||||
void gst_pad_set_getregion_function (GstPad *pad, GstPadGetRegionFunction getregion);
|
void gst_pad_set_getregion_function (GstPad *pad, GstPadGetRegionFunction getregion);
|
||||||
void gst_pad_set_qos_function (GstPad *pad, GstPadQoSFunction qos);
|
void gst_pad_set_qos_function (GstPad *pad, GstPadQoSFunction qos);
|
||||||
void gst_pad_set_eos_function (GstPad *pad, GstPadEOSFunction eos);
|
void gst_pad_set_eos_function (GstPad *pad, GstPadEOSFunction eos);
|
||||||
|
void gst_pad_set_negotiate_function (GstPad *pad, GstPadNegotiateFunction nego);
|
||||||
|
|
||||||
void gst_pad_set_caps_list (GstPad *pad, GList *caps);
|
void gst_pad_set_caps (GstPad *pad, GstCaps *caps);
|
||||||
GList* gst_pad_get_caps_list (GstPad *pad);
|
GstCaps* gst_pad_get_caps (GstPad *pad);
|
||||||
GstCaps* gst_pad_get_caps_by_name (GstPad *pad, gchar *name);
|
|
||||||
gboolean gst_pad_check_compatibility (GstPad *srcpad, GstPad *sinkpad);
|
gboolean gst_pad_check_compatibility (GstPad *srcpad, GstPad *sinkpad);
|
||||||
|
|
||||||
void gst_pad_set_element_private (GstPad *pad, gpointer priv);
|
void gst_pad_set_element_private (GstPad *pad, gpointer priv);
|
||||||
|
@ -284,11 +294,16 @@ void gst_pad_add_ghost_pad (GstPad *pad, GstPad *ghostpad);
|
||||||
void gst_pad_remove_ghost_pad (GstPad *pad, GstPad *ghostpad);
|
void gst_pad_remove_ghost_pad (GstPad *pad, GstPad *ghostpad);
|
||||||
GList* gst_pad_get_ghost_pad_list (GstPad *pad);
|
GList* gst_pad_get_ghost_pad_list (GstPad *pad);
|
||||||
|
|
||||||
|
GstPadTemplate* gst_pad_get_padtemplate (GstPad *pad);
|
||||||
|
|
||||||
GstPad* gst_pad_get_peer (GstPad *pad);
|
GstPad* gst_pad_get_peer (GstPad *pad);
|
||||||
|
|
||||||
void gst_pad_connect (GstPad *srcpad, GstPad *sinkpad);
|
gboolean gst_pad_connect (GstPad *srcpad, GstPad *sinkpad);
|
||||||
void gst_pad_disconnect (GstPad *srcpad, GstPad *sinkpad);
|
void gst_pad_disconnect (GstPad *srcpad, GstPad *sinkpad);
|
||||||
|
|
||||||
|
gboolean gst_pad_renegotiate (GstPad *pad);
|
||||||
|
GstCaps* gst_pad_negotiate_proxy (GstPad *pad, GstCaps* caps, gint count);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
void gst_pad_push (GstPad *pad, GstBuffer *buf);
|
void gst_pad_push (GstPad *pad, GstBuffer *buf);
|
||||||
#else
|
#else
|
||||||
|
@ -325,7 +340,10 @@ GtkType gst_padtemplate_get_type (void);
|
||||||
GstPadTemplate* gst_padtemplate_new (GstPadFactory *factory);
|
GstPadTemplate* gst_padtemplate_new (GstPadFactory *factory);
|
||||||
GstPadTemplate* gst_padtemplate_create (gchar *name_template,
|
GstPadTemplate* gst_padtemplate_create (gchar *name_template,
|
||||||
GstPadDirection direction, GstPadPresence presence,
|
GstPadDirection direction, GstPadPresence presence,
|
||||||
GList *caps);
|
GstCaps *caps);
|
||||||
|
|
||||||
|
GstCaps* gst_padtemplate_get_caps (GstPadTemplate *templ);
|
||||||
|
GstCaps* gst_padtemplate_get_caps_by_name (GstPadTemplate *templ, const gchar *name);
|
||||||
|
|
||||||
xmlNodePtr gst_padtemplate_save_thyself (GstPadTemplate *templ, xmlNodePtr parent);
|
xmlNodePtr gst_padtemplate_save_thyself (GstPadTemplate *templ, xmlNodePtr parent);
|
||||||
GstPadTemplate* gst_padtemplate_load_thyself (xmlNodePtr parent);
|
GstPadTemplate* gst_padtemplate_load_thyself (xmlNodePtr parent);
|
||||||
|
|
|
@ -66,6 +66,8 @@ static void gst_queue_set_arg (GtkObject *object, GtkArg *arg, guint id);
|
||||||
static void gst_queue_get_arg (GtkObject *object, GtkArg *arg, guint id);
|
static void gst_queue_get_arg (GtkObject *object, GtkArg *arg, guint id);
|
||||||
|
|
||||||
static gboolean gst_queue_handle_eos (GstPad *pad);
|
static gboolean gst_queue_handle_eos (GstPad *pad);
|
||||||
|
static GstCaps* gst_queue_handle_negotiate_src (GstPad *pad, GstCaps *caps, gint count);
|
||||||
|
static GstCaps* gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps *caps, gint count);
|
||||||
static void gst_queue_chain (GstPad *pad, GstBuffer *buf);
|
static void gst_queue_chain (GstPad *pad, GstBuffer *buf);
|
||||||
static GstBuffer * gst_queue_get (GstPad *pad);
|
static GstBuffer * gst_queue_get (GstPad *pad);
|
||||||
|
|
||||||
|
@ -131,10 +133,12 @@ gst_queue_init (GstQueue *queue)
|
||||||
gst_pad_set_chain_function (queue->sinkpad, GST_DEBUG_FUNCPTR(gst_queue_chain));
|
gst_pad_set_chain_function (queue->sinkpad, GST_DEBUG_FUNCPTR(gst_queue_chain));
|
||||||
gst_element_add_pad (GST_ELEMENT (queue), queue->sinkpad);
|
gst_element_add_pad (GST_ELEMENT (queue), queue->sinkpad);
|
||||||
gst_pad_set_eos_function (queue->sinkpad, gst_queue_handle_eos);
|
gst_pad_set_eos_function (queue->sinkpad, gst_queue_handle_eos);
|
||||||
|
gst_pad_set_negotiate_function (queue->sinkpad, gst_queue_handle_negotiate_sink);
|
||||||
|
|
||||||
queue->srcpad = gst_pad_new ("src", GST_PAD_SRC);
|
queue->srcpad = gst_pad_new ("src", GST_PAD_SRC);
|
||||||
gst_pad_set_get_function (queue->srcpad, GST_DEBUG_FUNCPTR(gst_queue_get));
|
gst_pad_set_get_function (queue->srcpad, GST_DEBUG_FUNCPTR(gst_queue_get));
|
||||||
gst_element_add_pad (GST_ELEMENT (queue), queue->srcpad);
|
gst_element_add_pad (GST_ELEMENT (queue), queue->srcpad);
|
||||||
|
gst_pad_set_negotiate_function (queue->srcpad, gst_queue_handle_negotiate_src);
|
||||||
|
|
||||||
queue->queue = NULL;
|
queue->queue = NULL;
|
||||||
queue->level_buffers = 0;
|
queue->level_buffers = 0;
|
||||||
|
@ -148,6 +152,26 @@ gst_queue_init (GstQueue *queue)
|
||||||
queue->fullcond = g_cond_new ();
|
queue->fullcond = g_cond_new ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstCaps*
|
||||||
|
gst_queue_handle_negotiate_src (GstPad *pad, GstCaps *caps, gint count)
|
||||||
|
{
|
||||||
|
GstQueue *queue;
|
||||||
|
|
||||||
|
queue = GST_QUEUE (GST_OBJECT_PARENT (pad));
|
||||||
|
|
||||||
|
return gst_pad_negotiate_proxy (queue->sinkpad, caps, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstCaps*
|
||||||
|
gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps *caps, gint count)
|
||||||
|
{
|
||||||
|
GstQueue *queue;
|
||||||
|
|
||||||
|
queue = GST_QUEUE (GST_OBJECT_PARENT (pad));
|
||||||
|
|
||||||
|
return gst_pad_negotiate_proxy (queue->srcpad, caps, count);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_queue_handle_eos (GstPad *pad)
|
gst_queue_handle_eos (GstPad *pad)
|
||||||
{
|
{
|
||||||
|
|
|
@ -285,7 +285,7 @@ gst_play_typefind (GstBin *bin, GstElement *element)
|
||||||
if (found) {
|
if (found) {
|
||||||
caps = gst_util_get_pointer_arg (GTK_OBJECT (typefind), "caps");
|
caps = gst_util_get_pointer_arg (GTK_OBJECT (typefind), "caps");
|
||||||
|
|
||||||
gst_pad_set_caps_list (gst_element_get_pad (element, "src"), g_list_prepend (NULL, caps));
|
gst_pad_set_caps (gst_element_get_pad (element, "src"), caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_pad_disconnect (gst_element_get_pad (element, "src"),
|
gst_pad_disconnect (gst_element_get_pad (element, "src"),
|
||||||
|
@ -360,7 +360,7 @@ gst_play_set_uri (GstPlay *play,
|
||||||
gtk_signal_connect (GTK_OBJECT (autoplug), "new_object", gst_play_object_added, play);
|
gtk_signal_connect (GTK_OBJECT (autoplug), "new_object", gst_play_object_added, play);
|
||||||
|
|
||||||
new_element = gst_autoplug_to_renderers (autoplug,
|
new_element = gst_autoplug_to_renderers (autoplug,
|
||||||
gst_pad_get_caps_list (gst_element_get_pad (priv->src, "src")),
|
gst_pad_get_caps (gst_element_get_pad (priv->src, "src")),
|
||||||
priv->video_element,
|
priv->video_element,
|
||||||
priv->audio_element,
|
priv->audio_element,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
|
@ -417,8 +417,9 @@ gst_audiosink_change_state (GstElement *element)
|
||||||
/* otherwise (READY or higher) we need to open the sound card */
|
/* otherwise (READY or higher) we need to open the sound card */
|
||||||
} else {
|
} else {
|
||||||
if (!GST_FLAG_IS_SET (element, GST_AUDIOSINK_OPEN)) {
|
if (!GST_FLAG_IS_SET (element, GST_AUDIOSINK_OPEN)) {
|
||||||
if (!gst_audiosink_open_audio (GST_AUDIOSINK (element)))
|
if (!gst_audiosink_open_audio (GST_AUDIOSINK (element))) {
|
||||||
return GST_STATE_FAILURE;
|
//return GST_STATE_FAILURE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,8 @@ static void gst_queue_set_arg (GtkObject *object, GtkArg *arg, guint id);
|
||||||
static void gst_queue_get_arg (GtkObject *object, GtkArg *arg, guint id);
|
static void gst_queue_get_arg (GtkObject *object, GtkArg *arg, guint id);
|
||||||
|
|
||||||
static gboolean gst_queue_handle_eos (GstPad *pad);
|
static gboolean gst_queue_handle_eos (GstPad *pad);
|
||||||
|
static GstCaps* gst_queue_handle_negotiate_src (GstPad *pad, GstCaps *caps, gint count);
|
||||||
|
static GstCaps* gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps *caps, gint count);
|
||||||
static void gst_queue_chain (GstPad *pad, GstBuffer *buf);
|
static void gst_queue_chain (GstPad *pad, GstBuffer *buf);
|
||||||
static GstBuffer * gst_queue_get (GstPad *pad);
|
static GstBuffer * gst_queue_get (GstPad *pad);
|
||||||
|
|
||||||
|
@ -131,10 +133,12 @@ gst_queue_init (GstQueue *queue)
|
||||||
gst_pad_set_chain_function (queue->sinkpad, GST_DEBUG_FUNCPTR(gst_queue_chain));
|
gst_pad_set_chain_function (queue->sinkpad, GST_DEBUG_FUNCPTR(gst_queue_chain));
|
||||||
gst_element_add_pad (GST_ELEMENT (queue), queue->sinkpad);
|
gst_element_add_pad (GST_ELEMENT (queue), queue->sinkpad);
|
||||||
gst_pad_set_eos_function (queue->sinkpad, gst_queue_handle_eos);
|
gst_pad_set_eos_function (queue->sinkpad, gst_queue_handle_eos);
|
||||||
|
gst_pad_set_negotiate_function (queue->sinkpad, gst_queue_handle_negotiate_sink);
|
||||||
|
|
||||||
queue->srcpad = gst_pad_new ("src", GST_PAD_SRC);
|
queue->srcpad = gst_pad_new ("src", GST_PAD_SRC);
|
||||||
gst_pad_set_get_function (queue->srcpad, GST_DEBUG_FUNCPTR(gst_queue_get));
|
gst_pad_set_get_function (queue->srcpad, GST_DEBUG_FUNCPTR(gst_queue_get));
|
||||||
gst_element_add_pad (GST_ELEMENT (queue), queue->srcpad);
|
gst_element_add_pad (GST_ELEMENT (queue), queue->srcpad);
|
||||||
|
gst_pad_set_negotiate_function (queue->srcpad, gst_queue_handle_negotiate_src);
|
||||||
|
|
||||||
queue->queue = NULL;
|
queue->queue = NULL;
|
||||||
queue->level_buffers = 0;
|
queue->level_buffers = 0;
|
||||||
|
@ -148,6 +152,26 @@ gst_queue_init (GstQueue *queue)
|
||||||
queue->fullcond = g_cond_new ();
|
queue->fullcond = g_cond_new ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstCaps*
|
||||||
|
gst_queue_handle_negotiate_src (GstPad *pad, GstCaps *caps, gint count)
|
||||||
|
{
|
||||||
|
GstQueue *queue;
|
||||||
|
|
||||||
|
queue = GST_QUEUE (GST_OBJECT_PARENT (pad));
|
||||||
|
|
||||||
|
return gst_pad_negotiate_proxy (queue->sinkpad, caps, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstCaps*
|
||||||
|
gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps *caps, gint count)
|
||||||
|
{
|
||||||
|
GstQueue *queue;
|
||||||
|
|
||||||
|
queue = GST_QUEUE (GST_OBJECT_PARENT (pad));
|
||||||
|
|
||||||
|
return gst_pad_negotiate_proxy (queue->srcpad, caps, count);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_queue_handle_eos (GstPad *pad)
|
gst_queue_handle_eos (GstPad *pad)
|
||||||
{
|
{
|
||||||
|
|
1
tests/.gitignore
vendored
1
tests/.gitignore
vendored
|
@ -26,3 +26,4 @@ padfactory
|
||||||
tee
|
tee
|
||||||
autoplug2
|
autoplug2
|
||||||
autoplug3
|
autoplug3
|
||||||
|
capsconnect
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
SUBDIRS = sched eos
|
SUBDIRS = sched eos
|
||||||
|
|
||||||
noinst_PROGRAMS = init loadall simplefake states caps queue registry \
|
noinst_PROGRAMS = init loadall simplefake states caps queue registry \
|
||||||
paranoia rip mp3encode autoplug props case4 markup load tee autoplug2 autoplug3
|
paranoia rip mp3encode autoplug props case4 markup load tee autoplug2 autoplug3 \
|
||||||
|
capsconnect
|
||||||
|
|
||||||
# we have nothing but apps here, we can do this safely
|
# we have nothing but apps here, we can do this safely
|
||||||
LIBS += $(GST_LIBS)
|
LIBS += $(GST_LIBS)
|
||||||
|
|
|
@ -34,8 +34,8 @@ main (int argc, char *argv[])
|
||||||
gtk_signal_connect (GTK_OBJECT (autoplugger), "new_object", new_object_added, NULL);
|
gtk_signal_connect (GTK_OBJECT (autoplugger), "new_object", new_object_added, NULL);
|
||||||
|
|
||||||
element = gst_autoplug_to_caps (autoplugger, testcaps,
|
element = gst_autoplug_to_caps (autoplugger, testcaps,
|
||||||
gst_pad_get_caps_list (gst_element_get_pad (audiosink, "sink")),
|
gst_pad_get_caps (gst_element_get_pad (audiosink, "sink")),
|
||||||
gst_pad_get_caps_list (gst_element_get_pad (videosink, "sink")),
|
gst_pad_get_caps (gst_element_get_pad (videosink, "sink")),
|
||||||
NULL);
|
NULL);
|
||||||
g_assert (element != NULL);
|
g_assert (element != NULL);
|
||||||
|
|
||||||
|
|
62
tests/capsconnect.c
Normal file
62
tests/capsconnect.c
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#include <gst/gst.h>
|
||||||
|
|
||||||
|
int main(int argc,char *argv[])
|
||||||
|
{
|
||||||
|
gboolean testret;
|
||||||
|
xmlDocPtr doc;
|
||||||
|
xmlNodePtr parent;
|
||||||
|
GstElement *mpg123;
|
||||||
|
GstElement *mp3parse;
|
||||||
|
GstElement *queue;
|
||||||
|
GstPad *sinkpad;
|
||||||
|
GstPad *srcpad;
|
||||||
|
GstPad *qsinkpad;
|
||||||
|
|
||||||
|
doc = xmlNewDoc ("1.0");
|
||||||
|
doc->xmlRootNode = xmlNewDocNode (doc, NULL, "Capabilities", NULL);
|
||||||
|
|
||||||
|
gst_init (&argc, &argv);
|
||||||
|
|
||||||
|
mpg123 = gst_elementfactory_make ("mpg123", "mpg123");
|
||||||
|
g_assert (mpg123 != NULL);
|
||||||
|
|
||||||
|
sinkpad = gst_element_get_pad (mpg123, "sink");
|
||||||
|
g_assert (sinkpad != NULL);
|
||||||
|
|
||||||
|
queue = gst_elementfactory_make ("queue", "queue");
|
||||||
|
g_assert (queue != NULL);
|
||||||
|
|
||||||
|
srcpad = gst_element_get_pad (queue, "src");
|
||||||
|
g_assert (srcpad != NULL);
|
||||||
|
qsinkpad = gst_element_get_pad (queue, "sink");
|
||||||
|
g_assert (qsinkpad != NULL);
|
||||||
|
|
||||||
|
parent = xmlNewChild (doc->xmlRootNode, NULL, "mpg123 caps", NULL);
|
||||||
|
gst_caps_save_thyself (gst_pad_get_caps (sinkpad), parent);
|
||||||
|
|
||||||
|
parent = xmlNewChild (doc->xmlRootNode, NULL, "queue caps", NULL);
|
||||||
|
gst_caps_save_thyself (gst_pad_get_caps (srcpad), parent);
|
||||||
|
|
||||||
|
gst_pad_connect (srcpad, sinkpad);
|
||||||
|
|
||||||
|
parent = xmlNewChild (doc->xmlRootNode, NULL, "queue caps after connect src", NULL);
|
||||||
|
gst_caps_save_thyself (gst_pad_get_caps (srcpad), parent);
|
||||||
|
|
||||||
|
parent = xmlNewChild (doc->xmlRootNode, NULL, "queue caps after connect sink", NULL);
|
||||||
|
gst_caps_save_thyself (gst_pad_get_caps (qsinkpad), parent);
|
||||||
|
|
||||||
|
mp3parse = gst_elementfactory_make ("mp3parse", "mp3parse");
|
||||||
|
g_assert (mp3parse != NULL);
|
||||||
|
|
||||||
|
gst_pad_connect (gst_element_get_pad (mp3parse, "src"), qsinkpad);
|
||||||
|
|
||||||
|
parent = xmlNewChild (doc->xmlRootNode, NULL, "queue caps after connect sink", NULL);
|
||||||
|
gst_caps_save_thyself (gst_pad_get_caps (qsinkpad), parent);
|
||||||
|
|
||||||
|
parent = xmlNewChild (doc->xmlRootNode, NULL, "mpg123 caps after connect sink", NULL);
|
||||||
|
gst_caps_save_thyself (gst_pad_get_caps (sinkpad), parent);
|
||||||
|
|
||||||
|
xmlDocDump(stdout, doc);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
9
tests/nego/.gitignore
vendored
Normal file
9
tests/nego/.gitignore
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
Makefile
|
||||||
|
Makefile.in
|
||||||
|
*.o
|
||||||
|
*.lo
|
||||||
|
*.la
|
||||||
|
.deps
|
||||||
|
.libs
|
||||||
|
*.xml
|
||||||
|
nego1
|
5
tests/nego/Makefile.am
Normal file
5
tests/nego/Makefile.am
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
noinst_PROGRAMS = nego1
|
||||||
|
|
||||||
|
# jsut apps here, this is safe
|
||||||
|
LIBS += $(GST_LIBS)
|
||||||
|
CFLAGS += $(GST_CFLAGS)
|
59
tests/nego/nego1.c
Normal file
59
tests/nego/nego1.c
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
#include <gst/gst.h>
|
||||||
|
|
||||||
|
/* this is an example of the src pad dictating the caps
|
||||||
|
* the sink pad only accepts audio/raw */
|
||||||
|
|
||||||
|
static GstCaps*
|
||||||
|
negotiate (GstPad *pad, GstCaps *caps, gint count)
|
||||||
|
{
|
||||||
|
g_print ("negotiation entered\n");
|
||||||
|
|
||||||
|
if (!strcmp (gst_caps_get_mime (caps), "audio/raw"))
|
||||||
|
return caps;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc,char *argv[])
|
||||||
|
{
|
||||||
|
GstPad *srcpad, *sinkpad;
|
||||||
|
GstCaps *new;
|
||||||
|
|
||||||
|
gst_init(&argc,&argv);
|
||||||
|
|
||||||
|
srcpad = gst_pad_new ("src", GST_PAD_SRC);
|
||||||
|
sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
|
||||||
|
|
||||||
|
gst_pad_connect (srcpad, sinkpad);
|
||||||
|
|
||||||
|
gst_pad_set_negotiate_function (sinkpad, negotiate);
|
||||||
|
|
||||||
|
/* fill in our desired caps */
|
||||||
|
new = gst_caps_new_with_props (
|
||||||
|
"src_caps", /* name */
|
||||||
|
"audio/raw", /* mime */
|
||||||
|
gst_props_new (
|
||||||
|
"format", GST_PROPS_INT (16),
|
||||||
|
"depth", GST_PROPS_INT (16),
|
||||||
|
"rate", GST_PROPS_INT (48000),
|
||||||
|
"channels", GST_PROPS_INT (2),
|
||||||
|
NULL
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
gst_pad_set_caps (srcpad, new);
|
||||||
|
|
||||||
|
new = gst_caps_new_with_props (
|
||||||
|
"src_caps", /* name */
|
||||||
|
"video/raw", /* mime */
|
||||||
|
gst_props_new (
|
||||||
|
"format", GST_PROPS_FOURCC ('Y','U','Y','V'),
|
||||||
|
NULL
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
gst_pad_set_caps (srcpad, new);
|
||||||
|
|
||||||
|
exit (0);
|
||||||
|
}
|
Loading…
Reference in a new issue